opensolid/geometry/1.2.0

NOTE: this package is not compatible with Elm 0.19.1

OpenSolid.Arc2d

Arc2d

An Arc2d is a section of a circle, defined by its center point, start point and swept angle (the counterclockwise angle from the start point to the end point). This module includes functionality for

  • Constructing arcs through given points and/or with a given radius
  • Scaling, rotating, translating and mirroring arcs
  • Converting arcs between different coordinate systems
  • Placing 2D arcs onto sketch planes to result in 3D arcs

Arcs can be constructed explicitly by passing a record with centerPoint, startPoint and sweptAngle fields to the Arc2d constructor, for example

exampleArc =
    Arc2d
        { centerPoint = Point2d ( 1, 1 )
        , startPoint = Point2d ( 3, 1 )
        , sweptAngle = degrees 90
        }

Constructors

type Length

Argument type used in fromEndpoints.

Argument type used in fromEndpoints.

short : Length

Flag used as argument to fromEndpoints.

long : Length

Flag used as argument to fromEndpoints.

clockwise : WindingDirection

Flag used as argument to fromEndpoints.

counterclockwise : WindingDirection

Flag used as argument to fromEndpoints.

throughPoints : Point2d -> Point2d -> Point2d -> Maybe Arc2d

Attempt to construct an arc that starts at the first given point, passes through the second given point and ends at the third given point. If the three points are collinear, returns Nothing.

Arc2d.throughPoints
    Point2d.origin
    (Point2d ( 1, 0 ))
    (Point2d ( 0, 1 ))
--> Just
-->     (Arc2d
-->         { centerPoint = Point2d ( 0.5, 0.5 )
-->         , startPoint = Point2d.origin
-->         , sweptAngle = degrees 270
-->         }
-->     )


Arc2d.throughPoints
    (Point2d ( 1, 0 ))
    Point2d.origin
    (Point2d ( 0, 1 ))
--> Just
-->     (Arc2d
-->         { centerPoint = Point2d ( 0.5, 0.5 )
-->         , startPoint = Point2d ( 1, 0 )
-->         , sweptAngle = degrees -180
-->         }
-->     )


Arc2d.throughPoints
    Point2d.origin
    (Point2d ( 1, 0 ))
    (Point2d ( 2, 0 ))
--> Nothing


Arc2d.throughPoints
    Point2d.origin
    Point2d.origin
    (Point2d ( 1, 0 ))
--> Nothing
fromEndpoints : Point2d -> Point2d -> Float -> Length -> WindingDirection -> Maybe Arc2d

Attempt to construct an arc with the given start point, end point and radius. For any given valid set of start point, end point and radius, there are four possible results, so two more arguments are required to fully specify the arc to create:

  • For the fourth argument, pass either Arc2d.short or Arc2d.long to indicate whether the returned arc should be have a swept angle less than or greater than 180 degrees respectively.
  • For the fifth argument, pass either Arc2d.counterclockwise or Arc2d.clockwise to indicate whether the returned arc should be counterclockwise (have a positive swept angle) or clockwise (have a negative swept angle).

For example:

p1 =
    Point2d ( 1, 0 )


p2 =
    Point2d ( 0, 1 )


Arc2d.fromEndpoints p1 p2 1 Arc2d.short Arc2d.counterclockwise
--> Just
-->     (Arc2d
-->         { startPoint = Point2d ( 1, 0 )
-->         , centerPoint = Point2d.origin
-->         , sweptAngle = degrees 90
-->         }
-->     )


Arc2d.fromEndpoints p1 p2 1 Arc2d.short Arc2d.clockwise
--> Just
-->     (Arc2d
-->         { startPoint = Point2d ( 1, 0 )
-->         , centerPoint = Point2d ( 1, 1 )
-->         , sweptAngle = degrees -90
-->         }
-->     )


Arc2d.fromEndpoints p1 p2 1 Arc2d.long Arc2d.counterclockwise
--> Just
-->     (Arc2d
-->         { startPoint = Point2d ( 1, 0 )
-->         , centerPoint = Point2d ( 1, 1 )
-->         , sweptAngle = degrees 270
-->         }
-->     )


Arc2d.fromEndpoints p1 p2 1 Arc2d.long Arc2d.clockwise
--> Just
-->     (Arc2d
-->         { startPoint = Point2d ( 1, 0 )
-->         , centerPoint = Point2d.origin
-->         , sweptAngle = degrees -270
-->         }
-->     )


Arc2d.fromEndpoints p1 p2 2 Arc2d.short Arc2d.counterclockwise
--> Just
-->     (Arc2d
-->         { startPoint = Point2d ( 1, 0 )
-->         , centerPoint = Point2d ( -0.8229, -0.8229 )
-->         , sweptAngle = degrees 41.4096
-->         }
-->     )

