GeometryHelpers
iOS CGSize, CGPoint, CGRect, CGFloat helpers
Install / Use
/learn @AndreasVerhoeven/GeometryHelpersREADME
GeometryHelpers
iOS CGSize, CGPoint, CGRect, CGFloat helpers
CGFloat
Helpers such as roundedToNearestPixel to round a float to the nearest pixel, instead of point. Useful when aligning on pixel boundaries.
hairLineHeightthe height of 1 pixel on the screenroundedToNearestPixelceiledToNearestPixelflooredToNearestPixel
CGPoint
Helpers such as with(x:), with(y:) to quickly change a component.
Creating
all(_:)creates a point with x and y set to the given valuex(_:)creates a point with x set to the given value, y to 0y(_:)creates a point withyx set to the given value, x to 0
Changing
with(x:)new point with a given xwith(y:)new point with a given y
Offset
offsetted(by:)offsetted by another pointoffsetted(x:y:)offsetted by some x and yoffsetted(by:)offsetted by insetsreverseOffsetted(by:)undoes the offsetting by another point/insets
Flipping & Mirroring
mirroredreturns a point mirrored alongside the y-axisflippedreturns a point flipped alongside the x-axis
To Pixel/Point
To Points/Pixels
roundedToNearestPixelrounds to the nearest pixelceiledToNearestPixelceils to the nearest pixelflooredToNearestPixelfloors to the nearest pixelroundedToFullPointsrounds to full (integer) pointsceiledToFullPointsceils to full (integer) pointsflooredToFullPointsfloors to full (integer) points
Other:
slope(to:)returns the slope of the line from this point to another point
CGSize
min(_:)returns the minimum dimensions of self and another sizemax(_:)returns the maximum dimensions self and another size
Creating
all(_:)creates a size with width and height set to the given value
Converting to Rects
rectAtZeroOriginreturnsCGRect(origin: .zero, size: self)centerreturns the center point forrectAtZeroOrigin
Changing:
with(width:)returns a new size with a new widthwith(height:)returns a new size with a new heightadding(width:height)returns a new size by adding to the width or heightadding(_:)returns a new size by adding another sizeadding(_:)returns a new size by adding the insets
Subtracting
subtracting(width:height:)subtracts from this sizesubtracting(_:)subtracts another size from this sizeinsetted(by:)insets the size by given insets
Stacking
verticallyStacked(with: spacing)returns the size that is needed to stack this with otherhorizontallyStacked(with: spacing)returns the size that is needed to stack this with other
To Points/Pixels
roundedToNearestPixel()rounds to the nearest pixelceiledToNearestPixel()ceils to the nearest pixelflooredToNearestPixel()floors to the nearest pixelroundedToFullPoints()rounds to full (integer) pointsceiledToFullPoints()ceils to full (integer) pointsflooredToFullPoints()floors to full (integer) points
Aspect Fitting
sizeThatFitsSize(_:)returns a size thats in the other size, while maintaining aspect ratioaspectFill(for:)returns the size that aspect fills in the given other sizeaspectFit(for:)returns the size that aspect fits in the given other sizeaspectScale(for:)returns the size that aspect scales in the given size
Other
isEmptytrue if width or height are <= 0greatestFiniteMagnitudeboth width and height are set togreatestFiniteMagnitude, useful forUIView.sizeThatFits()
CGRect
Derived Points
centertopLefttopRightbottomLeftbottomRightmidXmidYtopMiddlebottomMiddlemidLeftmidRight
Changing
with(origin:)returns a new rect with a new originwith(size:)returns a new rect with a new sizewith(x:)returns a new rect with a new x originwith(y:)returns a new rect with a new y originwith(height:)returns a new rect with a new heightwith(width:)returns a new rect with a new width
Offsetted
offsetted(by:)returns a new rect offsetted by a point/insetsoffsetted(x:y:)returns a new rect offsetted by x and y
Insettted
insetted(top:left:bottom:right)returns a new rect insetted by the given values
To Points
roundedToNearestPixelreturns a new rect with the corners rounded to the nearest pixelsceiledToNearestPixelreturns a new rect with the min coordinates floored, the max coordinates ceiled to the nearest pixel
Fitting
rectThatFitsInRect(_:)returns the rect that fits in this rect, retaining aspect ratio
UIView
When setting the center and bounds of a UIView, one must take special care that the view is actually aligned on pixel boundaries. If not, the view
will be slightly blurry, because the pixels of the grid do not align with the pixel grid of the device.
safeCenter and safeSize automatically do this for you: they make sure that the untransformed frame of the view will be pixel aligned.
Using UIView.frame compensates for the current transform of the view: it literally returns the actual position. More often than not, one wants
to set the frame irregardless of the transform, for example, when doing a scale animation. A way to do this is to set the center and bounds.
safeFrame wraps this by calculating the safeCenter and safeSize for you and setting it correctly, ignoring any transforms.
Euclidian Geometry Helpers
There are also a bunch of helpers for dealing with simple euclidian geometry:
SlopeLineLineSegmentCircleCircleArc
Slope
A slope models the slope of a line. Three cases:
- zero: the slope of a strict horizontal line
- infinity: the slope of a strict vertical line
- any other value: the slope of any other line
Creating:
init(rawValue:)creates a slope with a given raw value as slope.horizontalthe horizontal slope.verticalthe vertical slopeinit(from:to:)creates a slope from the slope of the line between two points
Methods:
isHorizontalisVerticalperpendicularthe slope perpendicular to thisisAmostEqual(to: tolerance:)
Line
A line goes thru a point with a specific slope and has no start and end point: it goes on forever.
Creation
init(point:slope:)creates a line that goes thru a point with a specific slopeinit(verticalLineAtX:)creates a vertical line that goes thru the x coordinateinit(horizontalLineAtY:)creates a horizontal line that goes thru the y coordinateinit(yIsXTimes:plus:)creates a line from the formulay = x * slope + binit(from:to:)creates a line that goes thru the two given pointsinit(tangentFromPointOnCircle:center:)create the line that is tangent for the point on the circle with the given center
Methods
isHorizontalisVerticalperpendicular(at:tolerance:)creates the line that is perpendicular to this line in the given point, if the given point is on this line, otherwise nil.
Getting positions/values
yValue(forX:)gets the value of y for the given x, if it existspoint(forX:)get the point for the given x, if it existsxValue(forY:)gets the value of x for the given y, if it existspoint(forY:)gets the point foe the given y, if it exists
Other
contains(other:tolerance:)checks if this line contains the given pointisAlmostEqual(to:tolerance:)check if this line is equal to another lineintersection(with:tolerance:)gets the intersection result from this line to another line, which could be:sameLine,parallelorintersect(at:)intersectionPoint(with:tolerance:)returns the intersection point of this line with another line, if there's only one unique intersection point, otherwise nil.
LineSegment
A line segment is a segment of a line between two points.
Creation
init(start:end:)creates a line segment between start and end.
Methods
linegets the line for this segmentslopegets the slope of this segmentisAlmostEqual(to:tolerance:)checks if this line segment is equal to another onecontains(point:tolerance:)checks if the given point is contained by the line segment
Circle
It's a circle :)
Creation
init(center:radius:)creates a circle with a given center and radius
Methods
isOnCircle(point:tolerance:)check if the given point is on the circleisInsideCircle(point:tolerance:)checks if the given point is inside the circleangle(for:tolerance:)returns the angle (in radians) for a point on the circlepoint(for:tolerance:)returns the point for a given angle (in radians)tangent(at:tolerance:) returns the tangent line for a point on the circletangent(for:tolerance:)returns the tangent line for a point at the given angle (in radians)isAlmostEqual(to:tolerance:)checks if this circle is the same as another circle
CircleArc
An arc of a circle. An arc start at a point on a circle and ends at a point on a circle and can go clockwise or counter clockwise.
Creation
init(circle:startPoint:endPoint:clockwise:tolerance:)creates an arc on the circle from start to end pointinit(circle:startAngle:endAngle:clockwise:)creates an arc on the circle from start to end angleinit(center:startPoint:endPoint:clockwise:tolerance:)creates an arc on the circle with the given center going thru startPoint and endPoint.init(center:startPoint:endAngle:clockwise:tolerance:)creates an arc on the circle with the given start point and end angle
Methods
contains(angle:tolerance:)checks if the given angle is contained by the arccontains(point:tolerance:)checks if the given point on the circle is contained by the arcisAlmostEqual(to: tolerance:)checks if this arc is equal to another arcclockwisereturns this arc, but in clock wise directioncounterClockwise
Related Skills
node-connect
347.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
108.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
347.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
347.9kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
