mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-21 06:15:15 +00:00
243 lines
5.8 KiB
Objective-C
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);
|
|
}
|