Files
react-native-svg/ios/QuartzBookPack/Geometry/BaseGeometry.m

243 lines
5.8 KiB
Objective-C

/*
Erica Sadun, http://ericasadun.com
*/
#import "BaseGeometry.h"
#pragma mark - Conversion
// Degrees from radians
CGFloat DegreesFromRadians(CGFloat radians)
{
return radians * 180.0f / M_PI;
}
// Radians from degrees
CGFloat RadiansFromDegrees(CGFloat degrees)
{
return degrees * M_PI / 180.0f;
}
#pragma mark - Clamp
CGFloat Clamp(CGFloat a, CGFloat min, CGFloat max)
{
return fmin(fmax(min, a), max);
}
CGPoint ClampToRect(CGPoint pt, CGRect rect)
{
CGFloat x = Clamp(pt.x, CGRectGetMinX(rect), CGRectGetMaxX(rect));
CGFloat y = Clamp(pt.y, CGRectGetMinY(rect), CGRectGetMaxY(rect));
return CGPointMake(x, y);
}
#pragma mark - General Geometry
CGPoint RectGetCenter(CGRect rect)
{
return CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
}
CGFloat PointDistanceFromPoint(CGPoint p1, CGPoint p2)
{
CGFloat dx = p2.x - p1.x;
CGFloat dy = p2.y - p1.y;
return sqrt(dx*dx + dy*dy);
}
CGPoint RectGetPointAtPercents(CGRect rect, CGFloat xPercent, CGFloat yPercent)
{
CGFloat dx = xPercent * rect.size.width;
CGFloat dy = yPercent * rect.size.height;
return CGPointMake(rect.origin.x + dx, rect.origin.y + dy);
}
#pragma mark - Rectangle Construction
CGRect RectMakeRect(CGPoint origin, CGSize size)
{
return (CGRect){.origin = origin, .size = size};
}
CGRect SizeMakeRect(CGSize size)
{
return (CGRect){.size = size};
}
CGRect PointsMakeRect(CGPoint p1, CGPoint p2)
{
CGRect rect = CGRectMake(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
return CGRectStandardize(rect);
}
CGRect OriginMakeRect(CGPoint origin)
{
return (CGRect){.origin = origin};
}
CGRect RectAroundCenter(CGPoint center, CGSize size)
{
CGFloat halfWidth = size.width / 2.0f;
CGFloat halfHeight = size.height / 2.0f;
return CGRectMake(center.x - halfWidth, center.y - halfHeight, size.width, size.height);
}
CGRect RectCenteredInRect(CGRect rect, CGRect mainRect)
{
CGFloat dx = CGRectGetMidX(mainRect)-CGRectGetMidX(rect);
CGFloat dy = CGRectGetMidY(mainRect)-CGRectGetMidY(rect);
return CGRectOffset(rect, dx, dy);
}
#pragma mark - Point Location
CGPoint PointAddPoint(CGPoint p1, CGPoint p2)
{
return CGPointMake(p1.x + p2.x, p1.y + p2.y);
}
CGPoint PointSubtractPoint(CGPoint p1, CGPoint p2)
{
return CGPointMake(p1.x - p2.x, p1.y - p2.y);
}
#pragma mark - Cardinal Points
CGPoint RectGetTopLeft(CGRect rect)
{
return CGPointMake(
CGRectGetMinX(rect),
CGRectGetMinY(rect)
);
}
CGPoint RectGetTopRight(CGRect rect)
{
return CGPointMake(
CGRectGetMaxX(rect),
CGRectGetMinY(rect)
);
}
CGPoint RectGetBottomLeft(CGRect rect)
{
return CGPointMake(
CGRectGetMinX(rect),
CGRectGetMaxY(rect)
);
}
CGPoint RectGetBottomRight(CGRect rect)
{
return CGPointMake(
CGRectGetMaxX(rect),
CGRectGetMaxY(rect)
);
}
CGPoint RectGetMidTop(CGRect rect)
{
return CGPointMake(
CGRectGetMidX(rect),
CGRectGetMinY(rect)
);
}
CGPoint RectGetMidBottom(CGRect rect)
{
return CGPointMake(
CGRectGetMidX(rect),
CGRectGetMaxY(rect)
);
}
CGPoint RectGetMidLeft(CGRect rect)
{
return CGPointMake(
CGRectGetMinX(rect),
CGRectGetMidY(rect)
);
}
CGPoint RectGetMidRight(CGRect rect)
{
return CGPointMake(
CGRectGetMaxX(rect),
CGRectGetMidY(rect)
);
}
#pragma mark - Aspect and Fitting
CGSize SizeScaleByFactor(CGSize aSize, CGFloat factor)
{
return CGSizeMake(aSize.width * factor, aSize.height * factor);
}
CGSize RectGetScale(CGRect sourceRect, CGRect destRect)
{
CGSize sourceSize = sourceRect.size;
CGSize destSize = destRect.size;
CGFloat scaleW = destSize.width / sourceSize.width;
CGFloat scaleH = destSize.height / sourceSize.height;
return CGSizeMake(scaleW, scaleH);
}
CGFloat AspectScaleFill(CGSize sourceSize, CGRect destRect)
{
CGSize destSize = destRect.size;
CGFloat scaleW = destSize.width / sourceSize.width;
CGFloat scaleH = destSize.height / sourceSize.height;
return fmax(scaleW, scaleH);
}
CGFloat AspectScaleFit(CGSize sourceSize, CGRect destRect)
{
CGSize destSize = destRect.size;
CGFloat scaleW = destSize.width / sourceSize.width;
CGFloat scaleH = destSize.height / sourceSize.height;
return fmin(scaleW, scaleH);
}
CGRect RectByFittingRect(CGRect sourceRect, CGRect destinationRect)
{
CGFloat aspect = AspectScaleFit(sourceRect.size, destinationRect);
CGSize targetSize = SizeScaleByFactor(sourceRect.size, aspect);
return RectAroundCenter(RectGetCenter(destinationRect), targetSize);
}
CGRect RectByFillingRect(CGRect sourceRect, CGRect destinationRect)
{
CGFloat aspect = AspectScaleFill(sourceRect.size, destinationRect);
CGSize targetSize = SizeScaleByFactor(sourceRect.size, aspect);
return RectAroundCenter(RectGetCenter(destinationRect), targetSize);
}
CGRect RectInsetByPercent(CGRect rect, CGFloat percent)
{
CGFloat wInset = rect.size.width * (percent / 2.0f);
CGFloat hInset = rect.size.height * (percent / 2.0f);
return CGRectInset(rect, wInset, hInset);
}
#pragma mark - Transforms
// Extract the x scale from transform
CGFloat TransformGetXScale(CGAffineTransform t)
{
return sqrt(t.a * t.a + t.c * t.c);
}
// Extract the y scale from transform
CGFloat TransformGetYScale(CGAffineTransform t)
{
return sqrt(t.b * t.b + t.d * t.d);
}
// Extract the rotation in radians
CGFloat TransformGetRotation(CGAffineTransform t)
{
return atan2f(t.b, t.a);
}