If the start and end points are coincident or the distance between them is more than twice the given radius, returns Nothing:

Arc2d.fromEndpoints p1 p2 0.5 Arc2d.short Arc2d.counterclockwise
--> Nothing

Note that this means it is dangerous to use this function to construct 180 degree arcs (half circles), since in this case due to numerical roundoff the distance between the two given points may appear to be slightly more than twice the given radius. In this case it is safer to use a more specialized approach, such as

halfCircle =
    Arc2d
        { startPoint = firstPoint
        , centerPoint = Point2d.midpoint firstPoint secondPoint
        , sweptAngle = degrees 180 -- or 'degrees -180' for a clockwise arc
        }

Accessors

centerPoint : Arc2d -> Point2d

Get the center point of an arc.

Arc2d.centerPoint exampleArc
--> Point2d ( 1, 1 )
radius : Arc2d -> Float

Get the radius of an arc.

Arc2d.radius exampleArc
--> 2
startPoint : Arc2d -> Point2d

Get the start point of an arc.

Arc2d.startPoint exampleArc
--> Point2d ( 3, 1 )
endPoint : Arc2d -> Point2d

Get the end point of an arc.

Arc2d.endPoint exampleArc
--> Point2d ( 1, 3 )
sweptAngle : Arc2d -> Float

Get the swept angle of an arc in radians.

Arc2d.sweptAngle exampleArc
--> 1.5708

The result will be positive for a counterclockwise arc and negative for a clockwise one.

Evaluation

point : Arc2d -> Float -> Point2d

Get the point along an arc at a given parameter value. A parameter value of 0 corresponds to the start point of the arc and a value of 1 corresponds to the end point.

Arc2d.point exampleArc 0.5
--> Point2d ( 2.4142, 2.4142 )

Transformations

scaleAbout : Point2d -> Float -> Arc2d -> Arc2d

Scale an arc about a given point by a given scale.

Arc2d.scaleAbout (Point2d ( 0, 1 )) 2 exampleArc
--> Arc2d
-->     { startPoint = Point2d ( 6, 1 )
-->     , centerPoint = Point2d ( 2, 1 )
-->     , sweptAngle = degrees 90
-->     }
rotateAround : Point2d -> Float -> Arc2d -> Arc2d

Rotate an arc around a given point by a given angle.

Arc2d.rotateAround Point2d.origin (degrees 90)
Arc2d
    { startPoint = Point2d ( -1, 3 )
    , centerPoint = Point2d ( -1, 1 )
    , sweptAngle = degrees 90
    }
translateBy : Vector2d -> Arc2d -> Arc2d

Translate an arc by a given displacement.

displacement =
    Vector2d ( 2, 3 )


Arc2d.translateBy displacement exampleArc
--> Arc2d
-->     { startPoint = Point2d ( 5, 4 )
-->     , centerPoint = Point2d ( 3, 4 )
-->     , sweptAngle = degrees 90
-->     }
mirrorAcross : Axis2d -> Arc2d -> Arc2d

Mirror an arc across a given axis.

Arc2d.mirrorAcross Axis2d.y exampleArc
--> Arc2d
-->     { startPoint = Point2d ( -3, 1 )
-->     , centerPoint = Point2d ( -1, 1 )
-->     , sweptAngle = degrees -90
-->     }

Coordinate frames

relativeTo : Frame2d -> Arc2d -> Arc2d

Take an arc defined in global coordinates, and return it expressed in local coordinates relative to a given reference frame.

localFrame =
    Frame2d.at (Point2d ( 1, 2 ))


Arc2d.relativeTo localFrame exampleArc
--> Arc2d
-->     { startPoint = Point2d ( 2, -1 )
-->     , centerPoint = Point2d ( 0, -1 )
-->     , sweptAngle = degrees 90
-->     }
placeIn : Frame2d -> Arc2d -> Arc2d

Take an arc considered to be defined in local coordinates relative to a given reference frame, and return that arc expressed in global coordinates.

localFrame =
    Frame2d.at (Point2d ( 1, 2 ))


Arc2d.placeIn localFrame exampleArc
--> Arc2d
-->     { startPoint = Point2d ( 4, 3 )
-->     , centerPoint = Point2d ( 2, 3 )
-->     , sweptAngle = degrees 90
-->     }

Sketch planes

placeOnto : SketchPlane3d -> Arc2d -> Arc3d

Take an arc defined in 2D coordinates within a particular sketch plane and return the corresponding arc in 3D.

Arc2d.placeOnto SketchPlane3d.yz exampleArc
--> Arc3d
-->     { startPoint = Point3d ( 0, 3, 1 )
-->     , axis =
-->         Axis3d
-->             { originPoint = Point3d ( 0, 1, 1 )
-->             , direction = Direction3d.x
-->             }
-->     , sweptAngle = degrees 90
-->     }