BezierKit

repository·master·Indexed 43 days ago

https://github.com/hfutrell/bezierkit

A Swift library for working with linear, quadratic, and cubic Bézier paths. It provides geometric operations including intersection detection, curve splitting, and bounding box calculation, along with CoreGraphics drawing utilities via the Draw class.

Tokens
1.2K
Snippets
6
Records
6
Agent score
5%

What's inside BezierKit

  1. Install BezierKit via CocoaPods

    master

    To integrate BezierKit into your Xcode project using CocoaPods, add the following to your Podfile target:

    target '<Your Target Name>' do
        pod 'BezierKit', '>= 0.16.5'
    end

    Then, run pod install in your terminal.

  2. Install BezierKit via Swift Package Manager

    master

    Add BezierKit as a dependency in your Package.swift file by adding its URL to the dependencies array.

    // swift-tools-version:5.0
    import PackageDescription
    
    let package = Package(
        name: "<Your Target Name>",
        dependencies: [
            .package(url: "https://github.com/hfutrell/BezierKit.git", from: "0.16.5"),
        ]
    )
  3. Construct and draw Bezier curves

    master

    BezierKit provides CubicCurve, QuadraticCurve, and LineSegment types. All these types conform to the BezierCurve protocol. You can use the Draw utility to render them via CoreGraphics.

    • Draw.drawSkeleton(context, curve): Draws a visual representation of the curve's control points.
    • Draw.drawCurve(context, curve): Draws the actual curve.
    import BezierKit
    
    let curve = CubicCurve(
        p0: CGPoint(x: 100, y: 25),
        p1: CGPoint(x: 10, y: 90),
        p2: CGPoint(x: 110, y: 100),
        p3: CGPoint(x: 150, y: 195)
     )
     
     let context: CGContext = ...       // your graphics context here
     Draw.drawSkeleton(context, curve)  // draws visual representation of curve control points
     Draw.drawCurve(context, curve)     // draws the curve itself
  4. Split curves into subcurves

    master

    You can extract portions of a curve using two methods:

    • split(from:to:): Returns a single subcurve representing the range between two t-values.
    • split(at:): Returns a tuple (leftCurve, rightCurve) split at a specific t-value.
    Draw.setColor(context, color: Draw.lightGrey)
    Draw.drawSkeleton(context, curve: curve)
    Draw.drawCurve(context, curve: curve)
    let subcurve = curve.split(from: 0.25, to: 0.75) // or try (leftCurve, rightCurve) = curve.split(at:)
    Draw.setColor(context, color: Draw.red)
    Draw.drawCurve(context, curve: subcurve)
    Draw.drawCircle(context, center: curve.point(at: 0.25), radius: 3)
    Draw.drawCircle(context, center: curve.point(at: 0.75), radius: 3)
  5. Find intersections between curves

    master

    Use the intersections(with:) method on a BezierCurve to find where it intersects another curve. This returns an array of Intersection objects.

    Each Intersection object contains:

    • t1: The t-value on the original curve (self).
    • t2: The t-value on the passed curve.

    You can resolve these t-values into CGPoint coordinates using the point(at:) method.

    For cubic curves, you can also use selfIntersections() to find where a curve intersects itself.

    let intersections: [Intersection] = curve1.intersections(with: curve2)
    let points: [CGPoint] = intersections.map { curve1.point(at: $0.t1) }
    
    Draw.drawCurve(context, curve: curve1)
    Draw.drawCurve(context, curve: curve2)
    for p in points {
        Draw.drawPoint(context, origin: p)
    }
  6. Determine curve bounding boxes

    master

    Every BezierCurve has a boundingBox property that returns the rectangular area containing the curve. You can visualize this using Draw.drawBoundingBox(context, boundingBox:).

    let boundingBox = curve.boundingBox
    Draw.drawSkeleton(context, curve: curve)
    Draw.drawCurve(context, curve: curve)
    Draw.setColor(context, color: Draw.pinkish)
    Draw.drawBoundingBox(context, boundingBox: curve.boundingBox)