[{"name":"Arc.SweptAngle","comment":" When constructing circular or elliptical arcs, it is sometimes necessary to\nspecify which of several possible arcs you want. For example, if you ask for a\ncircular arc from the point (1, 0) to the point (0, 1) with a radius of 1, there\nare four possible solutions:\n\n  - An arc with a swept angle of 90 degrees, with center point at (0, 0)\n  - An arc with a swept angle of -270 degrees, with center point at (0, 0)\n  - An arc with a swept angle of -90 degrees, with center point at (1, 1)\n  - An Arc with a swept angle of 270 degrees, with center point at (1, 1)\n\nThe `SweptAngle` type is used in these cases to specify which arc you want.\n\n@docs SweptAngle\n@docs smallPositive, smallNegative, largePositive, largeNegative\n\n","unions":[],"aliases":[{"name":"SweptAngle","comment":" Indicate which of four possible arcs you would like to construct. Used by\n[`Arc2d.withRadius`](Arc2d#withRadius) and [`EllipticalArc2d.fromEndpoints`](EllipticalArc2d#fromEndpoints).\n","args":[],"type":"Geometry.Types.SweptAngle"}],"values":[{"name":"largeNegative","comment":" Construct a clockwise arc with a swept angle between -180 and -360 degrees.\n","type":"Arc.SweptAngle.SweptAngle"},{"name":"largePositive","comment":" Construct a counterclockwise arc with a swept angle between 180 and 360\ndegrees.\n","type":"Arc.SweptAngle.SweptAngle"},{"name":"smallNegative","comment":" Construct a clockwise arc with a swept angle between 0 and -180 degrees.\n","type":"Arc.SweptAngle.SweptAngle"},{"name":"smallPositive","comment":" Construct a counterclockwise arc with a swept angle between 0 and 180\ndegrees.\n","type":"Arc.SweptAngle.SweptAngle"}],"binops":[]},{"name":"Arc2d","comment":" An `Arc2d` is a section of a circle, defined by its center point, start\npoint and swept angle (the counterclockwise angle from the start point to the\nend point). This module includes functionality for\n\n  - Constructing arcs through given points and/or with a given radius\n  - Scaling, rotating, translating and mirroring arcs\n  - Converting arcs between different coordinate systems\n\n@docs Arc2d\n\n\n# Constructors\n\n@docs from, with, sweptAround, throughPoints, withRadius\n\n\n# Properties\n\n@docs centerPoint, radius, startPoint, endPoint, sweptAngle\n\n\n# Evaluation\n\n@docs pointOn, pointsAt\n@docs Nondegenerate, nondegenerate, fromNondegenerate\n@docs tangentDirection, tangentDirectionsAt, sample, samplesAt\n\n\n# Linear approximation\n\n@docs toPolyline\n\n\n# Transformations\n\n@docs reverse, scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n\n# Differentiation\n\nYou are unlikely to need to use these functions directly, but they are useful if\nyou are writing low-level geometric algorithms.\n\n@docs firstDerivative, firstDerivativesAt\n\n","unions":[{"name":"Nondegenerate","comment":" If a curve has zero length (consists of just a single point), then we say\nthat it is 'degenerate'. Some operations such as computing tangent directions\nare not defined on degenerate curves.\n\nA `Nondegenerate` value represents an arc that is definitely not degenerate. It\nis used as input to functions such as `Arc2d.tangentDirection` and can be\nconstructed using `Arc2d.nondegenerate`.\n\n","args":[],"cases":[]}],"aliases":[{"name":"Arc2d","comment":" ","args":[],"type":"Geometry.Types.Arc2d"}],"values":[{"name":"centerPoint","comment":" Get the center point of an arc.\n\n    Arc2d.centerPoint exampleArc\n    --> Point2d.fromCoordinates ( 1, 1 )\n\n","type":"Arc2d.Arc2d -> Point2d.Point2d"},{"name":"endPoint","comment":" Get the end point of an arc.\n\n    Arc2d.endPoint exampleArc\n    --> Point2d.fromCoordinates ( 1, 3 )\n\n","type":"Arc2d.Arc2d -> Point2d.Point2d"},{"name":"firstDerivative","comment":" Get the first derivative of an arc at a given parameter value:\n\n    Arc2d.firstDerivative exampleArc ParameterValue.zero\n    --> Vector2d.fromComponents ( 0, 3.1416 )\n\n    Arc2d.firstDerivative exampleArc ParameterValue.half\n    --> Vector2d.fromComponents ( -2.2214, 2.2214 )\n\n    Arc2d.firstDerivative exampleArc ParameterValue.one\n    --> Vector2d.fromComponents ( -3.1416, 0 )\n\n","type":"Arc2d.Arc2d -> Curve.ParameterValue.ParameterValue -> Vector2d.Vector2d"},{"name":"firstDerivativesAt","comment":" Evaluate the first derivative of an arc at a given set of parameter values:\n\n    exampleArc\n        |> Arc2d.firstDerivativesAt\n            (ParameterValue.steps 2)\n    --> [ Vector2d.fromComponents ( 0, 3.1416 )\n    --> , Vector2d.fromComponents ( -2.2214, 2.2214 )\n    --> , Vector2d.fromComponents ( -3.1416, 0 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> Arc2d.Arc2d -> List.List Vector2d.Vector2d"},{"name":"from","comment":" Construct an arc with from the first given point to the second, with the\ngiven swept angle.\n\n    p1 =\n        Point2d.fromCoordinates ( 2, 1 )\n\n    p2 =\n        Point2d.fromCoordinates ( 1, 2 )\n\n    arc1 =\n        Arc2d.from p1 p2 (degrees 90)\n\n    Arc2d.centerPoint arc1\n    --> Point2d.fromCoordinates ( 1, 1 )\n\n    arc2 =\n        Arc2d.from p1 p2 (degrees -90)\n\n    Arc2d.centerPoint arc2\n    --> Point2d.fromCoordinates ( 2, 2 )\n\n    arc3 =\n        Arc2d.from p1 p2 (degrees 180)\n\n    Arc2d.centerPoint arc3\n    --> Point2d.fromCoordinates ( 1.5, 1.5 )\n\n    arc4 =\n        Arc2d.from p1 p2 (degrees -180)\n\n    Arc2d.centerPoint arc4\n    --> Point2d.fromCoordinates ( 1.5, 1.5 )\n\n    arc5 =\n        Arc2d.from p1 p2 (degrees 45)\n\n    Arc2d.centerPoint arc5\n    --> Point2d.fromCoordinates ( 0.2929, 0.2929 )\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Basics.Float -> Arc2d.Arc2d"},{"name":"fromNondegenerate","comment":" Convert a nondegenerate arc back to a general `Arc2d`.\n\n    Arc2d.fromNondegenerate nondegenerateExampleArc\n    --> exampleArc\n\n","type":"Arc2d.Nondegenerate -> Arc2d.Arc2d"},{"name":"mirrorAcross","comment":" Mirror an arc across a given axis.\n\n    Arc2d.mirrorAcross Axis2d.y exampleArc\n    --> Point2d.fromCoordinates ( -3, 1 )\n    -->     |> Arc2d.sweptAround\n    -->         (Point2d.fromCoordinates ( -1, 1 ))\n    -->         (degrees -90)\n\n","type":"Axis2d.Axis2d -> Arc2d.Arc2d -> Arc2d.Arc2d"},{"name":"nondegenerate","comment":" Attempt to construct a nondegenerate arc from a general `Arc2d`. If the arc\nis in fact degenerate (consists of a single point), returns an `Err` with that\npoint.\n\n    Arc2d.nondegenerate exampleArc\n    --> Ok nondegenerateExampleArc\n\n","type":"Arc2d.Arc2d -> Result.Result Point2d.Point2d Arc2d.Nondegenerate"},{"name":"placeIn","comment":" Take an arc considered to be defined in local coordinates relative to a\ngiven reference frame, and return that arc expressed in global coordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Arc2d.placeIn localFrame exampleArc\n    --> Point2d.fromCoordinates ( 4, 3 )\n    -->     |> Arc2d.sweptAround\n    -->         (Point2d.fromCoordinates ( 2, 3 ))\n    -->         (degrees 90)\n\n","type":"Frame2d.Frame2d -> Arc2d.Arc2d -> Arc2d.Arc2d"},{"name":"pointOn","comment":" Get the point along an arc at a given parameter value:\n\n    Arc2d.pointOn exampleArc ParameterValue.zero\n    --> Point2d.fromCoordinates ( 3, 1 )\n\n    Arc2d.pointOn exampleArc ParameterValue.half\n    --> Point2d.fromCoordinates ( 2.4142, 2.4142 )\n\n    Arc2d.pointOn exampleArc ParameterValue.one\n    --> Point2d.fromCoordinates ( 1, 3 )\n\n","type":"Arc2d.Arc2d -> Curve.ParameterValue.ParameterValue -> Point2d.Point2d"},{"name":"pointsAt","comment":" Get points along an arc at a given set of parameter values:\n\n    exampleArc |> Arc2d.pointsAt (ParameterValue.steps 2)\n    --> [ Point2d.fromCoordinates ( 3, 1 )\n    --> , Point2d.fromCoordinates ( 2.4142, 2.4142 )\n    --> , Point2d.fromCoordinates ( 1, 3 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> Arc2d.Arc2d -> List.List Point2d.Point2d"},{"name":"radius","comment":" Get the radius of an arc.\n\n    Arc2d.radius exampleArc\n    --> 2\n\n","type":"Arc2d.Arc2d -> Basics.Float"},{"name":"relativeTo","comment":" Take an arc defined in global coordinates, and return it expressed in local\ncoordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Arc2d.relativeTo localFrame exampleArc\n    --> Point2d.fromCoordinates ( 2, -1 )\n    -->     |> Arc2d.sweptAround\n    -->         (Point2d.fromCoordinates ( 0, -1 ))\n    -->         (degrees 90)\n\n","type":"Frame2d.Frame2d -> Arc2d.Arc2d -> Arc2d.Arc2d"},{"name":"reverse","comment":" Reverse the direction of an arc, so that the start point becomes the end\npoint and vice versa.\n\n    Arc2d.reverse exampleArc\n    --> Point2d.fromCoordinates ( 1, 3 )\n    -->     |> Arc2d.sweptAround\n    -->         (Point2d.fromCoordinates ( 1, 1 ))\n    -->         (degrees -90)\n\n","type":"Arc2d.Arc2d -> Arc2d.Arc2d"},{"name":"rotateAround","comment":" Rotate an arc around a given point by a given angle.\n\n    Arc2d.rotateAround Point2d.origin (degrees 90)\n    --> Point2d.fromCoordinates ( -1, 3 )\n    -->     |> Arc2d.sweptAround\n    -->         (Point2d.fromCoordinates ( -1, 1 ))\n    -->         (degrees 90)\n\n","type":"Point2d.Point2d -> Basics.Float -> Arc2d.Arc2d -> Arc2d.Arc2d"},{"name":"sample","comment":" Get both the point and tangent direction of a nondegenerate arc at a given\nparameter value:\n\n    Arc2d.sample nondegenerateExampleArc\n        ParameterValue.zero\n    --> ( Point2d.fromCoordinates ( 3, 1 )\n    --> , Direction2d.fromAngle (degrees 90)\n    --> )\n\n    Arc2d.sample nondegenerateExampleArc\n        ParameterValue.half\n    --> ( Point2d.fromCoordinates ( 2.4142, 2.4142 )\n    --> , Direction2d.fromAngle (degrees 135)\n    --> )\n\n    Arc2d.sample nondegenerateExampleArc\n        ParameterValue.one\n    --> ( Point2d.fromCoordinates ( 1, 3 )\n    --> , Direction2d.fromAngle (degrees 180)\n    --> )\n\n","type":"Arc2d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"samplesAt","comment":" Get points and tangent directions of a nondegenerate arc at a given set of\nparameter values:\n\n    nondegenerateExampleArc\n        |> Arc2d.samplesAt (ParameterValue.steps 2)\n    --> [ ( Point2d.fromCoordinates ( 3, 1 )\n    -->   , Direction2d.fromAngle (degrees 90)\n    -->   )\n    --> , ( Point2d.fromCoordinates ( 2.4142, 2.4142 )\n    -->   , Direction2d.fromAngle (degrees 135)\n    -->   )\n    --> , ( Point2d.fromCoordinates ( 1, 3 )\n    -->   , Direction2d.fromAngle (degrees 180)\n    -->   )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> Arc2d.Nondegenerate -> List.List ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"scaleAbout","comment":" Scale an arc about a given point by a given scale.\n\n    point =\n        Point2d.fromCoordinates ( 0, 1 )\n\n    Arc2d.scaleAbout point 2 exampleArc\n    --> Point2d.fromCoordinates ( 6, 1 )\n    -->     |> Arc2d.sweptAround\n    -->         (Point2d.fromCoordinates ( 2, 1 ))\n    -->         (degrees 90)\n\n","type":"Point2d.Point2d -> Basics.Float -> Arc2d.Arc2d -> Arc2d.Arc2d"},{"name":"startPoint","comment":" Get the start point of an arc.\n\n    Arc2d.startPoint exampleArc\n    --> Point2d.fromCoordinates ( 3, 1 )\n\n","type":"Arc2d.Arc2d -> Point2d.Point2d"},{"name":"sweptAngle","comment":" Get the swept angle of an arc in radians.\n\n    Arc2d.sweptAngle exampleArc\n    --> 1.5708\n\nThe result will be positive for a counterclockwise arc and negative for a\nclockwise one.\n\n","type":"Arc2d.Arc2d -> Basics.Float"},{"name":"sweptAround","comment":" Construct an arc by sweeping (rotating) a given start point around a given\ncenter point by a given angle. The center point to sweep around is given first\nand the start point to be swept is given last.\n\n    exampleArc =\n        Point2d.fromCoordinates ( 3, 1 )\n            |> Arc2d.sweptAround\n                (Point2d.fromCoordinates ( 1, 1 ))\n                (degrees 90)\n\n    Arc2d.endPoint exampleArc\n    --> Point2d.fromCoordinates ( 1, 3 )\n\nNote that the 'actual' form of this function is\n\n    arc =\n        Arc2d.sweptAround centerPoint sweptAngle startPoint\n\nbut it is generally written using the pipe operator `|>` (as in the first\nexample) to improve readability:\n\n    arc =\n        startPoint\n            |> Arc2d.sweptAround centerPoint sweptAngle\n\nA positive swept angle means that the arc is formed by rotating the start point\ncounterclockwise around the center point. A negative swept angle results in\na clockwise arc instead.\n\n","type":"Point2d.Point2d -> Basics.Float -> Point2d.Point2d -> Arc2d.Arc2d"},{"name":"tangentDirection","comment":" Get the tangent direction to a nondegenerate arc at a given parameter\nvalue:\n\n    Arc2d.tangentDirection nondegenerateExampleArc\n        ParameterValue.zero\n    --> Direction2d.fromAngle (degrees 90)\n\n    Arc2d.tangentDirection nondegenerateExampleArc\n        ParameterValue.half\n    --> Direction2d.fromAngle (degrees 135)\n\n    Arc2d.tangentDirection nondegenerateExampleArc\n        ParameterValue.one\n    --> Direction2d.fromAngle (degrees 180)\n\n","type":"Arc2d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> Direction2d.Direction2d"},{"name":"tangentDirectionsAt","comment":" Get tangent directions to a nondegenerate arc at a given set of parameter\nvalues:\n\n    nondegenerateExampleArc\n        |> Arc2d.tangentDirectionsAt\n            (ParameterValue.steps 2)\n    --> [ Direction2d.fromAngle (degrees 90)\n    --> , Direction2d.fromAngle (degrees 135)\n    --> , Direction2d.fromAngle (degrees 180)\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> Arc2d.Nondegenerate -> List.List Direction2d.Direction2d"},{"name":"throughPoints","comment":" Attempt to construct an arc that starts at the first given point, passes\nthrough the second given point and ends at the third given point:\n\n    Arc2d.throughPoints\n        Point2d.origin\n        (Point2d.fromCoordinates ( 1, 0 ))\n        (Point2d.fromCoordinates ( 0, 1 ))\n    --> Just\n    -->     (Point2d.origin\n    -->         |> Arc2d.sweptAround\n    -->             (Point2d.fromCoordinates ( 0.5, 0.5 ))\n    -->             (degrees 270)\n    -->     )\n\n    Arc2d.throughPoints\n        (Point2d.fromCoordinates ( 1, 0 ))\n        Point2d.origin\n        (Point2d.fromCoordinates ( 0, 1 ))\n    --> Just\n    -->     (Point2d.fromCoordinates ( 1, 0 )\n    -->         |> Arc2d.sweptAround\n    -->             (Point2d.fromCoordinates ( 0.5, 0.5 ))\n    -->             (degrees -180)\n    -->     )\n\nIf the three points are collinear, returns `Nothing`:\n\n    Arc2d.throughPoints\n        Point2d.origin\n        (Point2d.fromCoordinates ( 1, 0 ))\n        (Point2d.fromCoordinates ( 2, 0 ))\n    --> Nothing\n\n    Arc2d.throughPoints\n        Point2d.origin\n        Point2d.origin\n        (Point2d.fromCoordinates ( 1, 0 ))\n    --> Nothing\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Point2d.Point2d -> Maybe.Maybe Arc2d.Arc2d"},{"name":"toPolyline","comment":" Approximate an arc as a polyline, within a given tolerance:\n\n    exampleArc |> Arc2d.toPolyline { maxError = 0.1 }\n    --> Polyline2d.fromVertices\n    -->     [ Point2d.fromCoordinates ( 3, 1 )\n    -->     , Point2d.fromCoordinates ( 2.732, 2 )\n    -->     , Point2d.fromCoordinates ( 2, 2.732 )\n    -->     , Point2d.fromCoordinates ( 1, 3 )\n    -->     ]\n\nIn this example, every point on the returned polyline will be within 0.1 units\nof the original arc.\n\n","type":"{ maxError : Basics.Float } -> Arc2d.Arc2d -> Polyline2d.Polyline2d"},{"name":"translateBy","comment":" Translate an arc by a given displacement.\n\n    displacement =\n        Vector2d.fromComponents ( 2, 3 )\n\n    Arc2d.translateBy displacement exampleArc\n    --> Point2d.fromCoordinates ( 5, 4 )\n    -->     |> Arc2d.sweptAround\n    -->         (Point2d.fromCoordinates ( 3, 4 ))\n    -->         (degrees 90)\n\n","type":"Vector2d.Vector2d -> Arc2d.Arc2d -> Arc2d.Arc2d"},{"name":"translateIn","comment":" Translate an arc in a given direction by a given distance;\n\n    Arc2d.translateIn direction distance\n\nis equivalent to\n\n    Arc2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Arc2d.Arc2d -> Arc2d.Arc2d"},{"name":"with","comment":" Construct an arc with the given center point, radius, start angle and swept\nangle:\n\n    arc =\n        Arc2d.with\n            { centerPoint =\n                Point2d.fromCoordinates ( 2, 0 )\n            , radius = 1\n            , startAngle = degrees 45\n            , sweptAngle = degrees -90\n            }\n\n    Arc2d.startPoint arc\n    --> Point2d.fromCoordinates ( 2.7071, 0.7071 )\n\n    Arc2d.endPoint arc\n    --> Point2d.fromCoordinates ( 2.7071, -0.7071 )\n\n","type":"{ centerPoint : Point2d.Point2d, radius : Basics.Float, startAngle : Basics.Float, sweptAngle : Basics.Float } -> Arc2d.Arc2d"},{"name":"withRadius","comment":" Attempt to construct an arc with the given radius between the given start\nand end points. Note that this is only possible if the given radius is large\nenough! For any given valid radius, start point and end point, there are four\npossible results, so the [`SweptAngle`](Arc-SweptAngle) argument is used to\nspecify which arc to create. For example:\n\n    p1 =\n        Point2d.fromCoordinates ( 1, 0 )\n\n    p2 =\n        Point2d.fromCoordinates ( 0, 1 )\n\n    Arc2d.withRadius 1 SweptAngle.smallPositive p1 p2\n    --> Just\n    -->     (Point2d.fromCoordinates ( 1, 0 )\n    -->         |> Arc2d.sweptAround Point2d.origin\n    -->             (degrees 90)\n    -->     )\n\n    Arc2d.withRadius 1 SweptAngle.smallNegative p1 p2\n    --> Just\n    -->     (Point2d.fromCoordinates ( 1, 0 )\n    -->         |> Arc2d.sweptAround\n    -->             (Point2d.fromCoordinates ( 1, 1 ))\n    -->             (degrees -90)\n    -->     )\n\n    Arc2d.withRadius 1 SweptAngle.largePositive p1 p2\n    --> Just\n    -->     (Point2d.fromCoordinates ( 1, 0 )\n    -->         |> Arc2d.sweptAround\n    -->             (Point2d.fromCoordinates ( 1, 1 ))\n    -->             (degrees 270)\n    -->     )\n\n    Arc2d.withRadius 1 SweptAngle.largeNegative p1 p2\n    --> Just\n    -->     (Point2d.fromCoordinates ( 1, 0 )\n    -->         |> Arc2d.sweptAround Point2d.origin\n    -->             (degrees -270)\n    -->     )\n\n    Arc2d.withRadius 2 SweptAngle.smallPositive p1 p2\n    --> Just\n    -->     (Point2d.fromCoordinates ( 1, 0 )\n    -->         |> Arc2d.sweptAround\n    -->             (Point2d.fromCoordinates\n    -->                 ( -0.8229, -0.8229 )\n    -->             )\n    -->             (degrees 41.4096)\n    -->     )\n\nIf the start and end points are coincident or the distance between them is more\nthan twice the given radius, returns `Nothing`:\n\n    -- p1 and p2 are too far apart to be connected by an\n    -- arc of radius 0.5\n    Arc2d.withRadius 0.5 SweptAngle.smallPositive p1 p2\n    --> Nothing\n\nNote that this means it is dangerous to use this function to construct 180\ndegree arcs (half circles), since in this case due to numerical roundoff the\ndistance between the two given points may appear to be slightly more than twice\nthe given radius. In this case it is safer to use `Arc2d.from`, such as (for a\ncounterclockwise arc):\n\n    halfCircle =\n        Arc2d.from firstPoint secondPoint (degrees 180)\n\n(Use `degrees -180` for a clockwise arc.)\n\n","type":"Basics.Float -> Arc.SweptAngle.SweptAngle -> Point2d.Point2d -> Point2d.Point2d -> Maybe.Maybe Arc2d.Arc2d"}],"binops":[]},{"name":"Arc3d","comment":" An `Arc3d` is a section of a circle in 3D, defined by its central axis,\nstart point and swept angle (the counterclockwise angle around the axis from the\nstart point to the arc's end point). This module includes functionality for\n\n  - Constructing arcs through given points\n  - Scaling, rotating, translating and mirroring arcs\n  - Converting arcs between different coordinate systems\n\n@docs Arc3d\n\n\n# Constructors\n\n@docs on, sweptAround, throughPoints\n\n\n# Properties\n\n@docs axialDirection, axis, centerPoint, radius, startPoint, endPoint, sweptAngle\n\n\n# Evaluation\n\n@docs pointOn, pointsAt\n@docs Nondegenerate, nondegenerate, fromNondegenerate\n@docs tangentDirection, tangentDirectionsAt, sample, samplesAt\n\n\n# Linear approximation\n\n@docs toPolyline\n\n\n# Transformations\n\n@docs reverse, scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectInto\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n\n# Differentiation\n\nYou are unlikely to need to use these functions directly, but they are useful if\nyou are writing low-level geometric algorithms.\n\n@docs firstDerivative, firstDerivativesAt\n\n","unions":[{"name":"Nondegenerate","comment":" If a curve has zero length (consists of just a single point), then we say\nthat it is 'degenerate'. Some operations such as computing tangent directions\nare not defined on degenerate curves.\n\nA `Nondegenerate` value represents an arc that is definitely not degenerate. It\nis used as input to functions such as `Arc3d.tangentDirection` and can be\nconstructed using `Arc3d.nondegenerate`.\n\n","args":[],"cases":[]}],"aliases":[{"name":"Arc3d","comment":" ","args":[],"type":"Geometry.Types.Arc3d"}],"values":[{"name":"axialDirection","comment":" Get the axial direction of an arc.\n\n    Arc3d.axialDirection exampleArc\n    --> Direction3d.z\n\n","type":"Arc3d.Arc3d -> Direction3d.Direction3d"},{"name":"axis","comment":" Get the central axis of an arc. The origin point of the axis will be equal\nto the center point of the arc.\n\n    Arc3d.axis exampleArc\n    --> Axis3d.z\n\n","type":"Arc3d.Arc3d -> Axis3d.Axis3d"},{"name":"centerPoint","comment":" Get the center point of an arc.\n\n    Arc3d.centerPoint exampleArc\n    --> Point3d.origin\n\n","type":"Arc3d.Arc3d -> Point3d.Point3d"},{"name":"endPoint","comment":" Get the end point of an arc.\n\n    Arc3d.endPoint exampleArc\n    --> Point3d.fromCoordinates ( -1, 1, 0 )\n\n","type":"Arc3d.Arc3d -> Point3d.Point3d"},{"name":"firstDerivative","comment":" Get the first derivative of an arc at a given parameter value.\n\n    Arc3d.firstDerivative exampleArc ParameterValue.zero\n    --> Vector3d.fromComponents ( -1.5708, 1.5708, 0 )\n\n    Arc3d.firstDerivative exampleArc ParameterValue.one\n    --> Vector3d.fromComponents ( -1.5708, -1.5708, 0 )\n\n","type":"Arc3d.Arc3d -> Curve.ParameterValue.ParameterValue -> Vector3d.Vector3d"},{"name":"firstDerivativesAt","comment":" Evaluate the first derivative of an arc at a range of parameter values.\n\n    exampleArc\n        |> Arc3d.firstDerivativesAt\n            (ParameterValue.steps 2)\n    --> [ Vector3d ( -1.5708, 1.5708, 0 )\n    --> , Vector3d ( -2.2214, 0, 0 )\n    --> , Vector3d ( -1.5708, -1.5708, 0 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> Arc3d.Arc3d -> List.List Vector3d.Vector3d"},{"name":"fromNondegenerate","comment":" Convert a nondegenerate arc back to a general `Arc3d`.\n\n    Arc3d.fromNondegenerate nondegenerateExampleArc\n    --> exampleArc\n\n","type":"Arc3d.Nondegenerate -> Arc3d.Arc3d"},{"name":"mirrorAcross","comment":" Mirror an arc across a given plane.\n\n    Arc3d.mirrorAcross Plane3d.xy exampleArc\n    --> Arc3d.sweptAround (Axis3d.reverse Axis3d.z)\n    -->     (degrees -90)\n    -->     (Point3d.fromCoordinates ( 1, 1, 0 ))\n\nNote that this flips the sign of the arc's swept angle.\n\n","type":"Plane3d.Plane3d -> Arc3d.Arc3d -> Arc3d.Arc3d"},{"name":"nondegenerate","comment":" Attempt to construct a nondegenerate arc from a general `Arc3d`. If the arc\nis in fact degenerate (consists of a single point), returns an `Err` with that\npoint.\n\n    Arc3d.nondegenerate exampleArc\n    --> Ok nondegenerateExampleArc\n\n","type":"Arc3d.Arc3d -> Result.Result Point3d.Point3d Arc3d.Nondegenerate"},{"name":"on","comment":" Construct a 3D arc lying _on_ a sketch plane by providing a 2D arc specified\nin XY coordinates _within_ the sketch plane.\n\n    arc =\n        Arc3d.on SketchPlane3d.xz\n            (Point2d.fromCoordinates ( 3, 1 )\n                |> Arc2d.sweptAround\n                    (Point2d.fromCoordinates ( 1, 1 )\n                    (degrees 90)\n            )\n\n    Arc3d.centerPoint arc\n    --> Point3d.fromCoordinates ( 1, 0, 1 )\n\n    Arc3d.radius arc\n    --> 2\n\n    Arc3d.startPoint arc\n    --> Point3d.fromCoordinates ( 3, 0, 1 )\n\n    Arc3d.endPoint arc\n    --> Point3d.fromCoordinates ( 1, 0, 3 )\n\n","type":"SketchPlane3d.SketchPlane3d -> Arc2d.Arc2d -> Arc3d.Arc3d"},{"name":"placeIn","comment":" Take an arc considered to be defined in local coordinates relative to a\ngiven reference frame, and return that arc expressed in global coordinates.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Arc3d.placeIn localFrame exampleArc\n    --> Arc3d.sweptAround\n    -->     (Axis3d.withDirection Direction3d.z\n    -->         (Point3d.fromCoordinates ( 1, 2, 3 ))\n    -->     )\n    -->     (degrees 90)\n    -->     (Point3d.fromCoordinates ( 2, 3, 3 ))\n\n","type":"Frame3d.Frame3d -> Arc3d.Arc3d -> Arc3d.Arc3d"},{"name":"pointOn","comment":" Get the point along an arc at a given parameter value:\n\n    Arc3d.pointOn exampleArc ParameterValue.half\n    --> Point3d.fromCoordinates ( 0, 1.4142, 0 )\n\n","type":"Arc3d.Arc3d -> Curve.ParameterValue.ParameterValue -> Point3d.Point3d"},{"name":"pointsAt","comment":" Get points along an arc at a given set of parameter values.\n\n    exampleArc |> Arc3d.pointsAt (ParameterValue.steps 2)\n    --> [ Point3d ( 1, 1, 0 )\n    --> , Point3d ( 0, 1.4142, 0 )\n    --> , Point3d ( -1, 1, 0 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> Arc3d.Arc3d -> List.List Point3d.Point3d"},{"name":"projectInto","comment":" Project an arc into a sketch plane.\n\n    axis : Axis3d\n    axis =\n        Axis3d.through\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n            (Direction3d.fromAzimuthAndElevation\n                (degrees 0)\n                (degrees 45)\n            )\n\n    arc : Arc3d\n    arc =\n        Arc3d.sweptAround axis\n            (degrees 45)\n            (Point3d.fromCoordinates ( 1, 4, 3 ))\n\n    Arc3d.projectInto SketchPlane3d.xy arc\n    --> EllipticalArc2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( 1, 2 )\n    -->     , xDirection = Direction2d.y\n    -->     , xRadius = 2\n    -->     , yRadius = 1.4142\n    -->     , startAngle = degrees 0\n    -->     , sweptAngle = degrees 45\n    -->     }\n\n","type":"SketchPlane3d.SketchPlane3d -> Arc3d.Arc3d -> Geometry.Types.EllipticalArc2d"},{"name":"radius","comment":" Get the radius of an arc.\n\n    Arc3d.radius exampleArc\n    --> 1.4142\n\n","type":"Arc3d.Arc3d -> Basics.Float"},{"name":"relativeTo","comment":" Take an arc defined in global coordinates, and return it expressed in local\ncoordinates relative to a given reference frame.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Arc3d.relativeTo localFrame exampleArc\n    --> Arc3d.sweptAround\n    -->     (Axis3d.withDirection Direction3d.z\n    -->         (Point3d ( -1, -2, -3 ))\n    -->     )\n    -->     (degrees 90)\n    -->     (Point3d.fromCoordinates ( 0, -1, -3 ))\n\n","type":"Frame3d.Frame3d -> Arc3d.Arc3d -> Arc3d.Arc3d"},{"name":"reverse","comment":" Reverse the direction of an arc, so that the start point becomes the end\npoint and vice versa. The resulting arc will have the same axis as the original\nbut a swept angle with the opposite sign.\n\n    Arc3d.reverse exampleArc\n    --> Arc3d.sweptAround Axis3d.z\n    -->     (degrees -90)\n    -->     (Point3d.fromCoordinates ( -1, 1, 0 ))\n\n","type":"Arc3d.Arc3d -> Arc3d.Arc3d"},{"name":"rotateAround","comment":" Rotate an arc around a given axis by a given angle (in radians).\n\n    Arc3d.rotateAround Axis3d.x (degrees 90) exampleArc\n    --> Arc3d.sweptAround (Axis3d.reverse Axis3d.y)\n    -->     (degrees 90)\n    -->     (Point3d.fromCoordinates ( 1, 0, 1 ))\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Arc3d.Arc3d -> Arc3d.Arc3d"},{"name":"sample","comment":" Get both the point and tangent direction of a nondegenerate arc at a given\nparameter value:\n\n    Arc3d.sample nondegenerateExampleArc\n        ParameterValue.zero\n    --> ( Point3d.fromCoordinates ( 1, 1, 0 )\n    --> , Direction3d.fromAzimuthAndElevation\n    -->     (degrees 135)\n    -->     (degrees 0)\n    --> )\n\n    Arc3d.sample nondegenerateExampleArc\n        ParameterValue.half\n    --> ( Point3d.fromCoordinates ( 0, 1.4142, 0 )\n    --> , Direction3d.negativeX\n    --> )\n\n    Arc3d.sample nondegenerateExampleArc\n        ParameterValue.one\n    --> ( Point3d.fromCoordinates ( -1, 1, 0 )\n    --> , Direction3d.fromAzimuthAndElevation\n    -->     (degrees 225)\n    -->     (degrees 0)\n    --> )\n\n","type":"Arc3d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> ( Point3d.Point3d, Direction3d.Direction3d )"},{"name":"samplesAt","comment":" Get points and tangent directions of a nondegenerate arc at a given set of\nparameter values:\n\n    nondegenerateExampleArc\n        |> Arc3d.samplesAt (ParameterValue.steps 2)\n    --> [ ( Point3d.fromCoordinates ( 1, 1, 0 )\n    -->   , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 135)\n    -->         (degrees 0)\n    -->   )\n    --> , ( Point3d.fromCoordinates ( 0, 1.4142, 0 )\n    -->   , Direction3d.negativeX\n    -->   )\n    --> , ( Point3d.fromCoordinates ( -1, 1, 0 )\n    -->   , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 225)\n    -->         (degrees 0)\n    -->   )\n    --> ]\n\nIf the arc is degenerate (start point and end point are equal), returns an\nempty list.\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> Arc3d.Nondegenerate -> List.List ( Point3d.Point3d, Direction3d.Direction3d )"},{"name":"scaleAbout","comment":" Scale an arc about the given center point by the given scale.\n\n    point =\n        Point3d.fromCoordinates ( 0, -1, 0 )\n\n    Arc3d.scaleAbout point 2 exampleArc\n    --> Arc3d.sweptAround\n    -->     (Axis3d.withDirection Direction3d.z\n    -->         (Point3d.fromCoordinates ( 0, 1, 0 ))\n    -->     )\n    -->     (degrees 90)\n    -->     (Point3d.fromCoordinates ( 2, 3, 0 ))\n\n","type":"Point3d.Point3d -> Basics.Float -> Arc3d.Arc3d -> Arc3d.Arc3d"},{"name":"startPoint","comment":" Get the start point of an arc.\n\n    Arc3d.startPoint exampleArc\n    --> Point3d.fromCoordinates ( 1, 1, 0 )\n\n","type":"Arc3d.Arc3d -> Point3d.Point3d"},{"name":"sweptAngle","comment":" Get the swept angle of an arc in radians.\n\n    Arc3d.sweptAngle exampleArc\n    --> 1.5708\n\nA positive swept angle means that the arc is formed by rotating the given start\npoint counterclockwise around the central axis, and vice versa for a negative\nangle.\n\n","type":"Arc3d.Arc3d -> Basics.Float"},{"name":"sweptAround","comment":" Construct an arc by sweeping the given point around the given axis by the\ngiven angle:\n\n    exampleArc =\n        Point3d.fromCoordinates ( 1, 1, 0 )\n            |> Arc3d.sweptAround Axis3d.z (degrees 90)\n\n    Arc3d.centerPoint exampleArc\n    --> Point3d.origin\n\n    Arc3d.endPoint exampleArc\n    --> Point3d.fromCoordinates ( -1, 1, 0 )\n\nPositive swept angles result in a counterclockwise (right-handed) rotation\naround the given axis and vice versa for negative swept angles. The center point\nof the returned arc will lie on the given axis.\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Point3d.Point3d -> Arc3d.Arc3d"},{"name":"tangentDirection","comment":" Get the tangent direction to a nondegenerate arc at a given parameter\nvalue:\n\n    Arc3d.tangentDirection nondegenerateExampleArc\n        ParameterValue.zero\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 135)\n    -->     (degrees 0)\n\n    Arc3d.tangentDirection nondegenerateExampleArc\n        ParameterValue.half\n    --> Direction3d.negativeX\n\n    Arc3d.tangentDirection nondegenerateExampleArc\n        ParameterValue.zero\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 225)\n    -->     (degrees 0)\n\n","type":"Arc3d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> Direction3d.Direction3d"},{"name":"tangentDirectionsAt","comment":" Get tangent directions to a nondegenerate arc at a given set of parameter\nvalues:\n\n    nondegenerateExampleArc\n        |> Arc3d.tangentDirectionsAt\n            (ParameterValue.steps 2)\n    --> [ Direction3d.fromAzimuthAndElevation\n    -->     (degrees 135)\n    -->     (degrees 0)\n    --> , Direction3d.negativeX\n    --> , Direction3d.fromAzimuthAndElevation\n    -->     (degrees 225)\n    -->     (degrees 0)\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> Arc3d.Nondegenerate -> List.List Direction3d.Direction3d"},{"name":"throughPoints","comment":" Attempt to construct an arc that starts at the first given point, passes\nthrough the second given point and ends at the third given point. If the three\npoints are collinear, returns `Nothing`.\n\n    p1 =\n        Point3d.fromCoordinates ( 0, 0, 1 )\n\n    p2 =\n        Point3d.origin\n\n    p3 =\n        Point3d.fromCoordinates ( 0, 1, 0 )\n\n    Arc3d.throughPoints p1 p2 p3\n    --> Just\n    -->     (Arc3d.on SketchPlane3d.yz\n    -->         Point2d.fromCoordinates ( 0, 1 )\n    -->             |> Arc2d.sweptAround\n    -->                 (Point2d.fromCoordinates\n    -->                     ( 0.5, 0.5 )\n    -->                 )\n    -->                 (degrees 180)\n    -->     )\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Point3d.Point3d -> Maybe.Maybe Arc3d.Arc3d"},{"name":"toPolyline","comment":" Approximate an arc as a polyline, within a given tolerance:\n\n    exampleArc |> Arc3d.toPolyline { maxError = 0.1 }\n    --> Polyline3d.fromVertices\n    -->     [ Point3d.fromCoordinates ( 1, 1, 0 )\n    -->     , Point3d.fromCoordinates ( 0.366, 1.366, 0 )\n    -->     , Point3d.fromCoordinates ( -0.366, 1.366, 0 )\n    -->     , Point3d.fromCoordinates ( -1, 1, 0 )\n    -->     ]\n\nIn this example, every point on the returned polyline will be within 0.1 units\nof the original arc.\n\n","type":"{ maxError : Basics.Float } -> Arc3d.Arc3d -> Polyline3d.Polyline3d"},{"name":"translateBy","comment":" Translate an arc by a given displacement.\n\n    displacement =\n        Vector3d.fromComponents ( 2, 1, 3 )\n\n    Arc3d.translateBy displacement exampleArc\n    --> Arc3d.sweptAround\n    -->     (Axis3d.withDirection Direction3d.z\n    -->         (Point3d ( 2, 1, 3 ))\n    -->     )\n    -->     (degrees 90)\n    -->     (Point3d.fromCoordinates ( 3, 2, 3 ))\n\n","type":"Vector3d.Vector3d -> Arc3d.Arc3d -> Arc3d.Arc3d"},{"name":"translateIn","comment":" Translate an arc in a given direction by a given distance;\n\n    Arc3d.translateIn direction distance\n\nis equivalent to\n\n    Arc3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> Arc3d.Arc3d -> Arc3d.Arc3d"}],"binops":[]},{"name":"Axis2d","comment":" An `Axis2d` represents an infinitely long straight line in 2D and is defined\nby an origin point and direction. Axes have several uses, such as:\n\n  - Mirroring across the axis\n  - Projecting onto the axis\n  - Measuring distance along the axis from the origin point\n\n@docs Axis2d\n\n\n# Constants\n\n@docs x, y\n\n\n# Constructors\n\n@docs through, withDirection\n\n\n# Properties\n\n@docs originPoint, direction\n\n\n# Transformations\n\n@docs reverse, moveTo, rotateAround, translateBy, translateIn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Axis2d","comment":" ","args":[],"type":"Geometry.Types.Axis2d"}],"values":[{"name":"direction","comment":" Get the direction of an axis.\n\n    Axis2d.direction exampleAxis\n    --> Direction2d.fromAngle (degrees 30)\n\n","type":"Axis2d.Axis2d -> Direction2d.Direction2d"},{"name":"mirrorAcross","comment":" Mirror one axis across another. The axis to mirror across is given first and\nthe axis to mirror is given second.\n\n    Axis2d.mirrorAcross Axis2d.x exampleAxis\n    --> Axis2d.through (Point2d.fromCoordinates ( 1, -3 ))\n    -->     (Direction2d.fromAngle (degrees -30))\n\n","type":"Axis2d.Axis2d -> Axis2d.Axis2d -> Axis2d.Axis2d"},{"name":"moveTo","comment":" Move an axis so that it has the given origin point but unchanged direction.\n\n    newOrigin =\n        Point2d.fromCoordinates ( 4, 5 )\n\n    Axis2d.moveTo newOrigin exampleAxis\n    --> Axis2d.through (Point2d.fromCoordinates ( 4, 5 ))\n    -->     (Direction2d.fromAngle (degrees 30))\n\n","type":"Point2d.Point2d -> Axis2d.Axis2d -> Axis2d.Axis2d"},{"name":"originPoint","comment":" Get the origin point of an axis.\n\n    Axis2d.originPoint exampleAxis\n    --> Point2d.fromCoordinates ( 1, 3 )\n\n","type":"Axis2d.Axis2d -> Point2d.Point2d"},{"name":"placeIn","comment":" Take an axis defined in local coordinates relative to a given reference\nframe, and return that axis expressed in global coordinates.\n\n    frame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))\n\n    Axis2d.placeIn frame exampleAxis\n    --> Axis2d.through (Point2d.fromCoordinates ( 3, 6 ))\n    -->     (Direction2d.fromAngle (degrees 30))\n\n","type":"Geometry.Types.Frame2d -> Axis2d.Axis2d -> Axis2d.Axis2d"},{"name":"relativeTo","comment":" Take an axis defined in global coordinates, and return it expressed in local\ncoordinates relative to a given reference frame.\n\n    frame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))\n\n    Axis2d.relativeTo frame exampleAxis\n    --> Axis2d.through (Point2d.fromCoordinates ( -1, 0 ))\n    -->     (Direction2d.fromAngle (degrees 30))\n\n","type":"Geometry.Types.Frame2d -> Axis2d.Axis2d -> Axis2d.Axis2d"},{"name":"reverse","comment":" Reverse the direction of an axis while keeping the same origin point.\n\n    Axis2d.reverse exampleAxis\n    --> Axis2d.through (Point2d.fromCoordinates ( 1, 3 ))\n    -->     (Direction2d.fromAngle (degrees -150))\n\n","type":"Axis2d.Axis2d -> Axis2d.Axis2d"},{"name":"rotateAround","comment":" Rotate an axis around a given center point by a given angle. Rotates the\naxis' origin point around the given point by the given angle and the axis'\ndirection by the given angle.\n\n    exampleAxis\n        |> Axis2d.rotateAround Point2d.origin (degrees 90)\n    --> Axis2d.through (Point2d.fromCoordinates ( -3, 1 ))\n    -->     (Direction2d.fromAngle (degrees 120))\n\n","type":"Point2d.Point2d -> Basics.Float -> Axis2d.Axis2d -> Axis2d.Axis2d"},{"name":"through","comment":" Construct an axis through the given origin point with the given direction.\n\n    exampleAxis =\n        Axis2d.through (Point2d.fromCoordinates ( 1, 3 ))\n            (Direction2d.fromAngle (degrees 30))\n\n","type":"Point2d.Point2d -> Direction2d.Direction2d -> Axis2d.Axis2d"},{"name":"translateBy","comment":" Translate an axis by a given displacement. Applies the given displacement to\nthe axis' origin point and leaves the direction unchanged.\n\n    displacement =\n        Vector2d.fromComponents ( 2, 3 )\n\n    Axis2d.translateBy displacement exampleAxis\n    --> Axis2d.through (Point2d.fromCoordinates ( 3, 6 ))\n    -->     (Direction2d.fromAngle (degrees 30))\n\n","type":"Vector2d.Vector2d -> Axis2d.Axis2d -> Axis2d.Axis2d"},{"name":"translateIn","comment":" Translate an axis in a given direction by a given distance;\n\n    Axis2d.translateIn direction distance\n\nis equivalent to\n\n    Axis2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Axis2d.Axis2d -> Axis2d.Axis2d"},{"name":"withDirection","comment":" Construct an axis with the given direction, through the given origin point.\nFlipped version of `through`. Having both versions allow you to do different\nthings with partial application:\n\n    -- A list of axes in different directions all passing\n    -- through the same origin point\n    List.map (Axis2d.through point) directions\n\n\n    -- A list of parallel axes (all having the same\n    -- direction) through different points\n    List.map (Axis2d.withDirection direction) points\n\n","type":"Direction2d.Direction2d -> Point2d.Point2d -> Axis2d.Axis2d"},{"name":"x","comment":" The global X axis.\n\n    Axis2d.x\n    --> Axis2d.through Point2d.origin Direction2d.x\n\n","type":"Axis2d.Axis2d"},{"name":"y","comment":" The global Y axis.\n\n    Axis2d.y\n    --> Axis2d.through Point2d.origin Direction2d.y\n\n","type":"Axis2d.Axis2d"}],"binops":[]},{"name":"Axis3d","comment":" An `Axis3d` represents an infinitely long straight line in 3D and is defined\nby an origin point and direction. Axes have several uses, such as:\n\n  - Rotating around the axis\n  - Projecting onto the axis\n  - Measuring distance along the axis from the origin point\n\n@docs Axis3d\n\n\n# Constants\n\n@docs x, y, z\n\n\n# Constructors\n\n@docs through, withDirection, on\n\n\n# Properties\n\n@docs originPoint, direction\n\n\n# Transformations\n\n@docs reverse, moveTo, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn, projectInto\n\n","unions":[],"aliases":[{"name":"Axis3d","comment":" ","args":[],"type":"Geometry.Types.Axis3d"}],"values":[{"name":"direction","comment":" Get the direction of an axis.\n\n    Axis3d.direction exampleAxis\n    --> Direction3d.y\n\n","type":"Axis3d.Axis3d -> Direction3d.Direction3d"},{"name":"mirrorAcross","comment":" Mirror an axis across a plane.\n\n    Axis3d.mirrorAcross Plane3d.xy exampleAxis\n    --> Axis3d.withDirection Direction3d.y\n    -->     (Point3d.fromCoordinates ( 1, 2, -3 ))\n\n","type":"Geometry.Types.Plane3d -> Axis3d.Axis3d -> Axis3d.Axis3d"},{"name":"moveTo","comment":" Move an axis so that it has the given origin point but unchanged direction.\n\n    newOrigin =\n        Point3d.fromCoordinates ( 3, 4, 5 )\n\n    Axis3d.moveTo newOrigin exampleAxis\n    --> Axis3d.withDirection Direction3d.y\n    -->     (Point3d.fromCoordinates ( 3, 4, 5 ))\n\n","type":"Point3d.Point3d -> Axis3d.Axis3d -> Axis3d.Axis3d"},{"name":"on","comment":" Construct a 3D axis lying _on_ a sketch plane by providing a 2D axis\nspecified in XY coordinates _within_ the sketch plane.\n\n    axis2d =\n        Axis2d.through (Point2d.fromCoordinates ( 1, 3 ))\n            (Direction2d.fromAngle (degrees 30))\n\n    Axis3d.on SketchPlane3d.xy axis2d\n    --> Axis3d.through\n    -->     (Point3d.fromCoordinates ( 1, 3, 0 ))\n    -->     (Direction3d.fromAzimuthAndElevation\n    -->         (degrees 30)\n    -->         (degrees 0)\n    -->     )\n\n    Axis3d.on SketchPlane3d.zx axis2d\n    --> Axis3d.through\n    -->     (Point3d.fromCoordinates ( 3, 0, 1 ))\n    -->     (Direction3d.fromAzimuthAndElevation\n    -->         (degrees 0)\n    -->         (degrees 60)\n    -->     )\n\n","type":"Geometry.Types.SketchPlane3d -> Axis2d.Axis2d -> Axis3d.Axis3d"},{"name":"originPoint","comment":" Get the origin point of an axis.\n\n    Axis3d.originPoint exampleAxis\n    --> Point3d.fromCoordinates ( 1, 2, 3 )\n\n","type":"Axis3d.Axis3d -> Point3d.Point3d"},{"name":"placeIn","comment":" Take an axis defined in local coordinates relative to a given reference\nframe, and return that axis expressed in global coordinates.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 3, 3, 3 ))\n\n    Axis3d.placeIn localFrame exampleAxis\n    --> Axis3d.withDirection Direction3d.y\n    -->     (Point3d.fromCoordinates ( 4, 5, 6 ))\n\n","type":"Geometry.Types.Frame3d -> Axis3d.Axis3d -> Axis3d.Axis3d"},{"name":"projectInto","comment":" Project an axis into a given sketch plane. Conceptually, this finds the\n[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof the axis onto the plane and then expresses the projected axis in 2D sketch\ncoordinates.\n\nThis is only possible if the axis is not perpendicular to the sketch\nplane; if it is perpendicular, `Nothing` is returned.\n\n    Axis3d.projectInto SketchPlane3d.xy exampleAxis\n    --> Just\n    -->     (Axis2d.withDirection Direction2d.y\n    -->         (Point2d.fromCoordinates ( 1, 2 ))\n    -->     )\n\n    -- The global Y direction is the X direction of the\n    -- YZ plane:\n    Axis3d.projectInto SketchPlane3d.yz exampleAxis\n    --> Just\n    -->     (Axis2d.withDirection Direction2d.x\n    -->         (Point2d.fromCoordinates ( 2, 3 ))\n    -->     )\n\n    Axis3d.projectInto SketchPlane3d.xz exampleAxis\n    --> Nothing\n\n","type":"Geometry.Types.SketchPlane3d -> Axis3d.Axis3d -> Maybe.Maybe Axis2d.Axis2d"},{"name":"projectOnto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof an axis onto a plane. If the given axis is exactly perpendicular to the given\nplane, returns `Nothing`.\n\n    Axis3d.projectOnto Plane3d.xy exampleAxis\n    --> Just\n    -->     (Axis3d.withDirection Direction3d.y\n    -->         (Point3d.fromCoordinates ( 1, 2, 0 ))\n    -->     )\n\n    Axis3d.projectOnto Plane3d.xy Axis3d.z\n    --> Nothing\n\n","type":"Geometry.Types.Plane3d -> Axis3d.Axis3d -> Maybe.Maybe Axis3d.Axis3d"},{"name":"relativeTo","comment":" Take an axis defined in global coordinates, and return it expressed in local\ncoordinates relative to a given reference frame.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 3, 3, 3 ))\n\n    Axis3d.relativeTo localFrame exampleAxis\n    --> Axis3d.withDirection Direction3d.y\n    -->     (Point3d.fromCoordinates ( -2, -1, 0 ))\n\n","type":"Geometry.Types.Frame3d -> Axis3d.Axis3d -> Axis3d.Axis3d"},{"name":"reverse","comment":" Reverse the direction of an axis while keeping the same origin point.\n\n    Axis3d.reverse exampleAxis\n    --> Axis3d.withDirection Direction3d.negativeY\n    -->     (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n","type":"Axis3d.Axis3d -> Axis3d.Axis3d"},{"name":"rotateAround","comment":" Rotate an axis around another axis by a given angle. The axis to rotate\naround is given first and the axis to rotate is given last.\n\n    Axis3d.rotateAround Axis3d.z (degrees 90) exampleAxis\n    --> Axis3d.withDirection Direction3d.negativeX\n    -->     (Point3d.fromCoordinates ( -2, 1, 3 ))\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Axis3d.Axis3d -> Axis3d.Axis3d"},{"name":"through","comment":" Construct an axis through the given point, with the given direction.\n\n    exampleAxis =\n        Axis3d.through\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n            Direction3d.y\n\n","type":"Point3d.Point3d -> Direction3d.Direction3d -> Axis3d.Axis3d"},{"name":"translateBy","comment":" Translate an axis by a given displacement. Applies the given displacement to\nthe axis' origin point and leaves the direction unchanged.\n\n    displacement =\n        Vector3d.fromComponents ( 3, 3, 3 )\n\n    Axis3d.translateBy displacement exampleAxis\n    --> Axis3d.withDirection Direction3d.y\n    -->     (Point3d.fromCoordinates ( 4, 5, 6 ))\n\n","type":"Vector3d.Vector3d -> Axis3d.Axis3d -> Axis3d.Axis3d"},{"name":"translateIn","comment":" Translate an axis in a given direction by a given distance;\n\n    Axis3d.translateIn direction distance\n\nis equivalent to\n\n    Axis3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> Axis3d.Axis3d -> Axis3d.Axis3d"},{"name":"withDirection","comment":" Construct an axis with the given directoin, through the given point. Flipped\nversion of `through`. Having both versions allow you to do different\nthings with partial application:\n\n    -- A list of axes in different directions all passing\n    -- through the same origin point\n    List.map (Axis3d.through point) directions\n\n\n    -- A list of parallel axes (all having the same\n    -- direction) through different points\n    List.map (Axis3d.withDirection direction) points\n\n","type":"Direction3d.Direction3d -> Point3d.Point3d -> Axis3d.Axis3d"},{"name":"x","comment":" The global X axis.\n\n    Axis3d.x\n    --> Axis3d.through Point3d.origin Direction3d.x\n\n","type":"Axis3d.Axis3d"},{"name":"y","comment":" The global Y axis.\n\n    Axis3d.y\n    --> Axis3d.through Point3d.origin Direction3d.y\n\n","type":"Axis3d.Axis3d"},{"name":"z","comment":" The global Z axis.\n\n    Axis3d.z\n    --> Axis3d.through Point3d.origin Direction3d.z\n\n","type":"Axis3d.Axis3d"}],"binops":[]},{"name":"BoundingBox2d","comment":" A `BoundingBox2d` is a rectangular box in 2D defined by its minimum and\nmaximum X and Y values. It is possible to generate bounding boxes for most\ngeometric objects; for example, [`Triangle2d.boundingBox`](Triangle2d#boundingBox)\ntakes a `Triangle2d` and returns a `BoundingBox2d` that contains that triangle.\nThere are several use cases where it is more efficient to deal with the bounding\nbox of an object than the object itself, such as:\n\n  - Intersection checking: If (for example) the bounding boxes of a line segment\n    and a triangle do not overlap, then the line segment and triangle cannot\n    possibly intersect each other. Expensive intersection checking therefore\n    only has to be performed for line segments and triangles whose bounding\n    boxes _do_ overlap.\n  - 2D rendering: When rendering a 2D scene, any object whose bounding box does\n    not overlap the viewing area must itself be completely outside the viewing\n    area, and therefore does not have to be drawn. This provides a simple form\n    of culling.\n\n@docs BoundingBox2d\n\n\n# Constructors\n\n@docs fromExtrema, singleton, from, hull, intersection, aggregate, containingPoints\n\n\n# Properties\n\n@docs extrema, minX, maxX, minY, maxY, dimensions, midX, midY, centerPoint, centroid\n\n\n# Queries\n\n@docs contains, isContainedIn, intersects, overlappingBy, separatedBy\n\n\n# Transformations\n\n@docs scaleAbout, translateBy, translateIn\n\n","unions":[],"aliases":[{"name":"BoundingBox2d","comment":" ","args":[],"type":"Geometry.Types.BoundingBox2d"}],"values":[{"name":"aggregate","comment":" Construct a bounding box containing all bounding boxes in the given list. If\nthe list is empty, returns `Nothing`.\n\n    singletonBox =\n        BoundingBox2d.singleton\n            (Point2d.fromCoordinates ( 1, 3 ))\n\n    BoundingBox2d.aggregate [ exampleBox, singletonBox ]\n    --> Just\n    -->     (BoundingBox2d.fromExtrema\n    -->         { minX = 1,\n    -->         , maxX = 8\n    -->         , minY = 2\n    -->         , maxY = 6\n    -->         }\n    -->     )\n\n    BoundingBox2d.aggregate [ exampleBox ]\n    --> Just exampleBox\n\n    BoundingBox2d.aggregate []\n    --> Nothing\n\nIf you have exactly two bounding boxes, you can use [`BoundingBox2d.hull`](#hull)\ninstead (which returns a `BoundingBox2d` instead of a `Maybe BoundingBox2d`).\n\n","type":"List.List BoundingBox2d.BoundingBox2d -> Maybe.Maybe BoundingBox2d.BoundingBox2d"},{"name":"centerPoint","comment":" Get the point at the center of a bounding box.\n\n    BoundingBox2d.centerPoint exampleBox\n    --> Point2d.fromCoordinates ( 5.5, 4 )\n\n","type":"BoundingBox2d.BoundingBox2d -> Point2d.Point2d"},{"name":"centroid","comment":" **DEPRECATED**: Alias for `centerPoint`, will be removed in the next major\nrelease. Use `centerPoint` instead.\n","type":"BoundingBox2d.BoundingBox2d -> Point2d.Point2d"},{"name":"containingPoints","comment":" Construct a bounding box containing all points in the given list. If the\nlist is empty, returns `Nothing`.\n\n    BoundingBox2d.containingPoints\n        [ Point2d.fromCoordinates ( 2, 3 )\n        , Point2d.fromCoordinates ( -1, 5 )\n        , Point2d.fromCoordinates ( 6, 4 )\n        ]\n    --> Just <|\n    -->     BoundingBox2d.fromExtrema\n    -->         { minX = -1\n    -->         , maxX = 6\n    -->         , minY = 3\n    -->         , maxY = 5\n    -->         }\n\n    BoundingBox2d.containingPoints []\n    --> Nothing\n\n","type":"List.List Point2d.Point2d -> Maybe.Maybe BoundingBox2d.BoundingBox2d"},{"name":"contains","comment":" Check if a bounding box contains a particular point.\n\n    point =\n        Point2d.fromCoordinates ( 4, 3 )\n\n    BoundingBox2d.contains point exampleBox\n    --> True\n\n    BoundingBox2d.contains Point2d.origin exampleBox\n    --> False\n\n","type":"Point2d.Point2d -> BoundingBox2d.BoundingBox2d -> Basics.Bool"},{"name":"dimensions","comment":" Get the X and Y dimensions (width and height) of a bounding box.\n\n\n    ( width, height ) =\n        BoundingBox2d.dimensions exampleBox\n\n\n    --> width = 5\n    --> height = 4\n\n","type":"BoundingBox2d.BoundingBox2d -> ( Basics.Float, Basics.Float )"},{"name":"extrema","comment":" Get the minimum and maximum X and Y values of a bounding box in a single\nrecord.\n\n    BoundingBox2d.extrema exampleBox\n    --> { minX = 3\n    --> , maxX = 8\n    --> , minY = 2\n    --> , maxY = 6\n    --> }\n\nCan be useful when combined with record destructuring, for example\n\n\n    { minX, maxX, minY, maxY } =\n        BoundingBox2d.extrema exampleBox\n\n\n    --> minX = 3\n    --> maxX = 8\n    --> minY = 2\n    --> maxY = 6\n\n","type":"BoundingBox2d.BoundingBox2d -> { minX : Basics.Float, maxX : Basics.Float, minY : Basics.Float, maxY : Basics.Float }"},{"name":"from","comment":" Construct a bounding box with the two given points as two of its corners.\nThe points can be given in any order and don't have to represent the 'primary'\ndiagonal of the bounding box.\n\n    firstPoint =\n        Point2d.fromCoordinates ( 2, 3 )\n\n    secondPoint =\n        Point2d.fromCoordinates ( -1, 5 )\n\n    BoundingBox2d.from firstPoint secondPoint\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = -1\n    -->     , maxX = 2\n    -->     , minY = 3\n    -->     , maxY = 5\n    -->     }\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> BoundingBox2d.BoundingBox2d"},{"name":"fromExtrema","comment":" Construct a bounding box from its minimum and maximum X and Y values:\n\n    exampleBox =\n        BoundingBox2d.fromExtrema\n            { minX = 3\n            , maxX = 8\n            , minY = 2\n            , maxY = 6\n            }\n\nIf the minimum and maximum values are provided in the wrong order (for example\nif <code>minX&nbsp;>&nbsp;maxX</code>), then they will be swapped so that the\nresulting bounding box is valid.\n\n","type":"{ minX : Basics.Float, maxX : Basics.Float, minY : Basics.Float, maxY : Basics.Float } -> BoundingBox2d.BoundingBox2d"},{"name":"hull","comment":" Build a bounding box that contains both given bounding boxes.\n\n    firstBox =\n        BoundingBox2d.fromExtrema\n            { minX = 1\n            , maxX = 4\n            , minY = 2\n            , maxY = 3\n            }\n\n    secondBox =\n        BoundingBox2d.fromExtrema\n            { minX = -2\n            , maxX = 2\n            , minY = 4\n            , maxY = 5\n            }\n\n    BoundingBox2d.hull firstBox secondBox\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = -2\n    -->     , maxX = 4\n    -->     , minY = 2\n    -->     , maxY = 5\n    -->     }\n\n","type":"BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d"},{"name":"intersection","comment":" Attempt to build a bounding box that contains all points common to both\ngiven bounding boxes. If the given boxes do not intersect, returns `Nothing`.\n\n    firstBox =\n        BoundingBox2d.fromExtrema\n            { minX = 1\n            , maxX = 4\n            , minY = 2\n            , maxY = 3\n            }\n\n    secondBox =\n        BoundingBox2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 4\n            }\n\n    thirdBox =\n        BoundingBox2d.fromExtrema\n            { minX = 1\n            , maxX = 4\n            , minY = 4\n            , maxY = 5\n            }\n\n    BoundingBox2d.intersection firstBox secondBox\n    --> Just\n    -->     (BoundingBox2d.fromExtrema\n    -->         { minX = 2\n    -->         , maxX = 4\n    -->         , minY = 2\n    -->         , maxY = 3\n    -->         }\n    -->     )\n\n    BoundingBox2d.intersection firstBox thirdBox\n    --> Nothing\n\nIf two boxes just touch along an edge or at a corner, they are still considered\nto have an intersection, even though that intersection will have zero area (at\nleast one of its dimensions will be zero):\n\n    firstBox =\n        BoundingBox2d.fromExtrema\n            { minX = 0\n            , maxX = 1\n            , minY = 0\n            , maxY = 2\n            }\n\n    secondBox =\n        BoundingBox2d.fromExtrema\n            { minX = 1\n            , maxX = 2\n            , minY = 1\n            , maxY = 3\n            }\n\n    BoundingBox2d.intersection firstBox secondBox\n    --> Just\n    -->     (BoundingBox2d.fromExtrema\n    -->         { minX = 1\n    -->         , maxX = 1\n    -->         , minY = 1\n    -->         , maxY = 2\n    -->         }\n    -->     )\n\n","type":"BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d -> Maybe.Maybe BoundingBox2d.BoundingBox2d"},{"name":"intersects","comment":" Test if two boxes touch or overlap at all (have any points in common);\n\n    BoundingBox2d.intersects firstBox secondBox\n\nis equivalent to\n\n    BoundingBox2d.intersection firstBox secondBox\n        /= Nothing\n\nbut is more efficient.\n\n    firstBox =\n        BoundingBox2d.fromExtrema\n            { minX = 0\n            , maxX = 3\n            , minY = 0\n            , maxY = 2\n            }\n\n    secondBox =\n        BoundingBox2d.fromExtrema\n            { minX = 0\n            , maxX = 3\n            , minY = 1\n            , maxY = 4\n            }\n\n    thirdBox =\n        BoundingBox2d.fromExtrema\n            { minX = 0\n            , maxX = 3\n            , minY = 4\n            , maxY = 5\n            }\n\n    BoundingBox2d.intersects firstBox secondBox\n    --> True\n\n    BoundingBox2d.intersects firstBox thirdBox\n    --> False\n\n","type":"BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d -> Basics.Bool"},{"name":"isContainedIn","comment":" Test if the second given bounding box is fully contained within the first\n(is a subset of it).\n\n    outerBox =\n        BoundingBox2d.fromExtrema\n            { minX = 0\n            , maxX = 10\n            , minY = 0\n            , maxY = 10\n            }\n\n    innerBox =\n        BoundingBox2d.fromExtrema\n            { minX = 1\n            , maxX = 5\n            , minY = 3\n            , maxY = 9\n            }\n\n    overlappingBox =\n        BoundingBox2d.fromExtrema\n            { minX = 1\n            , maxX = 5\n            , minY = 3\n            , maxY = 12\n            }\n\n    BoundingBox2d.isContainedIn outerBox innerBox\n    --> True\n\n    BoundingBox2d.isContainedIn outerBox overlappingBox\n    --> False\n\n","type":"BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d -> Basics.Bool"},{"name":"maxX","comment":" Get the maximum X value of a bounding box.\n\n    BoundingBox2d.maxX exampleBox\n    --> 8\n\n","type":"BoundingBox2d.BoundingBox2d -> Basics.Float"},{"name":"maxY","comment":" Get the maximum Y value of a bounding box.\n\n    BoundingBox2d.maxY exampleBox\n    --> 6\n\n","type":"BoundingBox2d.BoundingBox2d -> Basics.Float"},{"name":"midX","comment":" Get the median X value of a bounding box.\n\n    BoundingBox2d.midX exampleBox\n    --> 5.5\n\n","type":"BoundingBox2d.BoundingBox2d -> Basics.Float"},{"name":"midY","comment":" Get the median Y value of a bounding box.\n\n    BoundingBox2d.midY exampleBox\n    --> 4\n\n","type":"BoundingBox2d.BoundingBox2d -> Basics.Float"},{"name":"minX","comment":" Get the minimum X value of a bounding box.\n\n    BoundingBox2d.minX exampleBox\n    --> 3\n\n","type":"BoundingBox2d.BoundingBox2d -> Basics.Float"},{"name":"minY","comment":" Get the minimum Y value of a bounding box.\n\n    BoundingBox2d.minY exampleBox\n    --> 2\n\n","type":"BoundingBox2d.BoundingBox2d -> Basics.Float"},{"name":"overlappingBy","comment":" Check if one box overlaps another by less than, greater than or equal to a\ngiven amount. For example, you could implement a tolerant collision check (one\nthat only returns true if the boxes overlap by at least some small finite\namount, and ignores boxes that just barely touch each other) as\n\n    boxesCollide box1 box2 =\n        BoundingBox2d.overlappingBy GT 0.001 box1 box2\n\nThis can be read as \"`box1` and `box2` are overlapping by greater than 0.001\nunits\". (The [`Order`](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#Order)\ntype and its three values `LT`, `GT` and `EQ` are defined in Elm's `Basics`\nmodule so are available by default in any Elm program.)\n\nOverlap is defined as the _minimum_ distance one box would have to move so that\nit did not touch the other, and is always positive for any two overlapping\nboxes.\n\nBoxes that just touch are considered to have an overlap of zero, which is\ndistinct from 'no overlap'. Boxes that do not touch or overlap at all are\nconsidered to have an overlap which is less than zero but not comparable to any\nnegative number.\n\n\n### Less than\n\n  - `overlappingBy LT 1e-3` will return true if the two boxes overlap by less\n    than 0.001 units or if they do not overlap at all (false if they overlap by\n    more than 0.001 units).\n  - `overlappingBy LT 0` will return true only if the two boxes don't touch or\n    overlap at all.\n  - `overlappingBy LT -1e-3` will always return false! If you care about _how\n    much_ two boxes are separated by, use `separatedBy` instead.\n\n\n### Greater than\n\n  - `overlappingBy GT 1e-3` will return true if the two boxes overlap by at\n    least 0.001 units (false if they overlap by less than that or do not overlap\n    at all).\n  - `overlappingBy GT 0` will return true if the two boxes overlap by any\n    non-zero amount (false if they just touch or do not overlap at all).\n  - `overlappingBy GT -1e-3` doesn't make a lot of sense but will return true if\n    the boxes touch or overlap at all (false if they don't overlap, regardless\n    of how close they are to overlapping). In this case, though, it would make\n    more sense to just user `intersects` instead.\n\n\n### Equal to\n\nChecking whether two boxes overlap by exactly a given amount is pretty weird and\nvulnerable to floating-point roundoff, but is defined as follows:\n\n  - `overlappingBy EQ 1e-3` will return true if the two boxes overlap by exactly\n    0.001 units.\n  - `overlappingBy EQ 0` will return true if and only if the boxes just touch\n    each other.\n  - `overlappingBy EQ -1e-3` will always return false.\n\n","type":"Basics.Order -> Basics.Float -> BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d -> Basics.Bool"},{"name":"scaleAbout","comment":" Scale a bounding box about a given point by a given scale.\n\n    point =\n        Point2d.fromCoordinates ( 4, 4 )\n\n    BoundingBox2d.scaleAbout point 2 exampleBox\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = 2\n    -->     , maxX = 12\n    -->     , minY = 0\n    -->     , maxY = 8\n    -->     }\n\n","type":"Point2d.Point2d -> Basics.Float -> BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d"},{"name":"separatedBy","comment":" Check if one box is separated from another by less than, greater than or\nequal to a given amount. For example, to perform clash detection between some\nobjects, you could use `separatedBy` on those objects' bounding boxes as a quick\ncheck to see if the objects had a gap of at least 1 cm between them:\n\n    safelySeparated box1 box2 =\n        BoundingBox2d.separatedBy GT 0.01 box1 box2\n\nThis can be read as \"`box1` and `box2` are separated by greater than 0.01\nunits\". (The [`Order`](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#Order)\ntype and its three values `LT`, `GT` and `EQ` are defined in Elm's `Basics`\nmodule so are available by default in any Elm program.)\n\nSeparation is defined as the _minimum_ distance one box would have to move\nso that it touched the other, and is always positive for any two boxes that do\nnot touch.\n\nBoxes that just touch are considered to have a separation of zero, which is\ndistinct from 'no separation'. 'No separation' (overlap) is considered to be\nless than zero but not comparable to any negative number.\n\n\n### Less than\n\n  - `separatedBy LT 1e-3` will return true if the two boxes are separated by\n    less than 0.001 units or if they touch or overlap (false if they are\n    separated by at least 0.001 units).\n  - `separatedBy LT 0` will return true only if the boxes overlap by some\n    non-zero amount.\n  - `separatedBy LT -1e-3` will always return false! If you care about _how\n    much_ two boxes overlap by, use `overlappingBy` instead.\n\n\n### Greater than\n\n  - `separatedBy GT 1e-3` will return true if the two boxes are separated by at\n    least 0.001 units (false if they are separated by less than that or if they\n    touch or overlap).\n  - `separatedBy GT 0` will return true if the two boxes are separated by any\n    non-zero amount (false if they touch or overlap).\n  - `separatedBy GT -1e-3` doesn't make a lot of sense but will return true if\n    the boxes just touch or are separated by any amount (false if they overlap\n    by any non-zero amount).\n\n\n### Equal to\n\nChecking whether two boxes are separated by exactly a given amount is pretty\nweird and vulnerable to floating-point roundoff, but is defined as follows:\n\n  - `separatedBy EQ 1e-3` will return true if the two boxes are separated by\n    exactly 0.001 units.\n  - `separatedBy EQ 0` will return true if and only if the boxes just touch each\n    other.\n  - `separatedBy EQ -3` will always return false.\n\n","type":"Basics.Order -> Basics.Float -> BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d -> Basics.Bool"},{"name":"singleton","comment":" Construct a zero-width bounding box containing a single point.\n\n    point =\n        Point2d.fromCoordinates ( 2, 3 )\n\n    BoundingBox2d.singleton point\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = 2\n    -->     , maxX = 2\n    -->     , minY = 3\n    -->     , maxY = 3\n    -->     }\n\n","type":"Point2d.Point2d -> BoundingBox2d.BoundingBox2d"},{"name":"translateBy","comment":" Translate a bounding box by a given displacement.\n\n    displacement =\n        Vector2d.fromComponents ( 2, -3 )\n\n    BoundingBox2d.translateBy displacement exampleBox\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = 5\n    -->     , maxX = 10\n    -->     , minY = -1\n    -->     , maxY = 3\n    -->     }\n\n","type":"Vector2d.Vector2d -> BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d"},{"name":"translateIn","comment":" Translate a bounding box in a given direction by a given distance;\n\n    BoundingBox2d.translateIn direction distance\n\nis equivalent to\n\n    BoundingBox2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> BoundingBox2d.BoundingBox2d -> BoundingBox2d.BoundingBox2d"}],"binops":[]},{"name":"BoundingBox3d","comment":" A `BoundingBox3d` is a rectangular box in 3D defined by its minimum and\nmaximum X, Y and Z values. It is possible to generate bounding boxes for most\ngeometric objects; for example, [`Triangle3d.boundingBox`](Triangle3d#boundingBox)\ntakes a `Triangle3d` and returns a `BoundingBox3d` that contains that triangle.\nThere are several use cases where it is more efficient to deal with the bounding\nbox of an object than the object itself, such as:\n\n  - Intersection checking: If (for example) the bounding boxes of a line segment\n    and a triangle do not overlap, then the line segment and triangle cannot\n    possibly intersect each other. Expensive intersection checking therefore\n    only has to be performed for line segments and triangles whose bounding\n    boxes _do_ overlap.\n  - 3D rendering: When rendering a 3D scene, any object whose bounding box is\n    not visible must itself be not visible, and therefore does not have to be\n    drawn. This provides a simple form of culling.\n\n@docs BoundingBox3d\n\n\n# Constructors\n\n@docs fromExtrema, singleton, from, hull, intersection, aggregate, containingPoints\n\n\n# Properties\n\n@docs extrema, minX, maxX, minY, maxY, minZ, maxZ, dimensions, midX, midY, midZ, centerPoint, centroid\n\n\n# Queries\n\n@docs contains, isContainedIn, intersects, overlappingBy, separatedBy\n\n\n# Transformations\n\n@docs scaleAbout, translateBy, translateIn\n\n","unions":[],"aliases":[{"name":"BoundingBox3d","comment":" ","args":[],"type":"Geometry.Types.BoundingBox3d"}],"values":[{"name":"aggregate","comment":" Construct a bounding box containing all bounding boxes in the given list. If\nthe list is empty, returns `Nothing`.\n\n    singletonBox =\n        BoundingBox3d.singleton\n            (Point3d.fromCoordinates ( 2, 1, 0 ))\n\n    BoundingBox3d.aggregate [ exampleBox, singletonBox ]\n    --> Just\n    -->     (BoundingBox3d.fromExtrema\n    -->         { minX = -2,\n    -->         , maxX = 2\n    -->         , minY = 1\n    -->         , maxY = 5\n    -->         , minZ = 0\n    -->         , maxZ = 4\n    -->         }\n    -->     )\n\n    BoundingBox3d.aggregate [ exampleBox ]\n    --> Just exampleBox\n\n    BoundingBox3d.aggregate []\n    --> Nothing\n\nIf you have exactly two bounding boxes, you can use [`BoundingBox3d.hull`](#hull)\ninstead (which returns a `BoundingBox3d` instead of a `Maybe BoundingBox3d`).\n\n","type":"List.List BoundingBox3d.BoundingBox3d -> Maybe.Maybe BoundingBox3d.BoundingBox3d"},{"name":"centerPoint","comment":" Get the point at the center of a bounding box.\n\n    BoundingBox3d.centerPoint exampleBox\n    --> Point3d.fromCoordinates ( 0, 3.5, 3.5 )\n\n","type":"BoundingBox3d.BoundingBox3d -> Point3d.Point3d"},{"name":"centroid","comment":" **DEPRECATED**: Alias for `centerPoint`, will be removed in the next major\nrelease. Use `centerPoint` instead.\n","type":"BoundingBox3d.BoundingBox3d -> Point3d.Point3d"},{"name":"containingPoints","comment":" Construct a bounding box containing all points in the given list. If the\nlist is empty, returns `Nothing`.\n\n    BoundingBox3d.containingPoints\n        [ Point3d.fromCoordinates ( 2, 1, 3 )\n        , Point3d.fromCoordinates ( -1, 5, -2 )\n        , Point3d.fromCoordinates ( 6, 4, 2 )\n        ]\n    --> Just <|\n    -->     BoundingBox3d.fromExtrema\n    -->         { minX = -1\n    -->         , maxX = 6\n    -->         , minY = 1\n    -->         , maxY = 5\n    -->         , minZ = -2\n    -->         , maxZ = 3\n    -->         }\n\n    BoundingBox3d.containingPoints []\n    --> Nothing\n\n","type":"List.List Point3d.Point3d -> Maybe.Maybe BoundingBox3d.BoundingBox3d"},{"name":"contains","comment":" Check if a bounding box contains a particular point.\n\n    firstPoint =\n        Point3d.fromCoordinates ( 1, 4, 3 )\n\n    secondPoint =\n        Point3d.fromCoordinates ( 3, 4, 5 )\n\n    BoundingBox3d.contains firstPoint exampleBox\n    --> True\n\n    BoundingBox3d.contains secondPoint exampleBox\n    --> False\n\n","type":"Point3d.Point3d -> BoundingBox3d.BoundingBox3d -> Basics.Bool"},{"name":"dimensions","comment":" Get the X, Y and Z dimensions (widths) of a bounding box.\n\n    BoundingBox3d.dimensions exampleBox\n    --> ( 4, 3, 1 )\n\n","type":"BoundingBox3d.BoundingBox3d -> ( Basics.Float, Basics.Float, Basics.Float )"},{"name":"extrema","comment":" Get the minimum and maximum X, Y and Z values of a bounding box in a single\nrecord.\n\n    BoundingBox3d.extrema exampleBox\n    --> { minX = -2\n    --> , maxX = 2\n    --> , minY = 2\n    --> , maxY = 5\n    --> , minZ = 3\n    --> , maxZ = 4\n    --> }\n\nCan be useful when combined with record destructuring, for example\n\n\n    { minX, maxX, minY, maxY, minZ, maxZ } =\n        BoundingBox3d.extrema exampleBox\n\n\n    --> minX = -2\n    --> maxX = 2\n    --> minY = 2\n    --> maxY = 5\n    --> minZ = 3\n    --> maxZ = 4\n\n","type":"BoundingBox3d.BoundingBox3d -> { minX : Basics.Float, maxX : Basics.Float, minY : Basics.Float, maxY : Basics.Float, minZ : Basics.Float, maxZ : Basics.Float }"},{"name":"from","comment":" Construct a bounding box with the two given points as two of its corners.\nThe points can be given in any order and don't have to represent the 'primary'\ndiagonal of the bounding box.\n\n    firstPoint =\n        Point3d.fromCoordinates ( 2, 1, 3 )\n\n    secondPoint =\n        Point3d.fromCoordinates ( -1, 5, -2 )\n\n    BoundingBox3d.from firstPoint secondPoint\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = -1\n    -->     , maxX = 2\n    -->     , minY = 1\n    -->     , maxY = 5\n    -->     , minZ = -2\n    -->     , maxZ = 3\n    -->     }\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> BoundingBox3d.BoundingBox3d"},{"name":"fromExtrema","comment":" Construct a bounding box from its minimum and maximum X, Y and Z values:\n\n    exampleBox =\n        BoundingBox3d.fromExtrema\n            { minX = -2\n            , maxX = 2\n            , minY = 2\n            , maxY = 5\n            , minZ = 3\n            , maxZ = 4\n            }\n\nIf the minimum and maximum values are provided in the wrong order (for example\nif <code>minX&nbsp;>&nbsp;maxX</code>), then they will be swapped so that the\nresulting bounding box is valid.\n\n","type":"{ minX : Basics.Float, maxX : Basics.Float, minY : Basics.Float, maxY : Basics.Float, minZ : Basics.Float, maxZ : Basics.Float } -> BoundingBox3d.BoundingBox3d"},{"name":"hull","comment":" Build a bounding box that contains both given bounding boxes.\n\n    firstBox =\n        BoundingBox3d.fromExtrema\n            { minX = 1\n            , maxX = 4\n            , minY = 2\n            , maxY = 3\n            , minZ = 0\n            , maxZ = 5\n            }\n\n    secondBox =\n        BoundingBox3d.fromExtrema\n            { minX = -2\n            , maxX = 2\n            , minY = 4\n            , maxY = 5\n            , minZ = -1\n            , maxZ = 0\n            }\n\n    BoundingBox3d.hull firstBox secondBox\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = -2\n    -->     , maxX = 4\n    -->     , minY = 2\n    -->     , maxY = 5\n    -->     , minZ = -1\n    -->     , maxZ = 5\n    -->     }\n\n","type":"BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d"},{"name":"intersection","comment":" Attempt to build a bounding box that contains all points common to both\ngiven bounding boxes. If the given boxes do not overlap, returns `Nothing`.\n\n    firstBox =\n        BoundingBox3d.fromExtrema\n            { minX = 1\n            , maxX = 4\n            , minY = 2\n            , maxY = 3\n            , minZ = 5\n            , maxZ = 8\n            }\n\n    secondBox =\n        BoundingBox3d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 4\n            , minZ = 6\n            , maxZ = 7\n            }\n\n    thirdBox =\n        BoundingBox3d.fromExtrema\n            { minX = 1\n            , maxX = 4\n            , minY = 4\n            , maxY = 5\n            , minZ = 5\n            , maxZ = 8\n            }\n\n    BoundingBox3d.intersection firstBox secondBox\n    --> Just\n    -->     (BoundingBox3d.fromExtrema\n    -->         { minX = 2\n    -->         , maxX = 4\n    -->         , minY = 2\n    -->         , maxY = 3\n    -->         , minZ = 6\n    -->         , maxZ = 7\n    -->         }\n    -->     )\n\n    BoundingBox3d.intersection firstBox thirdBox\n    --> Nothing\n\nIf two boxes just touch along an edge or at a corner, they are still considered\nto have an intersection, even though that intersection will have zero area (at\nleast one of its dimensions will be zero):\n\n    firstBox =\n        BoundingBox3d.fromExtrema\n            { minX = 0\n            , maxX = 1\n            , minY = 0\n            , maxY = 2\n            , minZ = 0\n            , maxZ = 3\n            }\n\n    secondBox =\n        BoundingBox3d.fromExtrema\n            { minX = 1\n            , maxX = 2\n            , minY = 1\n            , maxY = 3\n            , minZ = 1\n            , maxZ = 4\n            }\n\n    BoundingBox3d.intersection firstBox secondBox\n    --> Just\n    -->     (BoundingBox3d.fromExtrema\n    -->         { minX = 1\n    -->         , maxX = 1\n    -->         , minY = 1\n    -->         , maxY = 2\n    -->         , minZ = 1\n    -->         , maxZ = 3\n    -->         }\n    -->     )\n\n","type":"BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d -> Maybe.Maybe BoundingBox3d.BoundingBox3d"},{"name":"intersects","comment":" Test if two boxes touch or overlap at all (have any points in common);\n\n    BoundingBox3d.intersects firstBox secondBox\n\nis equivalent to\n\n    BoundingBox3d.intersection firstBox secondBox\n        /= Nothing\n\nbut is more efficient.\n\n    firstBox =\n        BoundingBox3d.fromExtrema\n            { minX = 0\n            , maxX = 3\n            , minY = 0\n            , maxY = 2\n            , minZ = 0\n            , maxZ = 1\n            }\n\n    secondBox =\n        BoundingBox3d.fromExtrema\n            { minX = 0\n            , maxX = 3\n            , minY = 1\n            , maxY = 4\n            , minZ = -1\n            , maxZ = 2\n            }\n\n    thirdBox =\n        BoundingBox3d.fromExtrema\n            { minX = 0\n            , maxX = 3\n            , minY = 4\n            , maxY = 5\n            , minZ = -1\n            , maxZ = 2\n            }\n\n    BoundingBox3d.intersects firstBox secondBox\n    --> True\n\n    BoundingBox3d.intersects firstBox thirdBox\n    --> False\n\n","type":"BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d -> Basics.Bool"},{"name":"isContainedIn","comment":" Test if the second given bounding box is fully contained within the first\n(is a subset of it).\n\n    outerBox =\n        BoundingBox3d.fromExtrema\n            { minX = 0\n            , maxX = 10\n            , minY = 0\n            , maxY = 10\n            , minZ = 0\n            , maxZ = 10\n            }\n\n    innerBox =\n        BoundingBox3d.fromExtrema\n            { minX = 1\n            , maxX = 5\n            , minY = 3\n            , maxY = 9\n            , minZ = 7\n            , maxZ = 8\n            }\n\n    overlappingBox =\n        BoundingBox3d.fromExtrema\n            { minX = 1\n            , maxX = 5\n            , minY = 3\n            , maxY = 12\n            , minZ = 7\n            , maxZ = 8\n            }\n\n    BoundingBox3d.isContainedIn outerBox innerBox\n    --> True\n\n    BoundingBox3d.isContainedIn outerBox overlappingBox\n    --> False\n\n","type":"BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d -> Basics.Bool"},{"name":"maxX","comment":" Get the maximum X value of a bounding box.\n\n    BoundingBox3d.maxX exampleBox\n    --> 2\n\n","type":"BoundingBox3d.BoundingBox3d -> Basics.Float"},{"name":"maxY","comment":" Get the maximum Y value of a bounding box.\n\n    BoundingBox3d.maxY exampleBox\n    --> 5\n\n","type":"BoundingBox3d.BoundingBox3d -> Basics.Float"},{"name":"maxZ","comment":" Get the maximum Z value of a bounding box.\n\n    BoundingBox3d.maxZ exampleBox\n    --> 4\n\n","type":"BoundingBox3d.BoundingBox3d -> Basics.Float"},{"name":"midX","comment":" Get the median X value of a bounding box.\n\n    BoundingBox3d.midX exampleBox\n    --> 0\n\n","type":"BoundingBox3d.BoundingBox3d -> Basics.Float"},{"name":"midY","comment":" Get the median Y value of a bounding box.\n\n    BoundingBox3d.midY exampleBox\n    --> 3.5\n\n","type":"BoundingBox3d.BoundingBox3d -> Basics.Float"},{"name":"midZ","comment":" Get the median Z value of a bounding box.\n\n    BoundingBox3d.midZ exampleBox\n    --> 3.5\n\n","type":"BoundingBox3d.BoundingBox3d -> Basics.Float"},{"name":"minX","comment":" Get the minimum X value of a bounding box.\n\n    BoundingBox3d.minX exampleBox\n    --> -2\n\n","type":"BoundingBox3d.BoundingBox3d -> Basics.Float"},{"name":"minY","comment":" Get the minimum Y value of a bounding box.\n\n    BoundingBox3d.minY exampleBox\n    --> 2\n\n","type":"BoundingBox3d.BoundingBox3d -> Basics.Float"},{"name":"minZ","comment":" Get the minimum Z value of a bounding box.\n\n    BoundingBox3d.minZ exampleBox\n    --> 3\n\n","type":"BoundingBox3d.BoundingBox3d -> Basics.Float"},{"name":"overlappingBy","comment":" Check if one box overlaps another by less than, greater than or equal to a\ngiven amount. For example, you could implement a tolerant collision check (one\nthat only returns true if the boxes overlap by at least some small finite\namount, and ignores boxes that just barely touch each other) as\n\n    boxesCollide box1 box2 =\n        BoundingBox3d.overlappingBy GT 0.001 box1 box2\n\nThis can be read as \"`box1` and `box2` are overlapping by greater than 0.001\nunits\". (The [`Order`](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#Order)\ntype and its three values `LT`, `GT` and `EQ` are defined in Elm's `Basics`\nmodule so are available by default in any Elm program.)\n\nOverlap is defined as the _minimum_ distance one box would have to move so that\nit did not touch the other, and is always positive for any two overlapping\nboxes.\n\nBoxes that just touch are considered to have an overlap of zero, which is\ndistinct from 'no overlap'. Boxes that do not touch or overlap at all are\nconsidered to have an overlap which is less than zero but not comparable to any\nnegative number.\n\n\n### Less than\n\n  - `overlappingBy LT 1e-3` will return true if the two boxes overlap by less\n    than 0.001 units or if they do not overlap at all (false if they overlap by\n    more than 0.001 units).\n  - `overlappingBy LT 0` will return true only if the two boxes don't touch or\n    overlap at all.\n  - `overlappingBy LT -1e-3` will always return false! If you care about _how\n    much_ two boxes are separated by, use `separatedBy` instead.\n\n\n### Greater than\n\n  - `overlappingBy GT 1e-3` will return true if the two boxes overlap by at\n    least 0.001 units (false if they overlap by less than that or do not overlap\n    at all).\n  - `overlappingBy GT 0` will return true if the two boxes overlap by any\n    non-zero amount (false if they just touch or do not overlap at all).\n  - `overlappingBy GT -1e-3` doesn't make a lot of sense but will return true if\n    the boxes touch or overlap at all (false if they don't overlap, regardless\n    of how close they are to overlapping). In this case, though, it would make\n    more sense to just user `intersects` instead.\n\n\n### Equal to\n\nChecking whether two boxes overlap by exactly a given amount is pretty weird and\nvulnerable to floating-point roundoff, but is defined as follows:\n\n  - `overlappingBy EQ 1e-3` will return true if the two boxes overlap by exactly\n    0.001 units.\n  - `overlappingBy EQ 0` will return true if and only if the boxes just touch\n    each other.\n  - `overlappingBy EQ -1e-3` will always return false.\n\n","type":"Basics.Order -> Basics.Float -> BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d -> Basics.Bool"},{"name":"scaleAbout","comment":" Scale a bounding box about a given point by a given scale.\n\n    point =\n        Point3d.fromCoordinates ( 2, 2, 2 )\n\n    BoundingBox3d.scaleAbout point 2 exampleBox\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = -6\n    -->     , maxX = 2\n    -->     , minY = 2\n    -->     , maxY = 8\n    -->     , minZ = 4\n    -->     , maxZ = 6\n    -->     }\n\n","type":"Point3d.Point3d -> Basics.Float -> BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d"},{"name":"separatedBy","comment":" Check if one box is separated from another by less than, greater than or\nequal to a given amount. For example, to perform clash detection between some\nobjects, you could use `separatedBy` on those objects' bounding boxes as a quick\ncheck to see if the objects had a gap of at least 1 cm between them:\n\n    safelySeparated box1 box2 =\n        BoundingBox3d.separatedBy GT 0.01 box1 box2\n\nThis can be read as \"`box1` and `box2` are separated by greater than 0.01\nunits\". (The [`Order`](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#Order)\ntype and its three values `LT`, `GT` and `EQ` are defined in Elm's `Basics`\nmodule so are available by default in any Elm program.)\n\nSeparation is defined as the _minimum_ distance one box would have to move\nso that it touched the other, and is always positive for any two boxes that do\nnot touch.\n\nBoxes that just touch are considered to have a separation of zero, which is\ndistinct from 'no separation'. 'No separation' (overlap) is considered to be\nless than zero but not comparable to any negative number.\n\n\n### Less than\n\n  - `separatedBy LT 1e-3` will return true if the two boxes are separated by\n    less than 0.001 units or if they touch or overlap (false if they are\n    separated by at least 0.001 units).\n  - `separatedBy LT 0` will return true only if the boxes overlap by some\n    non-zero amount.\n  - `separatedBy LT -1e-3` will always return false! If you care about _how\n    much_ two boxes overlap by, use `overlappingBy` instead.\n\n\n### Greater than\n\n  - `separatedBy GT 1e-3` will return true if the two boxes are separated by at\n    least 0.001 units (false if they are separated by less than that or if they\n    touch or overlap).\n  - `separatedBy GT 0` will return true if the two boxes are separated by any\n    non-zero amount (false if they touch or overlap).\n  - `separatedBy GT -1e-3` doesn't make a lot of sense but will return true if\n    the boxes just touch or are separated by any amount (false if they overlap\n    by any non-zero amount).\n\n\n### Equal to\n\nChecking whether two boxes are separated by exactly a given amount is pretty\nweird and vulnerable to floating-point roundoff, but is defined as follows:\n\n  - `separatedBy EQ 1e-3` will return true if the two boxes are separated by\n    exactly 0.001 units.\n  - `separatedBy EQ 0` will return true if and only if the boxes just touch each\n    other.\n  - `separatedBy EQ -3` will always return false.\n\n","type":"Basics.Order -> Basics.Float -> BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d -> Basics.Bool"},{"name":"singleton","comment":" Construct a zero-width bounding box containing a single point.\n\n    point =\n        Point3d.fromCoordinates ( 2, 1, 3 )\n\n    BoundingBox3d.singleton point\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = 2\n    -->     , maxX = 2\n    -->     , minY = 1\n    -->     , maxY = 1\n    -->     , minZ = 3\n    -->     , maxZ = 3\n    -->     }\n\n","type":"Point3d.Point3d -> BoundingBox3d.BoundingBox3d"},{"name":"translateBy","comment":" Translate a bounding box by a given displacement.\n\n    displacement =\n        Vector3d.fromComponents ( 2, -3, 1 )\n\n    BoundingBox3d.translateBy displacement exampleBox\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = 0\n    -->     , maxX = 4\n    -->     , minY = -1\n    -->     , maxY = 2\n    -->     , minZ = 4\n    -->     , maxZ = 5\n    -->     }\n\n","type":"Vector3d.Vector3d -> BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d"},{"name":"translateIn","comment":" Translate a bounding box in a given direction by a given distance;\n\n    BoundingBox3d.translateIn direction distance\n\nis equivalent to\n\n    BoundingBox3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> BoundingBox3d.BoundingBox3d -> BoundingBox3d.BoundingBox3d"}],"binops":[]},{"name":"Circle2d","comment":" A `Circle2d` is defined by its center point and radius. This module includes\nfunctionality for\n\n  - Constructing circles through points or with a given center/radius\n  - Scaling, rotating and translating circles\n  - Extracting properties of circles like area, center point and radius\n\n@docs Circle2d\n\n\n# Constants\n\n@docs unit\n\n\n# Constructors\n\n@docs withRadius, throughPoints, sweptAround\n\n\n# Properties\n\n@docs centerPoint, radius, diameter, area, circumference, boundingBox\n\n\n# Conversion\n\n@docs toArc\n\n\n# Queries\n\n@docs contains\n\n\n# Transformations\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Circle2d","comment":" ","args":[],"type":"Geometry.Types.Circle2d"}],"values":[{"name":"area","comment":" Get the area of a circle.\n\n    Circle2d.area exampleCircle\n    --> 28.2743\n\n","type":"Circle2d.Circle2d -> Basics.Float"},{"name":"boundingBox","comment":" Get the minimal bounding box containing a given circle.\n\n    Circle2d.boundingBox exampleCircle\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = -2\n    -->     , maxX = 4\n    -->     , minY = -1\n    -->     , maxY = 5\n    -->     }\n\n","type":"Circle2d.Circle2d -> BoundingBox2d.BoundingBox2d"},{"name":"centerPoint","comment":" Get the center point of a circle.\n\n    Circle2d.centerPoint exampleCircle\n    --> Point2d.fromCoordinates ( 1, 2 )\n\n","type":"Circle2d.Circle2d -> Point2d.Point2d"},{"name":"circumference","comment":" Get the circumference of a circle.\n\n    Circle2d.circumference exampleCircle\n    --> 18.8496\n\n","type":"Circle2d.Circle2d -> Basics.Float"},{"name":"contains","comment":" Check if a circle contains a given point.\n\n    Circle2d.contains Point2d.origin exampleCircle\n    --> True\n\n    exampleCircle\n        |> Circle2d.contains\n            (Point2d.fromCoordinates ( 10, 10 ))\n    --> False\n\n","type":"Point2d.Point2d -> Circle2d.Circle2d -> Basics.Bool"},{"name":"diameter","comment":" Get the diameter of a circle.\n\n    Circle2d.diameter exampleCircle\n    --> 6\n\n","type":"Circle2d.Circle2d -> Basics.Float"},{"name":"mirrorAcross","comment":" Mirror a circle across a given axis.\n\n    Circle2d.mirrorAcross Axis2d.x exampleCircle\n    --> Circle2d.withRadius 3\n    -->     (Point2d.fromCoordinates ( 1, -2 ))\n\n","type":"Axis2d.Axis2d -> Circle2d.Circle2d -> Circle2d.Circle2d"},{"name":"placeIn","comment":" Take a circle considered to be defined in local coordinates relative to a\ngiven reference frame, and return that circle expressed in global coordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))\n\n    Circle2d.placeIn localFrame exampleCircle\n    --> Circle2d.withRadius 3\n    -->     (Point2d.fromCoordinates ( 3, 5 ))\n\n","type":"Frame2d.Frame2d -> Circle2d.Circle2d -> Circle2d.Circle2d"},{"name":"radius","comment":" Get the radius of a circle.\n\n    Circle2d.radius exampleCircle\n    --> 3\n\n","type":"Circle2d.Circle2d -> Basics.Float"},{"name":"relativeTo","comment":" Take a circle defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))\n\n    Circle2d.relativeTo localFrame exampleCircle\n    --> Circle2d.withRadius 3\n    -->     (Point2d.fromCoordinates ( -1, -1 ))\n\n","type":"Frame2d.Frame2d -> Circle2d.Circle2d -> Circle2d.Circle2d"},{"name":"rotateAround","comment":" Rotate a circle around a given point by a given angle (in radians).\n\n    exampleCircle\n        |> Circle2d.rotateAround Point2d.origin\n            (degrees 90)\n    --> Circle2d.withRadius 3\n    -->     (Point2d.fromCoordinates ( -2, 1 ))\n\n","type":"Point2d.Point2d -> Basics.Float -> Circle2d.Circle2d -> Circle2d.Circle2d"},{"name":"scaleAbout","comment":" Scale a circle about a given point by a given scale.\n\n    Circle2d.scaleAbout Point2d.origin 2 exampleCircle\n    --> Circle2d.withRadius 6\n    -->     (Point2d.fromCoordinates ( 2, 4 ))\n\n    exampleCircle\n        |> Circle2d.scaleAbout\n            (Point2d.fromCoordinates ( 1, 2 ))\n            0.5\n    --> Circle2d.withRadius 1.5\n    -->     (Point2d.fromCoordinates ( 1, 2 ))\n\n","type":"Point2d.Point2d -> Basics.Float -> Circle2d.Circle2d -> Circle2d.Circle2d"},{"name":"sweptAround","comment":" Construct a circle by rotating a point on the circle around a given center\npoint. The center point is given first and the point on the circle is given\nsecond.\n\n    Circle2d.sweptAround Point2d.origin\n        (Point2d.fromCoordinates ( 2, 0 ))\n    --> Circle2d.withRadius 2 Point2d.origin\n\nThe above example could be rewritten as\n\n    Point2d.fromCoordinates ( 2, 0 )\n        |> Circle2d.sweptAround Point2d.origin\n\nand if you wanted to create many concentric circles all centered on the origin\nbut passing through several other different points, you could use something like\n\n    concentricCircles =\n        points\n            |> List.map\n                (Circle2d.sweptAround Point2d.origin)\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Circle2d.Circle2d"},{"name":"throughPoints","comment":" Attempt to construct a circle that passes through the three given points. If\nthe three given points are collinear, returns `Nothing`.\n\n    Circle2d.throughPoints\n        Point2d.origin\n        (Point2d.fromCoordinates ( 1, 0 ))\n        (Point2d.fromCoordinates ( 0, 1 ))\n    --> Just\n    -->     (Circle2d.withRadius 0.7071\n    -->         (Point2d.fromCoordinates ( 0.5, 0.5 ))\n    -->     )\n\n    Circle2d.throughPoints\n        Point2d.origin\n        (Point2d.fromCoordinates ( 2, 1 ))\n        (Point2d.fromCoordinates ( 4, 0 ))\n    --> Just\n    -->     (Circle2d.withRadius 2.5\n    -->         (Point2d.fromCoordinates ( 2, -1.5 ))\n    -->     )\n\n    Circle2d.throughPoints\n        Point2d.origin\n        (Point2d.fromCoordinates ( 2, 0 ))\n        (Point2d.fromCoordinates ( 4, 0 ))\n    --> Nothing\n\n    Circle2d.throughPoints\n        Point2d.origin\n        Point2d.origin\n        (Point2d.fromCoordinates ( 1, 0 ))\n    --> Nothing\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Point2d.Point2d -> Maybe.Maybe Circle2d.Circle2d"},{"name":"toArc","comment":" Convert a circle to a 360 degree arc.\n\n    Circle2d.toArc exampleCircle\n    --> Point2d.fromCoordinates ( 4, 2 )\n    -->     |> Arc2d.sweptAround\n    -->         (Point2d.fromCoordinates ( 1, 2 ))\n    -->         (degrees 360)\n\n","type":"Circle2d.Circle2d -> Geometry.Types.Arc2d"},{"name":"translateBy","comment":" Translate a circle by a given displacement.\n\n    exampleCircle\n        |> Circle2d.translateBy\n            (Vector2d.fromComponents ( 2, 2 ))\n    --> Circle2d.withRadius 3\n    -->     (Point2d.fromCoordinates ( 3, 4 ))\n\n","type":"Vector2d.Vector2d -> Circle2d.Circle2d -> Circle2d.Circle2d"},{"name":"translateIn","comment":" Translate a circle in a given direction by a given distance;\n\n    Circle2d.translateIn direction distance\n\nis equivalent to\n\n    Circle2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Circle2d.Circle2d -> Circle2d.Circle2d"},{"name":"unit","comment":" The unit circle, centered on the origin with a radius of 1.\n\n    Circle2d.unit\n    --> Circle2d.withRadius 1 Point2d.origin\n\n","type":"Circle2d.Circle2d"},{"name":"withRadius","comment":" Construct a circle from its radius and center point:\n\n    exampleCircle =\n        Circle2d.withRadius 3\n            (Point2d.fromCoordinates ( 1, 2 ))\n\nIf you pass a negative radius, the absolute value will be used.\n\n","type":"Basics.Float -> Point2d.Point2d -> Circle2d.Circle2d"}],"binops":[]},{"name":"Circle3d","comment":" A `Circle3d` is defined by its center point, axial direction and radius. The\naxial direction is the direction of the axis through the center of the circle\nthat all points on the circle are equidistant from, or equivalently the normal\ndirection of the plane defined by the circle. This module contains functionality\nfor:\n\n  - Constructing circles around axes, on planes, or through points\n  - Scaling, rotating and translating circles\n  - Extracting circle properties like center point and area\n\n@docs Circle3d\n\n\n# Constructors\n\n@docs withRadius, sweptAround, on, throughPoints\n\n\n# Properties\n\n@docs centerPoint, axialDirection, radius, diameter, axis, plane, area, circumference, boundingBox\n\n\n# Transformations\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectInto\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Circle3d","comment":" ","args":[],"type":"Geometry.Types.Circle3d"}],"values":[{"name":"area","comment":" Get the area of a circle.\n\n    Circle3d.area exampleCircle\n    --> 28.2743\n\n","type":"Circle3d.Circle3d -> Basics.Float"},{"name":"axialDirection","comment":" Get the axial direction of a circle.\n\n    Circle3d.axialDirection exampleCircle\n    --> Direction3d.z\n\n","type":"Circle3d.Circle3d -> Direction3d.Direction3d"},{"name":"axis","comment":" Get the central axis of a circle, perpendicular to its [`plane`](#plane).\nThe origin point of the returned axis will be the center point of the circle.\n\n    Circle3d.axis exampleCircle\n    --> Axis3d.withDirection Direction3d.z\n    -->     (Point3d.fromCoordinates ( 2, 0, 1 ))\n\n","type":"Circle3d.Circle3d -> Axis3d.Axis3d"},{"name":"boundingBox","comment":" Get the minimal bounding box containing a given circle.\n\n    Circle3d.boundingBox exampleCircle\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = -1\n    -->     , maxX = 5\n    -->     , minY = -3\n    -->     , maxY = 3\n    -->     , minZ = 1\n    -->     , maxZ = 1\n    -->     }\n\n","type":"Circle3d.Circle3d -> BoundingBox3d.BoundingBox3d"},{"name":"centerPoint","comment":" Get the center point of a circle.\n\n    Circle3d.centerPoint exampleCircle\n    --> Point3d.fromCoordinates ( 2, 0, 1 )\n\n","type":"Circle3d.Circle3d -> Point3d.Point3d"},{"name":"circumference","comment":" Get the circumference of a circle.\n\n    Circle3d.circumference exampleCircle\n    --> 18.8496\n\n","type":"Circle3d.Circle3d -> Basics.Float"},{"name":"diameter","comment":" Get the diameter of a circle.\n\n    Circl3d.diameter exampleCircle\n    --> 6\n\n","type":"Circle3d.Circle3d -> Basics.Float"},{"name":"mirrorAcross","comment":" Mirror a circle across a given plane.\n\n    Circle3d.mirrorAcross Plane3d.xy exampleCircle\n    --> Circle3d.withRadius 3\n    -->     Direction3d.negativeZ\n    -->     (Point3d.fromCoordinates ( 2, 0, -1 ))\n\n","type":"Plane3d.Plane3d -> Circle3d.Circle3d -> Circle3d.Circle3d"},{"name":"on","comment":" Construct a 3D circle lying _on_ a sketch plane by providing a 2D circle\nspecified in XY coordinates _within_ the sketch plane.\n\n    Circle3d.on SketchPlane3d.yz <|\n        Circle2d.withRadius 3\n            (Point2d.fromCoordinates ( 1, 2 ))\n\n    --> Circle3d.withRadius 3\n    -->     Direction3d.x\n    -->     (Point3d.fromCoordinates ( 0, 1, 2 ))\n\n","type":"SketchPlane3d.SketchPlane3d -> Circle2d.Circle2d -> Circle3d.Circle3d"},{"name":"placeIn","comment":" Take a circle considered to be defined in local coordinates relative to a\ngiven reference frame, and return that circle expressed in global coordinates.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Circle3d.placeIn localFrame exampleCircle\n    --> Circle3d.withRadius 3\n    -->     Direction3d.z\n    -->     (Point3d.fromCoordinates ( 3, 2, 4 ))\n\n","type":"Frame3d.Frame3d -> Circle3d.Circle3d -> Circle3d.Circle3d"},{"name":"plane","comment":" Get the plane that a circle lies in. The origin point of the returned plane\nwill be the center point of the circle, and its normal direction will be the\naxial direction of the circle.\n\n    Circle3d.plane exampleCircle\n    --> Plane3d.withNormalDirection Direction3d.z\n    -->     (Point3d.fromCoordinates ( 2, 0, 1 ))\n\n","type":"Circle3d.Circle3d -> Plane3d.Plane3d"},{"name":"projectInto","comment":" Project a circle into a sketch plane.\n\n    inclinedCircle : Circle3d\n    inclinedCircle =\n        Circle3d.withRadius 1\n            (Direction3d.fromAzimuthAndElevation\n                (degrees 0)\n                (degrees 45)\n            )\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Circle3d.projectInto SketchPlane3d.xy inclinedCircle\n    --> Ellipse2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( 1, 2 )\n    -->     , xDirection = Direction2d.negativeY\n    -->     , xRadius = 1\n    -->     , yRadius = 0.7071\n    -->     }\n\n","type":"SketchPlane3d.SketchPlane3d -> Circle3d.Circle3d -> Geometry.Types.Ellipse2d"},{"name":"radius","comment":" Get the radius of a circle.\n\n    Circle3d.radius exampleCircle\n    --> 3\n\n","type":"Circle3d.Circle3d -> Basics.Float"},{"name":"relativeTo","comment":" Take a circle defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Circle3d.relativeTo localFrame exampleCircle\n    --> Circle3d.withRadius 3\n    -->     Direction3d.z\n    -->     (Point3d.fromCoordinates ( 1, -2, -2 ))\n\n","type":"Frame3d.Frame3d -> Circle3d.Circle3d -> Circle3d.Circle3d"},{"name":"rotateAround","comment":" Rotate a circle around a given axis by a given angle (in radians).\n\n    exampleCircle\n        |> Circle3d.rotateAround Axis3d.y (degrees 90)\n    --> Circle3d.withRadius 3\n    -->     Direction3d.x\n    -->     (Point3d.fromCoordinates ( 1, 0, -2 ))\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Circle3d.Circle3d -> Circle3d.Circle3d"},{"name":"scaleAbout","comment":" Scale a circle around a given point by a given scale.\n\n    Circle3d.scaleAbout Point3d.origin 3 exampleCircle\n    --> Circle3d.withRadius 3\n    -->     Direction3d.z\n    -->     (Point3d.fromCoordinates ( 6, 0, 3 ))\n\n","type":"Point3d.Point3d -> Basics.Float -> Circle3d.Circle3d -> Circle3d.Circle3d"},{"name":"sweptAround","comment":" Construct a circle by sweeping the given point around the given axis.\n\n    Circle3d.sweptAround Axis3d.z\n        (Point3d.fromCoordinates ( 3, 0, 2 ))\n    --> Circle3d.withRadius 3\n    -->     Direction3d.z\n    -->     (Point3d.fromCoordinates ( 0, 0, 2 ))\n\n","type":"Axis3d.Axis3d -> Point3d.Point3d -> Circle3d.Circle3d"},{"name":"throughPoints","comment":" Attempt to construct a circle that passes through the three given points.\nThe axial direction of the returned circle will be such that the three points\nare in counterclockwise order around it, according to the right-hand rule. If\nthe three given points are collinear, returns `Nothing`.\n\n    Circle3d.throughPoints\n        (Point3d.fromCoordinates ( 1, 0, 0 ))\n        (Point3d.fromCoordinates ( 0, 1, 0 ))\n        (Point3d.fromCoordinates ( 0, 0, 1 ))\n    --> Just\n    -->     (Circle3d.withRadius 0.8165\n    -->         (Direction3d.fromAzimuthAndElevation\n    -->             (degrees 45)\n    -->             (degrees 35.26)\n    -->         )\n    -->         (Point3d.fromCoordinates\n    -->             ( 0.333, 0.333, 0.333 )\n    -->         )\n    -->     )\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Point3d.Point3d -> Maybe.Maybe Circle3d.Circle3d"},{"name":"translateBy","comment":" Translate a circle by a given displacement.\n\n    displacement =\n        Vector3d.fromComponents ( 2, 1, 3 )\n\n    Circle3d.translateBy displacement exampleCircle\n    --> Circle3d.withRadius 3\n    -->     Direction3d.z\n    -->     (Point3d.fromCoordinates ( 4, 1, 4 ))\n\n","type":"Vector3d.Vector3d -> Circle3d.Circle3d -> Circle3d.Circle3d"},{"name":"translateIn","comment":" Translate a circle in a given direction by a given distance;\n\n    Circle3d.translateIn direction distance\n\nis equivalent to\n\n    Circle3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> Circle3d.Circle3d -> Circle3d.Circle3d"},{"name":"withRadius","comment":" Construct a circle from its radius, axial direction and center point:\n\n    exampleCircle =\n        Circle3d.withRadius 3\n            Direction3d.z\n            (Point3d.fromCoordinates ( 2, 0, 1 ))\n\nIf you pass a negative radius, the absolute value will be used.\n\n","type":"Basics.Float -> Direction3d.Direction3d -> Point3d.Point3d -> Circle3d.Circle3d"}],"binops":[]},{"name":"CubicSpline2d","comment":" A `CubicSpline2d` is a cubic [Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve)\nin 2D defined by a start point, end point and two control points. This module\ncontains functionality for\n\n  - Constructing splines\n  - Evaluating points and tangent directions along a spline\n  - Scaling, rotating, translating or mirroring a spline\n  - Converting a spline between local and global coordinates in different\n    reference frames\n\n@docs CubicSpline2d\n\n\n# Constructors\n\n@docs with, fromEndpoints, fromQuadraticSpline\n\n\n# Properties\n\n@docs startPoint, endPoint, startControlPoint, endControlPoint, startDerivative, endDerivative, boundingBox\n\n\n# Evaluation\n\n@docs pointOn, pointsAt\n@docs Nondegenerate, nondegenerate, fromNondegenerate\n@docs tangentDirection, tangentDirectionsAt, sample, samplesAt\n\n\n# Transformations\n\n@docs reverse, scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n\n# Subdivision\n\n@docs bisect, splitAt\n\n\n# Arc length parameterization\n\n@docs ArcLengthParameterized, arcLengthParameterized, arcLength, pointAlong, tangentDirectionAlong, sampleAlong\n\n\n## Low level\n\nAn `ArcLengthParameterized` value is a combination of an\n[`ArcLengthParameterization`](Geometry-ArcLengthParameterization) and an\nunderlying `CubicSpline2d`. If you need to do something fancy, you can extract\nthese two values separately.\n\n@docs arcLengthParameterization, fromArcLengthParameterized\n\n\n# Differentiation\n\nYou are unlikely to need to use these functions directly, but they are useful if\nyou are writing low-level geometric algorithms.\n\n@docs firstDerivative, firstDerivativesAt, secondDerivative, secondDerivativesAt, thirdDerivative, maxSecondDerivativeMagnitude\n\n","unions":[{"name":"ArcLengthParameterized","comment":" A spline that has been parameterized by arc length.\n","args":[],"cases":[]},{"name":"Nondegenerate","comment":" If a curve has zero length (consists of just a single point), then we say\nthat it is 'degenerate'. Some operations such as computing tangent directions\nare not defined on degenerate curves.\n\nA `Nondegenerate` value represents a spline that is definitely not degenerate.\nIt is used as input to functions such as `CubicSpline2d.tangentDirection` and\ncan be constructed using `CubicSpline2d.nondegenerate`.\n\n","args":[],"cases":[]}],"aliases":[{"name":"CubicSpline2d","comment":" ","args":[],"type":"Geometry.Types.CubicSpline2d"}],"values":[{"name":"arcLength","comment":" Find the total arc length of a spline:\n\n    arcLength =\n        CubicSpline2d.arcLength parameterizedSpline\n\n    arcLength\n    --> 7.0952\n\nIn this example, the result will be accurate to within `1.0e-4` since that was\nthe tolerance used when constructing `parameterizedSpline`.\n\n","type":"CubicSpline2d.ArcLengthParameterized -> Basics.Float"},{"name":"arcLengthParameterization","comment":" ","type":"CubicSpline2d.ArcLengthParameterized -> Curve.ArcLengthParameterization.ArcLengthParameterization"},{"name":"arcLengthParameterized","comment":" Build an arc length parameterization of the given spline, with a given\naccuracy. Generally speaking, all operations on the resulting\n`ArcLengthParameterized` value will be accurate to within the specified maximum\nerror.\n\n    parameterizedSpline =\n        exampleSpline\n            |> CubicSpline2d.arcLengthParameterized\n                { maxError = 1.0e-4 }\n\nThe accuracy of the parameterization affects the accuracy of results returned\nfrom functions such as `arcLength` and `pointAlong`.\n\n","type":"{ maxError : Basics.Float } -> CubicSpline2d.CubicSpline2d -> CubicSpline2d.ArcLengthParameterized"},{"name":"bisect","comment":" Split a spline into two roughly equal halves.\n\n    CubicSpline2d.bisect exampleSpline\n    --> ( CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 1, 1 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 2, 2.5 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 3, 2.5 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 4, 2.5 )\n    -->     }\n    --> , CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 4, 2.5 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 5, 2.5 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 6, 2.5 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 7, 4 )\n    -->     }\n    --> )\n\nEquivalent to `CubicSpline2d.splitAt ParameterValue.half`.\n\n","type":"CubicSpline2d.CubicSpline2d -> ( CubicSpline2d.CubicSpline2d, CubicSpline2d.CubicSpline2d )"},{"name":"boundingBox","comment":" Compute a bounding box for a given spline. It is not guaranteed that the\nresult will be the _smallest_ possible bounding box, since for efficiency the\nbounding box is computed from the spline's control points (which cover a larger\narea than the spline itself).\n\n    CubicSpline2d.boundingBox exampleSpline\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 7\n    -->     , minY = 1\n    -->     , maxY = 4\n    -->     }\n\n","type":"CubicSpline2d.CubicSpline2d -> BoundingBox2d.BoundingBox2d"},{"name":"endControlPoint","comment":" Get the end control point of a spline (the control point next to the\nend point).\n\n    CubicSpline2d.endControlPoint exampleSpline\n    --> Point2d.fromCoordinates ( 5, 1 )\n\n","type":"CubicSpline2d.CubicSpline2d -> Point2d.Point2d"},{"name":"endDerivative","comment":" Get the end derivative of a spline. This is equal to three times the vector\nfrom the spline's end control point to its end point.\n\n    CubicSpline2d.endDerivative exampleSpline\n    --> Vector2d.fromComponents ( 6, 9 )\n\n","type":"CubicSpline2d.CubicSpline2d -> Vector2d.Vector2d"},{"name":"endPoint","comment":" Get the end point of a spline.\n\n    CubicSpline2d.endPoint exampleSpline\n    --> Point2d.fromCoordinates ( 7, 4 )\n\n","type":"CubicSpline2d.CubicSpline2d -> Point2d.Point2d"},{"name":"firstDerivative","comment":" Get the first derivative of a spline at a given parameter value:\n\n    CubicSpline2d.firstDerivative exampleSpline\n        ParameterValue.zero\n    --> Vector2d.fromComponents ( 6, 9 )\n\n    CubicSpline2d.firstDerivative exampleSpline\n        ParameterValue.half\n    --> Vector2d.fromComponents ( 6, 0 )\n\n    CubicSpline2d.firstDerivative exampleSpline\n        ParameterValue.one\n    --> Vector2d.fromComponents ( 6, 9 )\n\n","type":"CubicSpline2d.CubicSpline2d -> Curve.ParameterValue.ParameterValue -> Vector2d.Vector2d"},{"name":"firstDerivativesAt","comment":" Evaluate the first derivative of a spline at a given set of parameter\nvalues:\n\n    exampleSpline\n        |> CubicSpline2d.firstDerivativesAt\n            (ParameterValue.steps 2)\n    --> [ Vector2d.fromComponents ( 6, 9 )\n    --> , Vector2d.fromComponents ( 6, 0 )\n    --> , Vector2d.fromComponents ( 6, 9 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline2d.CubicSpline2d -> List.List Vector2d.Vector2d"},{"name":"fromArcLengthParameterized","comment":" ","type":"CubicSpline2d.ArcLengthParameterized -> CubicSpline2d.CubicSpline2d"},{"name":"fromEndpoints","comment":" Construct a spline from a given start point with a given start derivative,\nto a given end point with a given end derivative, like so:\n\n![Cubic spline from endpoints](https://ianmackenzie.github.io/elm-geometry/1.0.0/CubicSpline2d/fromEndpoints.svg)\n\nThe spline is based on a parameter that ranges from 0 to 1; as a result, in most\ncases the length of each derivative vector should be roughly equal to the length\nof the resulting spline.\n\n","type":"{ startPoint : Point2d.Point2d, startDerivative : Vector2d.Vector2d, endPoint : Point2d.Point2d, endDerivative : Vector2d.Vector2d } -> CubicSpline2d.CubicSpline2d"},{"name":"fromNondegenerate","comment":" Convert a nondegenerate spline back to a general `CubicSpline2d`.\n\n    CubicSpline2d.fromNondegenerate\n        nondegenerateExampleSpline\n    --> exampleSpline\n\n","type":"CubicSpline2d.Nondegenerate -> CubicSpline2d.CubicSpline2d"},{"name":"fromQuadraticSpline","comment":" Convert a quadratic spline into the equivalent cubic spline (every quadratic\nspline can be represented exactly as a cubic spline).\n\n    quadraticSpline =\n        QuadraticSpline2d.with\n            { startPoint =\n                Point2d.fromCoordinates ( 0, 0  )\n            , controlPoint =\n                Point2d.fromCoordinates ( 3, 0 )\n            , endPoint =\n                Point2d.fromCoordinates ( 3, 3 )\n            }\n\n    CubicSpline2d.fromQuadraticSpline quadraticSpline\n    --> CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 0, 0 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 2, 0 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 3, 1 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 3, 3 )\n    -->     }\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> CubicSpline2d.CubicSpline2d"},{"name":"maxSecondDerivativeMagnitude","comment":" Find a conservative upper bound on the magnitude of the second derivative of\na spline. This can be useful when determining error bounds for various kinds of\nlinear approximations.\n\n    exampleSpline\n        |> CubicSpline2d.maxSecondDerivativeMagnitude\n    --> 36\n\n","type":"CubicSpline2d.CubicSpline2d -> Basics.Float"},{"name":"mirrorAcross","comment":" Mirror a spline across an axis.\n\n    CubicSpline2d.mirrorAcross Axis2d.x exampleSpline\n    --> CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 1, -1 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 3, -4 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 5, -1 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 7, -4 )\n    -->     }\n\n","type":"Axis2d.Axis2d -> CubicSpline2d.CubicSpline2d -> CubicSpline2d.CubicSpline2d"},{"name":"nondegenerate","comment":" Attempt to construct a nondegenerate spline from a general `CubicSpline2d`.\nIf the spline is in fact degenerate (consists of a single point), returns an\n`Err` with that point.\n\n    CubicSpline2d.nondegenerate exampleSpline\n    --> Ok nondegenerateExampleSpline\n\n","type":"CubicSpline2d.CubicSpline2d -> Result.Result Point2d.Point2d CubicSpline2d.Nondegenerate"},{"name":"placeIn","comment":" Take a spline considered to be defined in local coordinates relative to a\ngiven reference frame, and return that spline expressed in global coordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    CubicSpline2d.placeIn localFrame exampleSpline\n    --> CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 2, 3 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 4, 6 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 6, 3 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 8, 6 )\n    -->     }\n\n","type":"Frame2d.Frame2d -> CubicSpline2d.CubicSpline2d -> CubicSpline2d.CubicSpline2d"},{"name":"pointAlong","comment":" Try to get the point along a spline at a given arc length. For example, to\nget the point a quarter of the way along `exampleSpline`, using `arcLength` as\ncomputed above:\n\n    CubicSpline2d.pointAlong parameterizedSpline\n        (0.25 * arcLength)\n    --> Just (Point2d.fromCoordinates ( 2.2681, 2.2114 ))\n\nNote that this is not the same as evaulating at a parameter value of 0.25:\n\n    CubicSpline2d.pointOn exampleSpline\n        (ParameterValue.clamped 0.25)\n    --> Point2d.fromCoordinates ( 2.5, 2.3125 )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline, returns `Nothing`.\n\n","type":"CubicSpline2d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Point2d.Point2d"},{"name":"pointOn","comment":" Get the point along a spline at a given parameter value:\n\n    CubicSpline2d.pointOn exampleSpline ParameterValue.zero\n    --> Point2d.fromCoordinates ( 1, 1 )\n\n    CubicSpline2d.pointOn exampleSpline ParameterValue.half\n    --> Point2d.fromCoordinates ( 4, 2.5 )\n\n    CubicSpline2d.pointOn exampleSpline ParameterValue.one\n    --> Point2d.fromCoordinates ( 7, 4 )\n\n","type":"CubicSpline2d.CubicSpline2d -> Curve.ParameterValue.ParameterValue -> Point2d.Point2d"},{"name":"pointsAt","comment":" Get points along a spline at a given set of parameter values:\n\n    exampleSpline\n        |> CubicSpline2d.pointsAt\n            (ParameterValue.steps 2)\n    --> [ Point2d.fromCoordinates ( 1, 1 )\n    --> , Point2d.fromCoordinates ( 4, 2.5 )\n    --> , Point2d.fromCoordinates ( 7, 4 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline2d.CubicSpline2d -> List.List Point2d.Point2d"},{"name":"relativeTo","comment":" Take a spline defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    CubicSpline2d.relativeTo localFrame exampleSpline\n    --> CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 0, -1 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 2, 2 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 4, -1 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 6, 2 )\n    -->     }\n\n","type":"Frame2d.Frame2d -> CubicSpline2d.CubicSpline2d -> CubicSpline2d.CubicSpline2d"},{"name":"reverse","comment":" Reverse a spline so that the start point becomes the end point, and vice\nversa.\n\n    CubicSpline2d.reverse exampleSpline\n    --> CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 7, 4 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 5, 1 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 3, 4 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 1, 1 )\n    -->     }\n\n","type":"CubicSpline2d.CubicSpline2d -> CubicSpline2d.CubicSpline2d"},{"name":"rotateAround","comment":" Rotate a spline counterclockwise around a given center point by a given\nangle (in radians).\n\n    exampleSpline\n        |> CubicSpline2d.rotateAround Point2d.origin\n            (degrees 90)\n    --> CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( -1, 1 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( -4, 3 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( -1, 5 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( -4, 7 )\n    -->     }\n\n","type":"Point2d.Point2d -> Basics.Float -> CubicSpline2d.CubicSpline2d -> CubicSpline2d.CubicSpline2d"},{"name":"sample","comment":" Get both the point and tangent direction of a nondegenerate spline at a\ngiven parameter value:\n\n    CubicSpline2d.sample nondegenerateExampleSpline\n        ParameterValue.half\n    --> ( Point2d.fromCoordinates ( 4, 2.5 )\n    --> , Direction2d.fromAngle (degrees 0)\n    --> )\n\n","type":"CubicSpline2d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"sampleAlong","comment":" Try to get the point and tangent direction along a spline at a given arc\nlength. To get the point and tangent direction a quarter of the way along\n`exampleSpline`:\n\n    CubicSpline2d.sampleAlong parameterizedSpline\n        (0.25 * arcLength)\n    --> Just\n    -->     ( Point2d.fromCoordinates ( 2.2681, 2.2114 )\n    -->     , Direction2d.fromAngle (degrees 26.5611)\n    -->     )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline (or if the spline is degenerate), returns `Nothing`.\n\n","type":"CubicSpline2d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"samplesAt","comment":" Get points and tangent directions of a nondegenerate spline at a given set\nof parameter values:\n\n    nondegenerateExampleSpline\n        |> CubicSpline2d.samplesAt\n            (ParameterValue.steps 2)\n    --> [ ( Point2d.fromCoordinates ( 1, 1 )\n    -->   , Direction2d.fromAngle (degrees 56.31)\n    -->   )\n    --> , ( Point2d.fromCoordinates ( 4, 2.5 )\n    -->   , Direction2d.fromAngle (degrees 0)\n    -->   )\n    --> , ( Point2d.fromCoordinates ( 7, 4 )\n    -->   , Direction2d.fromAngle (degrees 56.31)\n    -->   )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline2d.Nondegenerate -> List.List ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"scaleAbout","comment":" Scale a spline about the given center point by the given scale.\n\n    CubicSpline2d.scaleAbout Point2d.origin 2 exampleSpline\n    --> CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 2, 2 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 6, 8 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 10, 2 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 14, 8 )\n    -->     }\n\n","type":"Point2d.Point2d -> Basics.Float -> CubicSpline2d.CubicSpline2d -> CubicSpline2d.CubicSpline2d"},{"name":"secondDerivative","comment":" Evaluate the second derivative of a spline at a given parameter value:\n\n    CubicSpline2d.secondDerivativeAt 0 exampleSpline\n    --> Just (Vector2d.fromComponents ( 0, -36 ))\n\n    CubicSpline2d.secondDerivativeAt 0.5 exampleSpline\n    --> Just (Vector2d.fromComponents ( 0, 0 ))\n\n    CubicSpline2d.secondDerivativeAt 1 exampleSpline\n    --> Just (Vector2d.fromComponents ( 0, 36 ))\n\n","type":"CubicSpline2d.CubicSpline2d -> Curve.ParameterValue.ParameterValue -> Vector2d.Vector2d"},{"name":"secondDerivativesAt","comment":" Evaluate the second derivative of a spline at a given set of parameter\nvalues:\n\n    exampleSpline\n        |> CubicSpline2d.secondDerivativesAt\n            (ParameterValue.steps 2)\n    --> [ Vector2d.fromComponents ( 0, -36 )\n    --> , Vector2d.fromComponents ( 0, 0 )\n    --> , Vector2d.fromComponents ( 0, 36 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline2d.CubicSpline2d -> List.List Vector2d.Vector2d"},{"name":"splitAt","comment":" Split a spline at a particular parameter value, resulting in two smaller\nsplines.\n\n    parameterValue =\n        ParameterValue.clamped 0.75\n\n    CubicSpline2d.splitAt parameterValue exampleSpline\n    --> ( CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 1, 1 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 2.5, 3.25 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 4, 2.125 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 5.5, 2.6875 )\n    -->     }\n    --> , CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 5.5, 2.6875 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 6, 2.875 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 6.5, 3.25 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 7, 4 )\n    -->     }\n    --> )\n\n","type":"Curve.ParameterValue.ParameterValue -> CubicSpline2d.CubicSpline2d -> ( CubicSpline2d.CubicSpline2d, CubicSpline2d.CubicSpline2d )"},{"name":"startControlPoint","comment":" Get the start control point of a spline (the control point next to the\nstart point).\n\n    CubicSpline2d.startControlPoint exampleSpline\n    --> Point2d.fromCoordinates ( 3, 4 )\n\n","type":"CubicSpline2d.CubicSpline2d -> Point2d.Point2d"},{"name":"startDerivative","comment":" Get the start derivative of a spline. This is equal to three times the\nvector from the spline's start point to its start control point.\n\n    CubicSpline2d.startDerivative exampleSpline\n    --> Vector2d.fromComponents ( 6, 9 )\n\n","type":"CubicSpline2d.CubicSpline2d -> Vector2d.Vector2d"},{"name":"startPoint","comment":" Get the start point of a spline.\n\n    CubicSpline2d.startPoint exampleSpline\n    --> Point2d.fromCoordinates ( 1, 1 )\n\n","type":"CubicSpline2d.CubicSpline2d -> Point2d.Point2d"},{"name":"tangentDirection","comment":" Get the tangent direction to a nondegenerate spline at a given parameter\nvalue:\n\n    CubicSpline2d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.zero\n    --> Direction2d.fromAngle (degrees 56.31)\n\n    CubicSpline2d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.half\n    --> Direction2d.fromAngle (degrees 0)\n\n    CubicSpline2d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.one\n    --> Direction2d.fromAngle (degrees 56.31)\n\n","type":"CubicSpline2d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> Direction2d.Direction2d"},{"name":"tangentDirectionAlong","comment":" Try to get the tangent direction along a spline at a given arc length. To\nget the tangent direction a quarter of the way along `exampleSpline`:\n\n    CubicSpline2d.tangentDirectionAlong parameterizedSpline\n        (0.25 * arcLength)\n    --> Just (Direction2d.fromAngle (degrees 26.5611))\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline (or if the spline is degenerate), returns `Nothing`.\n\n","type":"CubicSpline2d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Direction2d.Direction2d"},{"name":"tangentDirectionsAt","comment":" Get tangent directions to a nondegenerate spline at a given set of parameter\nvalues:\n\n    nondegenerateExampleSpline\n        |> CubicSpline2d.tangentDirectionsAt\n            (ParameterValue.steps 2)\n    --> [ Direction2d.fromAngle (degrees 56.31)\n    --> , Direction2d.fromAngle (degrees 0)\n    --> , Direction2d.fromAngle (degrees 56.31)\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline2d.Nondegenerate -> List.List Direction2d.Direction2d"},{"name":"thirdDerivative","comment":" Get the third derivative of a spline (for a cubic spline, this is a\nconstant):\n\n    CubicSpline2d.thirdDerivative exampleSpline\n    --> Vector2d.fromComponents ( 0, 72 )\n\n","type":"CubicSpline2d.CubicSpline2d -> Vector2d.Vector2d"},{"name":"translateBy","comment":" Translate a spline by a given displacement.\n\n    displacement =\n        Vector2d.fromComponents ( 2, 3 )\n\n    CubicSpline2d.translateBy displacement exampleSpline\n    --> CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 3, 4 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 5, 7 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 7, 4 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 9, 7 )\n    -->     }\n\n","type":"Vector2d.Vector2d -> CubicSpline2d.CubicSpline2d -> CubicSpline2d.CubicSpline2d"},{"name":"translateIn","comment":" Translate a spline in a given direction by a given distance;\n\n    CubicSpline2d.translateIn direction distance\n\nis equivalent to\n\n    CubicSpline2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> CubicSpline2d.CubicSpline2d -> CubicSpline2d.CubicSpline2d"},{"name":"with","comment":" Construct a spline from its endpoints and control points:\n\n    exampleSpline =\n        CubicSpline2d.with\n            { startPoint =\n                Point2d.fromCoordinates ( 1, 1 )\n            , startControlPoint =\n                Point2d.fromCoordinates ( 3, 4 )\n            , endControlPoint =\n                Point2d.fromCoordinates ( 5, 1 )\n            , endPoint =\n                Point2d.fromCoordinates ( 7, 4 )\n            }\n\n","type":"{ startPoint : Point2d.Point2d, startControlPoint : Point2d.Point2d, endControlPoint : Point2d.Point2d, endPoint : Point2d.Point2d } -> CubicSpline2d.CubicSpline2d"}],"binops":[]},{"name":"CubicSpline3d","comment":" A `CubicSpline3d` is a cubic [Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve)\nin 3D defined by a start point, end point and two control points. This module\ncontains functionality for\n\n  - Constructing splines\n  - Evaluating points and derivatives along a spline\n  - Scaling, rotating, translating or mirroring a spline\n  - Converting a spline between local and global coordinates in different\n    reference frames\n\n@docs CubicSpline3d\n\n\n# Constructors\n\n@docs with, fromEndpoints, on, fromQuadraticSpline\n\n\n# Properties\n\n@docs startPoint, endPoint, startControlPoint, endControlPoint, startDerivative, endDerivative, boundingBox\n\n\n# Evaluation\n\n@docs pointOn, pointsAt\n@docs Nondegenerate, nondegenerate, fromNondegenerate\n@docs tangentDirection, tangentDirectionsAt, sample, samplesAt\n\n\n# Transformations\n\n@docs reverse, scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn, projectInto\n\n\n# Subdivision\n\n@docs bisect, splitAt\n\n\n# Arc length parameterization\n\n@docs ArcLengthParameterized, arcLengthParameterized, arcLength, pointAlong, tangentDirectionAlong, sampleAlong\n\n\n## Low level\n\nAn `ArcLengthParameterized` value is a combination of an\n[`ArcLengthParameterization`](Geometry-ArcLengthParameterization) and an\nunderlying `CubicSpline3d`. If you need to do something fancy, you can extract\nthese two values separately.\n\n@docs arcLengthParameterization, fromArcLengthParameterized\n\n\n# Differentiation\n\nYou are unlikely to need to use these functions directly, but they are useful if\nyou are writing low-level geometric algorithms.\n\n@docs firstDerivative, firstDerivativesAt, secondDerivative, secondDerivativesAt, thirdDerivative, maxSecondDerivativeMagnitude\n\n","unions":[{"name":"ArcLengthParameterized","comment":" A spline that has been parameterized by arc length.\n","args":[],"cases":[]},{"name":"Nondegenerate","comment":" If a curve has zero length (consists of just a single point), then we say\nthat it is 'degenerate'. Some operations such as computing tangent directions\nare not defined on degenerate curves.\n\nA `Nondegenerate` value represents a spline that is definitely not degenerate.\nIt is used as input to functions such as `CubicSpline3d.tangentDirection` and\ncan be constructed using `CubicSpline3d.nondegenerate`.\n\n","args":[],"cases":[]}],"aliases":[{"name":"CubicSpline3d","comment":" ","args":[],"type":"Geometry.Types.CubicSpline3d"}],"values":[{"name":"arcLength","comment":" Find the total arc length of a spline:\n\n    arcLength =\n        CubicSpline3d.arcLength parameterizedSpline\n\n    arcLength\n    --> 4.3303\n\nIn this example, the result will be accurate to within `1.0e-4` since that was\nthe tolerance used when constructing `parameterizedSpline`.\n\n","type":"CubicSpline3d.ArcLengthParameterized -> Basics.Float"},{"name":"arcLengthParameterization","comment":" ","type":"CubicSpline3d.ArcLengthParameterized -> Curve.ArcLengthParameterization.ArcLengthParameterization"},{"name":"arcLengthParameterized","comment":" Build an arc length parameterization of the given spline, with a given\naccuracy. Generally speaking, all operations on the resulting\n`ArcLengthParameterized` value will be accurate to within the specified maximum\nerror.\n\n    parameterizedSpline =\n        exampleSpline\n            |> CubicSpline3d.arcLengthParameterized\n                { maxError = 1.0e-4 }\n\n","type":"{ maxError : Basics.Float } -> CubicSpline3d.CubicSpline3d -> CubicSpline3d.ArcLengthParameterized"},{"name":"bisect","comment":" Split a spline into two roughly equal halves.\n\n    CubicSpline3d.bisect exampleSpline\n    --> ( CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, 1 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 2, 1, 1 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 2.5, 1.5, 1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 2.75, 2, 1.25 )\n    -->     }\n    --> , CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 2.75, 2, 1.25 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 2.5, 1.5 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 2 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 3 )\n    -->     }\n    --> )\n\nEquivalent to `CubicSpline3d.splitAt ParameterValue.half`.\n\n","type":"CubicSpline3d.CubicSpline3d -> ( CubicSpline3d.CubicSpline3d, CubicSpline3d.CubicSpline3d )"},{"name":"boundingBox","comment":" Compute a bounding box for a given spline. It is not guaranteed that the\nresult will be the _smallest_ possible bounding box, since for efficiency the\nbounding box is computed from the spline's control points (which cover a larger\nvolume than the spline itself).\n\n    CubicSpline3d.boundingBox exampleSpline\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 3\n    -->     , minY = 1\n    -->     , maxY = 3\n    -->     , minZ = 1\n    -->     , maxZ = 3\n    -->     }\n\n","type":"CubicSpline3d.CubicSpline3d -> BoundingBox3d.BoundingBox3d"},{"name":"endControlPoint","comment":" Get the end control point of a spline (the control point next to the\nend point).\n","type":"CubicSpline3d.CubicSpline3d -> Point3d.Point3d"},{"name":"endDerivative","comment":" Get the end derivative of a spline. This is equal to three times the vector\nfrom the spline's end control point to its end point.\n\n    CubicSpline3d.endDerivative exampleSpline\n    --> Vector3d.fromComponents ( 0, 0, 6 )\n\n","type":"CubicSpline3d.CubicSpline3d -> Vector3d.Vector3d"},{"name":"endPoint","comment":" Get the end point of a spline.\n\n    CubicSpline3d.endPoint exampleSpline\n    --> Point3d.fromCoordinates ( 3, 3, 3 )\n\n","type":"CubicSpline3d.CubicSpline3d -> Point3d.Point3d"},{"name":"firstDerivative","comment":" Get the first derivative of a spline at a given parameter value.\n\n    CubicSpline3d.derivative exampleSpline\n        ParameterValue.zero\n    --> Vector3d.fromComponents ( 6, 0, 0 )\n\n    CubicSpline3d.derivative exampleSpline\n        ParameterValue.half\n    --> Vector3d.fromComponents ( 1.5, 3, 1.5 )\n\n    CubicSpline3d.derivative exampleSpline\n        ParameterValue.one\n    --> Vector3d.fromComponents ( 0, 0, 6 )\n\n","type":"CubicSpline3d.CubicSpline3d -> Curve.ParameterValue.ParameterValue -> Vector3d.Vector3d"},{"name":"firstDerivativesAt","comment":" Evaluate the first derivative of a spline at a range of parameter values.\n\n    exampleSpline\n        |> CubicSpline3d.firstDerivativesAt\n            (ParameterValue.steps 2)\n    --> [ Vector3d.fromComponents ( 6, 0, 0 )\n    --> , Vector3d.fromComponents ( 1.5, 3, 1.5 )\n    --> , Vector3d.fromComponents ( 0, 0, 6 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline3d.CubicSpline3d -> List.List Vector3d.Vector3d"},{"name":"fromArcLengthParameterized","comment":" ","type":"CubicSpline3d.ArcLengthParameterized -> CubicSpline3d.CubicSpline3d"},{"name":"fromEndpoints","comment":" Construct a spline from a given start point with a given start derivative,\nto a given end point with a given end derivative, like so:\n\n![Cubic spline from endpoints](https://ianmackenzie.github.io/elm-geometry/1.0.0/CubicSpline2d/fromEndpoints.svg)\n\nThe spline is based on a parameter that ranges from 0 to 1; as a result, in most\ncases the length of each derivative vector should be roughly equal to the length\nof the resulting spline.\n\n","type":"{ startPoint : Point3d.Point3d, startDerivative : Vector3d.Vector3d, endPoint : Point3d.Point3d, endDerivative : Vector3d.Vector3d } -> CubicSpline3d.CubicSpline3d"},{"name":"fromNondegenerate","comment":" Convert a nondegenerate spline back to a general `CubicSpline3d`.\n\n    CubicSpline3d.fromNondegenerate\n        nondegenerateExampleSpline\n    --> exampleSpline\n\n","type":"CubicSpline3d.Nondegenerate -> CubicSpline3d.CubicSpline3d"},{"name":"fromQuadraticSpline","comment":" Convert a quadratic spline into the equivalent cubic spline (every quadratic\nspline can be represented exactly as a cubic spline).\n\n    quadraticSpline =\n        QuadraticSpline3d.with\n            { startPoint =\n                Point3d.fromCoordinates ( 0, 0, 0  )\n            , controlPoint =\n                Point3d.fromCoordinates ( 3, 0, 0 )\n            , endPoint =\n                Point3d.fromCoordinates ( 3, 3, 0 )\n            }\n\n    CubicSpline3d.fromQuadraticSpline quadraticSpline\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 0, 0, 0 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 2, 0, 0 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 1, 0 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 0 )\n    -->     )\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"maxSecondDerivativeMagnitude","comment":" Find a conservative upper bound on the magnitude of the second derivative of\na spline. This can be useful when determining error bounds for various kinds of\nlinear approximations.\n","type":"CubicSpline3d.CubicSpline3d -> Basics.Float"},{"name":"mirrorAcross","comment":" Mirror a spline across a plane.\n\n    CubicSpline3d.mirrorAcross Plane3d.xy exampleSpline\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, -1 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 1, -1 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, -1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, -3 )\n    -->     }\n\n","type":"Plane3d.Plane3d -> CubicSpline3d.CubicSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"nondegenerate","comment":" Attempt to construct a nondegenerate spline from a general `CubicSpline3d`.\nIf the spline is in fact degenerate (consists of a single point), returns an\n`Err` with that point.\n\n    CubicSpline3d.nondegenerate exampleSpline\n    --> Ok nondegenerateExampleSpline\n\n","type":"CubicSpline3d.CubicSpline3d -> Result.Result Point3d.Point3d CubicSpline3d.Nondegenerate"},{"name":"on","comment":" Construct a 3D spline lying _on_ a sketch plane by providing a 2D spline\nspecified in XY coordinates _within_ the sketch plane.\n\n    CubicSpline3d.on SketchPlane3d.xz <|\n        CubicSpline2d.with\n            { startPoint =\n                Point2d.fromCoordinates ( 1, 1 )\n            , startControlPoint =\n                Point2d.fromCoordinates ( 3, 4 )\n            , endControlPoint =\n                Point2d.fromCoordinates ( 5, 1 )\n            , endPoint =\n                Point2d.fromCoordinates ( 7, 4 )\n            }\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 0, 1 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 0, 4 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 5, 0, 1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 7, 0, 4 )\n    -->     }\n\n","type":"SketchPlane3d.SketchPlane3d -> CubicSpline2d.CubicSpline2d -> CubicSpline3d.CubicSpline3d"},{"name":"placeIn","comment":" Take a spline considered to be defined in local coordinates relative to a\ngiven reference frame, and return that spline expressed in global coordinates.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    CubicSpline3d.placeIn localFrame exampleSpline\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 2, 3, 4 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 4, 3, 4 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 4, 5, 4 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 4, 5, 6 )\n    -->     }\n\n","type":"Frame3d.Frame3d -> CubicSpline3d.CubicSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"pointAlong","comment":" Try to get the point along a spline at a given arc length. For example, to\nget the point a quarter of the way along `exampleSpline`:\n\n    CubicSpline3d.pointAlong parameterizedSpline\n        (arcLength / 4)\n    --> Just <|\n    -->     Point3d.fromCoordinates\n    -->         ( 2.0425, 1.2431, 1.0206 )\n\nNote that this is not the same as evaulating at a parameter value of 1/4:\n\n    CubicSpline3d.pointOn exampleSpline\n        (ParameterValue.clamped 0.25)\n    --> Point3d.fromCoordinates ( 2.1563, 1.3125, 1.0313 )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline, returns `Nothing`.\n\n","type":"CubicSpline3d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Point3d.Point3d"},{"name":"pointOn","comment":" Get a point at a given parameter value.\n\n    CubicSpline3d.pointOn exampleSpline ParameterValue.zero\n    --> Point3d.fromCoordinates ( 1, 1, 1 )\n\n    CubicSpline3d.pointOn exampleSpline ParameterValue.half\n    --> Point3d.fromCoordinates ( 2.75, 2, 1.25 )\n\n    CubicSpline3d.pointOn exampleSpline ParameterValue.one\n    --> Point3d.fromCoordinates ( 3, 3, 3 )\n\n","type":"CubicSpline3d.CubicSpline3d -> Curve.ParameterValue.ParameterValue -> Point3d.Point3d"},{"name":"pointsAt","comment":" Get points along a spline at a given set of parameter values.\n\n    exampleSpline\n        |> CubicSpline3d.pointsAt\n            (ParameterValue.steps 2)\n    --> [ Point3d.fromCoordinates ( 1, 1, 1 )\n    --> , Point3d.fromCoordinates ( 2.75, 2, 1.25 )\n    --> , Point3d.fromCoordinates ( 3, 3, 3 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline3d.CubicSpline3d -> List.List Point3d.Point3d"},{"name":"projectInto","comment":" Project a spline into a given sketch plane. Conceptually, this finds the\n[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof the spline onto the plane and then expresses the projected spline in 2D\nsketch coordinates.\n\n    exampleSpline\n        |> CubicSpline3d.projectInto SketchPlane3d.yz\n    --> CubicSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 1, 1 )\n    -->     , startControlPoint =\n    -->         Point2d.fromCoordinates ( 1, 1 )\n    -->     , endControlPoint =\n    -->         Point2d.fromCoordinates ( 3, 1 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 3, 3 )\n    -->     }\n\n","type":"SketchPlane3d.SketchPlane3d -> CubicSpline3d.CubicSpline3d -> CubicSpline2d.CubicSpline2d"},{"name":"projectOnto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof a spline onto a plane.\n\n    CubicSpline3d.projectOnto Plane3d.xy exampleSpline\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, 0 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 1, 0 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 0 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 0 )\n    -->     }\n\n","type":"Plane3d.Plane3d -> CubicSpline3d.CubicSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"relativeTo","comment":" Take a spline defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    CubicSpline3d.relativeTo localFrame exampleSpline\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 0, -1, -2 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 2, -1, -2 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 2, 1, -2 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 2, 1, 0 )\n    -->     }\n\n","type":"Frame3d.Frame3d -> CubicSpline3d.CubicSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"reverse","comment":" Reverse a spline so that the start point becomes the end point, and vice\nversa.\n\n    CubicSpline3d.reverse exampleSpline\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 3 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 1 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 1, 1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, 1 )\n    -->     }\n\n","type":"CubicSpline3d.CubicSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"rotateAround","comment":" Rotate a spline counterclockwise around a given axis by a given angle (in\nradians).\n\n    exampleSpline\n        |> CubicSpline3d.rotateAround Axis3d.z (degrees 90)\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( -1, 1, 1 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( -1, 3, 1 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( -3, 3, 1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( -3, 3, 3 )\n    -->     }\n\n","type":"Axis3d.Axis3d -> Basics.Float -> CubicSpline3d.CubicSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"sample","comment":" Get both the point and tangent direction of a nondegenerate spline at a\ngiven parameter value:\n\n    CubicSpline3d.sample nondegenerateExampleSpline\n        ParameterValue.half\n    --> ( Point3d.fromCoordinates ( 2.75, 2, 1.25 )\n    --> , Direction3d.fromAzimuthAndElevation\n    -->     (degrees 63.43)\n    -->     (degrees 24.09)\n    --> )\n\n","type":"CubicSpline3d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> ( Point3d.Point3d, Direction3d.Direction3d )"},{"name":"sampleAlong","comment":" Try to get the point and tangent direction along a spline at a given arc\nlength. To get the point and tangent direction a quarter of the way along\n`exampleSpline`:\n\n    CubicSpline3d.sampleAlong parameterizedSpline\n        (0.25 * arcLength)\n    --> Just\n    -->     ( Point3d.fromCoordinates\n    -->         ( 2.0425, 1.2431, 1.0206 )\n    -->     , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 29.1)\n    -->         (degrees 3.871)\n    -->     )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline (or if the spline is degenerate), returns `Nothing`.\n\n","type":"CubicSpline3d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe ( Point3d.Point3d, Direction3d.Direction3d )"},{"name":"samplesAt","comment":" Get points and tangent directions of a nondegenerate spline at a given set\nof parameter values:\n\n    nondegenerateExampleSpline\n        |> CubicSpline3d.samplesAt\n            (ParameterValue.steps 2)\n    --> [ ( Point3d.fromCoordinates ( 1, 1, 1 )\n    -->   , Direction3d.x\n    -->   )\n    --> , ( Point3d.fromCoordinates ( 2.75, 2, 1.25 )\n    -->   , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 63.43)\n    -->         (degrees 24.09)\n    -->   )\n    --> , ( Point3d.fromCoordinates ( 3, 3, 3 )\n    -->   , Direction3d.z\n    -->   )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline3d.Nondegenerate -> List.List ( Point3d.Point3d, Direction3d.Direction3d )"},{"name":"scaleAbout","comment":" Scale a spline about the given center point by the given scale.\n\n    CubicSpline3d.scaleAbout Point3d.origin 2 exampleSpline\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 2, 2, 2 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 6, 2, 2 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 6, 6, 2 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 6, 6, 6 )\n    -->     }\n\n","type":"Point3d.Point3d -> Basics.Float -> CubicSpline3d.CubicSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"secondDerivative","comment":" Get the second derivative value at a point along a spline, based on a\nparameter that ranges from 0 to 1. A parameter value of 0 corresponds to the\nstart of the spline and a value of 1 corresponds to the end.\n\n    CubicSpline3d.secondDerivative exampleSpline\n        ParameterValue.zero\n    --> Vector3d.fromComponents ( -12, 12, 0 )\n\n    CubicSpline3d.secondDerivative exampleSpline\n        ParameterValue.half\n    --> Vector3d.fromComponents ( -6, 0, 6 )\n\n    CubicSpline3d.secondDerivative exampleSpline\n        ParameterValue.one\n    --> Vector3d.fromComponents ( 0, -12, 12 )\n\n","type":"CubicSpline3d.CubicSpline3d -> Curve.ParameterValue.ParameterValue -> Vector3d.Vector3d"},{"name":"secondDerivativesAt","comment":" Evaluate the second derivative of a spline at a range of parameter values.\n\n    exampleSpline\n        |> CubicSpline3d.secondDerivativesAt\n            (ParameterValue.steps 2)\n    --> [ Vector3d.fromComponents ( -12, 12, 0 )\n    --> , Vector3d.fromComponents ( -6, 0, 6 )\n    --> , Vector3d.fromComponents ( 0, -12, 12 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline3d.CubicSpline3d -> List.List Vector3d.Vector3d"},{"name":"splitAt","comment":" Split a spline at a particular parameter value, resulting in two smaller\nsplines.\n\n    parameterValue =\n        ParameterValue.clamped 0.75\n\n    CubicSpline3d.splitAt parameterValue exampleSpline\n    --> ( CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, 1 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 2.5, 1, 1 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 2.88, 2.13, 1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 2.97, 2.69, 1.84 )\n    -->     }\n    --> , CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 2.97, 2.69, 1.84 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 2.88, 2.13 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 2.5 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 3 )\n    -->     }\n    --> )\n\n","type":"Curve.ParameterValue.ParameterValue -> CubicSpline3d.CubicSpline3d -> ( CubicSpline3d.CubicSpline3d, CubicSpline3d.CubicSpline3d )"},{"name":"startControlPoint","comment":" Get the start control point of a spline (the control point next to the\nstart point).\n","type":"CubicSpline3d.CubicSpline3d -> Point3d.Point3d"},{"name":"startDerivative","comment":" Get the start derivative of a spline. This is equal to three times the\nvector from the spline's start point to its start control point.\n\n    CubicSpline3d.startDerivative exampleSpline\n    --> Vector3d.fromComponents ( 6, 0, 0 )\n\n","type":"CubicSpline3d.CubicSpline3d -> Vector3d.Vector3d"},{"name":"startPoint","comment":" Get the start point of a spline.\n\n    CubicSpline3d.startPoint exampleSpline\n    --> Point3d.fromCoordinates ( 1, 1, 1 )\n\n","type":"CubicSpline3d.CubicSpline3d -> Point3d.Point3d"},{"name":"tangentDirection","comment":" Get the tangent direction to a nondegenerate spline at a given parameter\nvalue:\n\n    CubicSpline3d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.zero\n    --> Direction3d.x\n\n    CubicSpline3d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.half\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 63.43)\n    -->     (degrees 24.09)\n\n    CubicSpline3d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.one\n    --> Direction3d.z\n\n","type":"CubicSpline3d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> Direction3d.Direction3d"},{"name":"tangentDirectionAlong","comment":" Try to get the tangent direction along a spline at a given arc length. To\nget the tangent direction a quarter of the way along `exampleSpline`:\n\n    CubicSpline3d.tangentDirectionAlong parameterizedSpline\n        (0.25 * arcLength)\n    --> Just\n    -->     (Direction3d.fromAzimuthAndElevation\n    -->         (degrees 29.1)\n    -->         (degrees 3.871)\n    -->     )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline (or if the spline is degenerate), returns `Nothing`.\n\n","type":"CubicSpline3d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Direction3d.Direction3d"},{"name":"tangentDirectionsAt","comment":" Get tangent directions to a nondegenerate spline at a given set of parameter\nvalues:\n\n    nondegenerateExampleSpline\n        |> CubicSpline3d.tangentDirectionsAt\n            (ParameterValue.steps 2)\n    --> [ Direction3d.x\n    --> , Direction3d.fromAzimuthAndElevation\n    -->     (degrees 63.43)\n    -->     (degrees 24.09)\n    --> , Direction3d.z\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> CubicSpline3d.Nondegenerate -> List.List Direction3d.Direction3d"},{"name":"thirdDerivative","comment":" Get the third derivative of a spline (for a cubic spline, this is a\nconstant).\n","type":"CubicSpline3d.CubicSpline3d -> Vector3d.Vector3d"},{"name":"translateBy","comment":" Translate a spline by a given displacement.\n\n    displacement =\n        Vector3d.fromComponents ( 2, 3, 1 )\n\n    CubicSpline3d.translateBy displacement exampleSpline\n    --> CubicSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 3, 4, 2 )\n    -->     , startControlPoint =\n    -->         Point3d.fromCoordinates ( 5, 4, 2 )\n    -->     , endControlPoint =\n    -->         Point3d.fromCoordinates ( 5, 6, 2 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 5, 6, 4 )\n    -->     }\n\n","type":"Vector3d.Vector3d -> CubicSpline3d.CubicSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"translateIn","comment":" Translate a spline in a given direction by a given distance;\n\n    CubicSpline3d.translateIn direction distance\n\nis equivalent to\n\n    CubicSpline3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> CubicSpline3d.CubicSpline3d -> CubicSpline3d.CubicSpline3d"},{"name":"with","comment":" Construct a spline from its four control points:\n\n    exampleSpline =\n        CubicSpline3d.with\n            { startPoint =\n                Point3d.fromCoordinates ( 1, 1, 1 )\n            , startControlPoint =\n                Point3d.fromCoordinates ( 3, 1, 1 )\n            , endControlPoint =\n                Point3d.fromCoordinates ( 3, 3, 1 )\n            , endPoint =\n                Point3d.fromCoordinates ( 3, 3, 3 )\n            }\n\n","type":"{ startPoint : Point3d.Point3d, startControlPoint : Point3d.Point3d, endControlPoint : Point3d.Point3d, endPoint : Point3d.Point3d } -> CubicSpline3d.CubicSpline3d"}],"binops":[]},{"name":"Curve.ArcLengthParameterization","comment":" _You will likely never need to use this module directly._ In the vast\nmajority of cases the individual curve modules such as `QuadraticSpline2d`\nshould contain all the functionality you need to construct an arc length\nparameterization and use it to do things like evaluate a curve at evenly-spaced\npoints. This module is primarily for use internally by those curve modules, but\nmay be useful if you want to do some fancy mapping between arc length and curve\nparameter values.\n\n@docs ArcLengthParameterization\n\n\n# Constructing\n\n@docs build\n\n\n# Evaluating\n\n@docs totalArcLength, arcLengthToParameterValue, parameterValueToArcLength\n\n","unions":[{"name":"ArcLengthParameterization","comment":" Contains a mapping from curve parameter value to arc length, and vice versa.\n","args":[],"cases":[]}],"aliases":[],"values":[{"name":"arcLengthToParameterValue","comment":" Convert an arc length to the corresponding parameter value. If the given\narc length is less than zero or greater than the total arc length of the curve\n(as reported by `totalArcLength`), returns `Nothing`.\n","type":"Basics.Float -> Curve.ArcLengthParameterization.ArcLengthParameterization -> Maybe.Maybe Curve.ParameterValue.ParameterValue"},{"name":"build","comment":" Build an arc length parameterization for some curve. You must supply:\n\n  - A `derivativeMagnitude` function that returns the magnitude of the first\n    derivative of the curve at a given parameter value\n  - The maximum magnitude of the second derivative of the curve\n  - A tolerance specifying the maximum error of the resulting parameterization\n\n","type":"{ maxError : Basics.Float, derivativeMagnitude : Curve.ParameterValue.ParameterValue -> Basics.Float, maxSecondDerivativeMagnitude : Basics.Float } -> Curve.ArcLengthParameterization.ArcLengthParameterization"},{"name":"parameterValueToArcLength","comment":" Convert a parameter value to the corresponding arc length.\n","type":"Curve.ParameterValue.ParameterValue -> Curve.ArcLengthParameterization.ArcLengthParameterization -> Basics.Float"},{"name":"totalArcLength","comment":" Find the total arc length of some curve given its arc length\nparameterization;\n\n    ArcLengthParameterization.totalArcLength\n        parameterization\n\nis equivalent to\n\n    ArcLengthParameterization.parameterValueToArcLength\n        ParameterValue.one\n        parameterization\n\nbut is more efficient.\n\n","type":"Curve.ArcLengthParameterization.ArcLengthParameterization -> Basics.Float"}],"binops":[]},{"name":"Curve.ParameterValue","comment":" Curves in `elm-geometry` are [parameterized](https://en.wikipedia.org/wiki/Parametric_equation)\nby a value that ranges from 0 to 1. A value of 0 corresponds to the start point\nof the curve and a value of 1 corresponds to the end point. This module contains\nfunctionality for:\n\n  - Constructing parameter values that are guaranteed to be in the range 0 to 1\n  - Constructing ranges of evenly-spaced parameter values\n\n@docs ParameterValue\n\n\n# Constants\n\n@docs zero, half, one\n\n\n# Conversion to and from `Float` values\n\n@docs value, clamped, checked, unsafe\n\n\n# Ranges\n\n@docs steps, leading, trailing, midpoints, range\n\n\n# Arithmetic\n\n@docs midpoint, oneMinus\n\n","unions":[{"name":"ParameterValue","comment":" A parameter value between 0 and 1. Curve types such as [`Arc2d`](Arc2d) and\n[`CubicSpline3d`](CubicSpline3d) use `ParameterValue` arguments for curve\nevaluation functions such as [`Arc2d.pointOn`](Arc2d#pointOn) and\n[`CubicSpline3d.samplesAt`](CubicSpline3d#samplesAt).\n","args":[],"cases":[]}],"aliases":[],"values":[{"name":"checked","comment":" If the given value is between 0 and 1, return `Just` that value as a\n`ParameterValue`. Otherwise, return `Nothing`.\n\n    ParameterValue.checked 0.75\n        |> Maybe.map ParameterValue.value\n    --> Just 0.75\n\n    ParameterValue.checked -0.25\n    --> Nothing\n\n    ParameterValue.checked 1.25\n    --> Nothing\n\n","type":"Basics.Float -> Maybe.Maybe Curve.ParameterValue.ParameterValue"},{"name":"clamped","comment":" Construct a valid parameter value by clamping a plain `Float` value to\nbetween 0 and 1.\n\n    ParameterValue.value (ParameterValue.clamped 0.75)\n    --> 0.75\n\n    ParameterValue.value (ParameterValue.clamped -0.25)\n    --> 0\n\n    ParameterValue.value (ParameterValue.clamped 1.25)\n    --> 1\n\n","type":"Basics.Float -> Curve.ParameterValue.ParameterValue"},{"name":"half","comment":" The parameter value 0.5.\n\n    ParameterValue.value ParameterValue.half\n    --> 0.5\n\n","type":"Curve.ParameterValue.ParameterValue"},{"name":"leading","comment":" Construct a list of parameter values by dividing the range [0,1] into a\ngiven number of steps and then returning the value at the beginning of each\nstep.\n\n    ParameterValue.leading 0\n    --> []\n\n    ParameterValue.leading 1\n    --> [ ParameterValue.zero ]\n\n    Parametervalue.leading 2\n    --> [ ParameterValue.zero, ParameterValue.half ]\n\n    ParameterValue.leading 5\n        |> List.map ParameterValue.value\n    --> [ 0, 0.2, 0.4, 0.6, 0.8 ]\n\n","type":"Basics.Int -> List.List Curve.ParameterValue.ParameterValue"},{"name":"midpoint","comment":" Find the midpoint between two parameter values.\n\n    ParameterValue.midpoint\n        ParameterValue.zero\n        ParameterValue.one\n    --> ParameterValue.half\n\n","type":"Curve.ParameterValue.ParameterValue -> Curve.ParameterValue.ParameterValue -> Curve.ParameterValue.ParameterValue"},{"name":"midpoints","comment":" Construct a list of parameter values by dividing the range [0,1] into a\ngiven number of steps and then returning the value at the midpoint of each step.\n\n    ParameterValue.midpoints 0\n    --> []\n\n    ParameterValue.midpoints 1\n    --> [ ParameterValue.half ]\n\n    ParameterValue.midpoints 2\n        |> List.map ParameterValue.value\n    --> [ 0.25, 0.75 ]\n\n    ParameterValue.midpoints 5\n        |> List.map ParameterValue.value\n    --> [ 0.1, 0.3, 0.5, 0.7, 0.9 ]\n\n","type":"Basics.Int -> List.List Curve.ParameterValue.ParameterValue"},{"name":"one","comment":" The parameter value 1.\n\n    ParameterValue.value ParameterValue.one\n    --> 1\n\n","type":"Curve.ParameterValue.ParameterValue"},{"name":"oneMinus","comment":" Subtract a parameter value from 1 to give a new parameter value.\n\n    ParameterValue.oneMinus ParameterValue.one\n    --> ParameterValue.zero\n\n    ParameterValue.oneMinus ParameterValue.zero\n    --> ParameterValue.one\n\n    ParameterValue.oneMinus ParameterValue.half\n    --> ParameterValue.half\n\nThis can be thought of as the 'negation' or 'complement' of a parameter value.\nFor example, evaluating a reversed curve at a parameter value `t` is generally\nequivalent to evaluating the original curve at a parameter value\n<code>1&nbsp;-&nbsp;t</code>, and vice versa.\n\n","type":"Curve.ParameterValue.ParameterValue -> Curve.ParameterValue.ParameterValue"},{"name":"range","comment":" Construct a list of evenly-spaced parameter values between 0 and 1 by\nspecifying:\n\n  - the number of steps to take from 0 to 1\n  - whether to include the start value (0)\n  - whether to include the end value (1)\n\nThis is a more general form of `steps`, `leading` and `trailing`; for example,\n\n    ParameterValue.steps 10\n\nis equivalent to\n\n    ParameterValue.range\n        { numSteps = 10\n        , includeStart = True\n        , includeEnd = True\n        }\n\nand\n\n    ParameterValue.trailing 10\n\nis equivalent to\n\n    ParameterValue.range\n        { numSteps = 10\n        , includeStart = False\n        , includeEnd = True\n        }\n\n","type":"{ numSteps : Basics.Int, includeStart : Basics.Bool, includeEnd : Basics.Bool } -> List.List Curve.ParameterValue.ParameterValue"},{"name":"steps","comment":" Construct a list of parameter values by taking a given number of steps from\n0 to 1. Note that the number of returned values will in general be one greater\nthan the number of steps!\n\n    ParameterValue.steps 0\n    --> []\n\n    ParameterValue.steps 1\n    --> [ ParameterValue.zero, ParameterValue.one ]\n\n    Parametervalue.steps 2\n    --> [ ParameterValue.zero\n    --> , ParameterValue.half\n    --> , ParameterValue.one\n    --> ]\n\n    ParameterValue.steps 5\n        |> List.map ParameterValue.value\n    --> [ 0, 0.2, 0.4, 0.6, 0.8, 1 ]\n\n","type":"Basics.Int -> List.List Curve.ParameterValue.ParameterValue"},{"name":"trailing","comment":" Construct a list of parameter values by dividing the range [0,1] into a\ngiven number of steps and then returning the value at the end of each step.\n\n    ParameterValue.trailing 0\n    --> []\n\n    ParameterValue.trailing 1\n    --> [ ParameterValue.one ]\n\n    Parametervalue.trailing 2\n    --> [ ParameterValue.half, ParameterValue.one ]\n\n    ParameterValue.trailing 5\n        |> List.map ParameterValue.value\n    --> [ 0.2, 0.4, 0.6, 0.8, 1 ]\n\n","type":"Basics.Int -> List.List Curve.ParameterValue.ParameterValue"},{"name":"unsafe","comment":" Directly construct a `ParameterValue` from a `Float` without checking\nwhether it is valid. `ParameterValue.clamped` should generally be used instead,\nunless you are **very** sure you know what you are doing and\nprofiling/benchmarking shows that `ParameterValue.clamped` is a performance\nbottleneck.\n","type":"Basics.Float -> Curve.ParameterValue.ParameterValue"},{"name":"value","comment":" Convert a `ParameterValue` to a plain `Float` value between 0 and 1.\n\n    ParameterValue.value ParameterValue.half\n    --> 0.5\n\n","type":"Curve.ParameterValue.ParameterValue -> Basics.Float"},{"name":"zero","comment":" The parameter value 0.\n\n    ParameterValue.value ParameterValue.zero\n    --> 0\n\n","type":"Curve.ParameterValue.ParameterValue"}],"binops":[]},{"name":"DelaunayTriangulation2d","comment":" This module provides functionality for working with [Delaunay\ntriangulations](https://en.wikipedia.org/wiki/Delaunay_triangulation). You can:\n\n  - Build a Delaunay triangulation from a set of points or arbitrary vertices\n  - Add a new vertex to an existing Delaunay triangulation\n  - Extract the resulting triangulation as a list of triangles or a\n    [`TriangularMesh`](https://package.elm-lang.org/packages/ianmackenzie/elm-triangular-mesh/latest/TriangularMesh#TriangularMesh)\n\nThe current implementation is somewhat inefficient, but there are plans to speed\nit up in the future (without requiring any changes to the API).\n\n@docs DelaunayTriangulation2d, Error, Face\n\n\n# Construction\n\nConstructing a Delaunay triangulation from points/vertices is currently an\nO(n^2) operation but should be O(n log n) in the future.\n\n@docs empty\n\n@docs fromPoints, fromVerticesBy\n\n\n# Modification\n\nInserting a point into a Delaunay triangulation is currently an O(n) operation\nbut should be O(log n) in the future.\n\n@docs insertPoint, insertVertexBy\n\n\n# Properties\n\n@docs vertices, triangles, circumcircles, faces, toMesh\n\n","unions":[{"name":"Error","comment":" An error type indicating that the two given vertices have the same position.\n","args":["vertex"],"cases":[["CoincidentVertices",["vertex","vertex"]]]}],"aliases":[{"name":"DelaunayTriangulation2d","comment":" A 2D Delaunay triangulation of a set of vertices.\n","args":["vertex"],"type":"Geometry.Types.DelaunayTriangulation2d vertex"},{"name":"Face","comment":" All the details about a particular face of a Delaunay triangulation:\n\n  - The three input vertices it is formed from\n  - The `Triangle2d` defining its shape\n  - The circumcircle of that triangle\n\n","args":["vertex"],"type":"{ vertices : ( vertex, vertex, vertex ), triangle : Triangle2d.Triangle2d, circumcircle : Circle2d.Circle2d }"}],"values":[{"name":"circumcircles","comment":" Get all circumcircles in a given Delaunay triangulation;\n\n    DelaunayTriangulation2d.circumcircles triangulation\n\nis equivalent to\n\n    DelaunayTriangulation2d.faces triangulation\n        |> List.map .circumcircle\n\nbut somewhat more efficient. Complexity: O(n).\n\n","type":"DelaunayTriangulation2d.DelaunayTriangulation2d vertex -> List.List Circle2d.Circle2d"},{"name":"empty","comment":" An empty Delaunay triangulation with no vertices or faces.\n","type":"DelaunayTriangulation2d.DelaunayTriangulation2d vertex"},{"name":"faces","comment":" Get a list of all `Face`s in a given Delaunay triangulation. Complexity:\nO(n).\n","type":"DelaunayTriangulation2d.DelaunayTriangulation2d vertex -> List.List (DelaunayTriangulation2d.Face vertex)"},{"name":"fromPoints","comment":" Construct a Delaunay triangulation from an array of points. The points must\nall be distinct; if any two points are equal, you will get an `Err\nCoincidentVertices`.\n\nNote that if all points are collinear, then the resulting triangulation will\nbe empty (have no faces).\n\n","type":"Array.Array Point2d.Point2d -> Result.Result (DelaunayTriangulation2d.Error Point2d.Point2d) (DelaunayTriangulation2d.DelaunayTriangulation2d Point2d.Point2d)"},{"name":"fromVerticesBy","comment":" Construct a Delaunay triangulation from an array of vertices of arbitrary\ntype, by supplying a function that returns the position of each vertex as a\n`Point2d`. For example, if you had\n\n    types alias Vertex =\n        { position = Point2d\n        , color = String\n        }\n\nand\n\n    vertices : Array Vertex\n    vertices =\n        ...\n\nthen you would use\n\n    DelaunayTriangulation2d.fromVerticesBy .position vertices\n\nThe vertices must all be distinct; if any two have the same position, you will\nget an `Err CoincidentVertices`.\n\nNote that if all vertices are collinear, then the resulting triangulation will\nbe empty (have no faces).\n\n","type":"(vertex -> Point2d.Point2d) -> Array.Array vertex -> Result.Result (DelaunayTriangulation2d.Error vertex) (DelaunayTriangulation2d.DelaunayTriangulation2d vertex)"},{"name":"insertPoint","comment":" Add a new point into an existing Delaunay triangulation. It must not be\nequal to any existing point; if it is, you will get an `Err CoincidentVertices`.\n","type":"Point2d.Point2d -> DelaunayTriangulation2d.DelaunayTriangulation2d Point2d.Point2d -> Result.Result (DelaunayTriangulation2d.Error Point2d.Point2d) (DelaunayTriangulation2d.DelaunayTriangulation2d Point2d.Point2d)"},{"name":"insertVertexBy","comment":" Add a new vertex into an existing Delaunay triangulation, by supplying a\nfunction to get the position of the vertex. The vertex must not have the same\nposition as any existing vertex; if it is, you will get an `Err\nCoincidentVertices`.\n","type":"(vertex -> Point2d.Point2d) -> vertex -> DelaunayTriangulation2d.DelaunayTriangulation2d vertex -> Result.Result (DelaunayTriangulation2d.Error vertex) (DelaunayTriangulation2d.DelaunayTriangulation2d vertex)"},{"name":"toMesh","comment":" Convert a Delaunay triangulation to a [`TriangularMesh`](https://package.elm-lang.org/packages/ianmackenzie/elm-triangular-mesh/latest/TriangularMesh#TriangularMesh).\nComplexity: O(n).\n","type":"DelaunayTriangulation2d.DelaunayTriangulation2d vertex -> TriangularMesh.TriangularMesh vertex"},{"name":"triangles","comment":" Get all triangles in a given Delaunay triangulation;\n\n    DelaunayTriangulation2d.triangles triangulation\n\nis equivalent to\n\n    DelaunayTriangulation2d.faces triangulation\n        |> List.map .triangle\n\nbut somewhat more efficient. Complexity: O(n).\n\n","type":"DelaunayTriangulation2d.DelaunayTriangulation2d vertex -> List.List Triangle2d.Triangle2d"},{"name":"vertices","comment":" Get the vertices of a Delaunay triangulation. If the triangulation was\nconstructed by calling `fromPoints` or `fromVerticesBy`, then the returned\nvertex array will simply be the array that was passed in. If any vertices were\nadded using `insertPoint` or `insertVertexBy`, then they will be appended to\nthe end of the array. This is a simple accessor, so complexity is O(1).\n","type":"DelaunayTriangulation2d.DelaunayTriangulation2d vertex -> Array.Array vertex"}],"binops":[]},{"name":"Direction2d","comment":" A `Direction2d` represents a direction like 'up' or 'north' or 'forwards'.\nThey are represented using X and Y components, and can be converted to vectors\nif necessary, but should be thought of as conceptually different. Directions\nhave several uses, such as:\n\n  - Constructing a vector from a length and direction\n  - Determining the component of a vector in a particular direction (for\n    example, finding the component of velocity in the up direction to get\n    vertical speed)\n  - Determining the (signed) angle between two directions\n  - Defining the orientation of an axis or reference frame\n\n@docs Direction2d\n\n\n# Constants\n\n@docs x, y, positiveX, negativeX, positiveY, negativeY\n\n\n# Constructors\n\n@docs from, perpendicularTo, orthonormalize, orthogonalize, unsafe\n\n\n# Conversions\n\n@docs fromAngle, toAngle\n\n\n# Properties\n\n@docs components, xComponent, yComponent\n\n\n# Comparison\n\n@docs equalWithin\n\n\n# Measurement\n\n@docs componentIn, angleFrom\n\n\n# Conversion\n\n@docs toVector\n\n\n# Transformations\n\n@docs reverse, rotateClockwise, rotateCounterclockwise, rotateBy, mirrorAcross\n\n\n# Coordinate conversions\n\nLike other transformations, coordinate transformations of directions depend only\non the orientations of the relevant frames, not the positions of their origin\npoints.\n\nFor the examples, assume the following frames have been defined:\n\n    upsideDownFrame =\n        Frame2d\n            { originPoint = Point2d.origin\n            , xDirection = Direction2d.positiveX\n            , yDirection = Direction2d.negativeY\n            }\n\n    rotatedFrame =\n        Frame2d.atOrigin |> Frame2d.rotateBy (degrees 30)\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Direction2d","comment":" ","args":[],"type":"Geometry.Types.Direction2d"}],"values":[{"name":"angleFrom","comment":" Find the counterclockwise angle in radians from the first direction to the\nsecond. The result will be in the range -π to π.\n\n    referenceDirection =\n        Direction2d.fromAngle (degrees 30)\n\n    Direction2d.angleFrom referenceDirection Direction2d.y\n    --> degrees 60\n\n    Direction2d.angleFrom referenceDirection Direction2d.x\n    --> degrees -30\n\n","type":"Direction2d.Direction2d -> Direction2d.Direction2d -> Basics.Float"},{"name":"componentIn","comment":" Find the component of one direction in another direction. This is equal to\nthe cosine of the angle between the directions, or equivalently the dot product\nof the two directions converted to unit vectors.\n\n    direction =\n        Direction2d.fromAngle (degrees 60)\n\n    Direction2d.componentIn Direction2d.x direction\n    --> 0.5\n\n    Direction2d.componentIn direction direction\n    --> 1\n\n    Direction2d.componentIn Direction2d.x Direction2d.y\n    --> 0\n\nThis is more general and flexible than using `xComponent` or `yComponent`, both\nof which can be expressed in terms of `componentIn`; for example,\n\n    Direction2d.xComponent direction\n\nis equivalent to\n\n    Direction2d.componentIn Direction2d.x direction\n\n","type":"Direction2d.Direction2d -> Direction2d.Direction2d -> Basics.Float"},{"name":"components","comment":" Get the components of a direction as a tuple (the components it would have\nas a unit vector, also know as its direction cosines).\n\n    ( x, y ) =\n        Direction2d.components direction\n\n","type":"Direction2d.Direction2d -> ( Basics.Float, Basics.Float )"},{"name":"equalWithin","comment":" Compare two directions within an angular tolerance. Returns true if the\nabsolute value of the angle between the two given directions is less than the\ngiven tolerance.\n\n    firstDirection =\n        Direction2d.fromAngle (degrees 45)\n\n    secondDirection =\n        Direction2d.fromAngle (degrees 47)\n\n    Direction2d.equalWithin (degrees 5)\n        firstDirection\n        secondDirection\n    --> True\n\n    Direction2d.equalWithin (degrees 1)\n        firstDirection\n        secondDirection\n    --> False\n\n","type":"Basics.Float -> Direction2d.Direction2d -> Direction2d.Direction2d -> Basics.Bool"},{"name":"from","comment":" Attempt to construct the direction from the first given point to the second.\nIf the two points are coincident, returns `Nothing`.\n\n    point =\n        Point2d.fromCoordinates ( 1, 1 )\n\n    Direction2d.from Point2d.origin point\n    --> Just (Direction2d.fromAngle (degrees 45))\n\n    Direction2d.from point Point2d.origin\n    --> Just (Direction2d.fromAngle (degrees -135))\n\n    Direction2d.from point point\n    --> Nothing\n\n","type":"Geometry.Types.Point2d -> Geometry.Types.Point2d -> Maybe.Maybe Direction2d.Direction2d"},{"name":"fromAngle","comment":" Construct a direction from an angle in radians, given counterclockwise from\nthe positive X direction.\n\n    Direction2d.fromAngle 0\n    --> Direction2d.x\n\n    Direction2d.fromAngle (degrees 90)\n    --> Direction2d.y\n\n    Direction2d.fromAngle (degrees -90)\n    --> Direction2d.negativeY\n\n","type":"Basics.Float -> Direction2d.Direction2d"},{"name":"mirrorAcross","comment":" Mirror a direction across a particular axis. Note that only the direction of\nthe axis affects the result, since directions are position-independent.\n\n    slopedAxis =\n        Axis2d.through\n            (Point2d.fromCoordinates ( 100, 200 ))\n            (Direction2d.fromAngle (degrees 45))\n\n    Direction2d.mirrorAcross slopedAxis Direction2d.x\n    --> Direction2d.y\n\n    Direction2d.mirrorAcross slopedAxis Direction2d.y\n    --> Direction2d.x\n\n","type":"Geometry.Types.Axis2d -> Direction2d.Direction2d -> Direction2d.Direction2d"},{"name":"negativeX","comment":" The negative X direction.\n\n    Direction2d.components Direction2d.negativeX\n    --> ( -1, 0 )\n\n","type":"Direction2d.Direction2d"},{"name":"negativeY","comment":" The negative Y direction.\n\n    Direction2d.components Direction2d.negativeY\n    --> ( 0, -1 )\n\n","type":"Direction2d.Direction2d"},{"name":"orthogonalize","comment":" Attempt to form a pair of perpendicular directions from the two given\ndirections;\n\n    Direction2d.orthogonalize xDirection yDirection\n\nis equivalent to\n\n    Direction2d.orthonormalize\n        (Direction2d.toVector xDirection)\n        (Direction2d.toVector yDirection)\n\n","type":"Direction2d.Direction2d -> Direction2d.Direction2d -> Maybe.Maybe ( Direction2d.Direction2d, Direction2d.Direction2d )"},{"name":"orthonormalize","comment":" Attempt to form a pair of perpendicular directions from the two given\nvectors by performing [Gram-Schmidt normalization](https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process):\n\n  - The first returned direction will be equal to the direction of the first\n    given vector\n  - The second returned direction will be as close as possible to the second\n    given vector while being perpendicular to the first returned direction\n\nIf either of the given vectors are zero, or if the two vectors are parallel,\nreturns `Nothing`.\n\n    Direction2d.orthonormalize\n        (Vector2d.fromComponents ( 3, 3 ))\n        (Vector2d.fromComponents ( 0, -2 ))\n    --> Just\n    -->     ( Direction2d.fromAngle (degrees 45)\n    -->     , Direction2d.fromAngle (degrees -45)\n    -->     )\n\n    Direction2d.orthonormalize\n        (Vector2d.fromComponents ( 3, 3 ))\n        (Vector2d.fromComponents ( -2, -2 ))\n    --> Nothing\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d -> Maybe.Maybe ( Direction2d.Direction2d, Direction2d.Direction2d )"},{"name":"perpendicularTo","comment":" Construct a direction perpendicular to the given direction, by rotating the\ngiven direction 90 degrees counterclockwise. Synonym for\n`rotateCounterclockwise`.\n\n    Direction2d.perpendicularTo Direction2d.x\n    --> Direction2d.y\n\n    Direction2d.perpendicularTo Direction2d.y\n    --> Direction2d.negativeX\n\n","type":"Direction2d.Direction2d -> Direction2d.Direction2d"},{"name":"placeIn","comment":" Take a direction defined in local coordinates relative to a given reference\nframe, and return that direction expressed in global coordinates.\n\n    Direction2d.placeIn upsideDownFrame Direction2d.y\n    --> Direction2d.negativeY\n\n    Direction2d.placeIn rotatedFrame Direction2d.x\n    --> Direction2d.fromAngle (degrees 30)\n\n    Direction2d.placeIn rotatedFrame Direction2d.y\n    --> Direction2d.fromAngle (degrees 120)\n\n","type":"Geometry.Types.Frame2d -> Direction2d.Direction2d -> Direction2d.Direction2d"},{"name":"positiveX","comment":" The positive X direction.\n\n    Direction2d.components Direction2d.positiveX\n    --> ( 1, 0 )\n\n","type":"Direction2d.Direction2d"},{"name":"positiveY","comment":" The positive Y direction.\n\n    Direction2d.components Direction2d.positiveY\n    --> ( 0, 1 )\n\n","type":"Direction2d.Direction2d"},{"name":"relativeTo","comment":" Take a direction defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    Direction2d.relativeTo upsideDownFrame Direction2d.y\n    --> Direction2d.negativeY\n\n    Direction2d.relativeTo rotatedFrame Direction2d.x\n    --> Direction2d.fromAngle (degrees -30)\n\n    Direction2d.relativeTo rotatedFrame Direction2d.y\n    --> Direction2d.fromAngle (degrees 60)\n\n","type":"Geometry.Types.Frame2d -> Direction2d.Direction2d -> Direction2d.Direction2d"},{"name":"reverse","comment":" Reverse a direction.\n\n    Direction2d.reverse Direction2d.y\n    --> Direction2d.negativeY\n\n","type":"Direction2d.Direction2d -> Direction2d.Direction2d"},{"name":"rotateBy","comment":" Rotate a direction counterclockwise by a given angle (in radians).\n\n    Direction2d.rotateBy pi Direction2d.x\n    --> Direction2d.negativeX\n\n    Direction2d.rotateBy (degrees 45) Direction2d.y\n    --> Direction2d.fromAngle (degrees 135)\n\n","type":"Basics.Float -> Direction2d.Direction2d -> Direction2d.Direction2d"},{"name":"rotateClockwise","comment":" Rotate a direction by 90 degrees clockwise.\n\n    Direction2d.rotateClockwise Direction2d.y\n    --> Direction2d.x\n\n    Direction2d.rotateClockwise Direction2d.x\n    --> Direction2d.negativeY\n\n","type":"Direction2d.Direction2d -> Direction2d.Direction2d"},{"name":"rotateCounterclockwise","comment":" Rotate a direction by 90 degrees counterclockwise.\n\n    Direction2d.rotateClockwise Direction2d.x\n    --> Direction2d.y\n\n    Direction2d.rotateClockwise Direction2d.y\n    --> Direction2d.negativeX\n\n","type":"Direction2d.Direction2d -> Direction2d.Direction2d"},{"name":"toAngle","comment":" Convert a direction to a polar angle (the counterclockwise angle in radians\nfrom the positive X direction). The result will be in the range -π to π.\n\n    Direction2d.toAngle Direction2d.x\n    --> 0\n\n    Direction2d.toAngle Direction2d.y\n    --> degrees 90\n\n    Direction2d.toAngle Direction2d.negativeY\n    --> degrees -90\n\n","type":"Direction2d.Direction2d -> Basics.Float"},{"name":"toVector","comment":" Convert a direction to a unit vector.\n\n    Direction2d.toVector Direction2d.x\n    --> Vector2d.fromComponents ( 1, 0 )\n\n","type":"Direction2d.Direction2d -> Vector2d.Vector2d"},{"name":"unsafe","comment":" Construct a direction directly from its X and Y components. Note that **you\nmust ensure that the sum of the squares of the given components is exactly\none**:\n\n    Direction2d.unsafe ( 1, 0 )\n\n    Direction2d.unsafe ( 0, -1 )\n\n    Direction2d.unsafe ( 0.6, 0.8 )\n\nare all valid but\n\n    Direction2d.unsafe ( 2, 0 )\n\n    Direction2d.unsafe ( 1, 1 )\n\nare not. Instead of using `Direction2d.unsafe`, it may be easier to use\nconstructors like `Direction2d.fromAngle` (which will always result in a valid\ndirection) or start with existing directions and transform them as necessary.\n\n","type":"( Basics.Float, Basics.Float ) -> Direction2d.Direction2d"},{"name":"x","comment":" Synonym for `Direction2d.positiveX`.\n","type":"Direction2d.Direction2d"},{"name":"xComponent","comment":" Get the X component of a direction.\n\n    Direction2d.xComponent Direction2d.x\n    --> 1\n\n    Direction2d.xComponent Direction2d.y\n    --> 0\n\n","type":"Direction2d.Direction2d -> Basics.Float"},{"name":"y","comment":" Synonym for `Direction2d.positiveY`.\n","type":"Direction2d.Direction2d"},{"name":"yComponent","comment":" Get the Y component of a direction.\n\n    Direction2d.yComponent Direction2d.x\n    --> 0\n\n    Direction2d.yComponent Direction2d.y\n    --> 1\n\n","type":"Direction2d.Direction2d -> Basics.Float"}],"binops":[]},{"name":"Direction3d","comment":" A `Direction3d` represents a direction like 'up' or 'north' or 'forwards'.\nThey are represented using X, Y and Z components, and can be converted to\nvectors if necessary, but should be thought of as conceptually different.\nDirections have several uses, such as:\n\n  - Constructing a vector from a length and direction\n  - Determining the component of a vector in a particular direction (for\n    example, finding the component of velocity in the up direction to get\n    vertical speed)\n  - Determining the angle between two directions\n  - Defining the orientation of an axis, plane or reference frame\n\n@docs Direction3d\n\n\n# Constants\n\n@docs x, y, z, positiveX, negativeX, positiveY, negativeY, positiveZ, negativeZ\n\n\n# Constructors\n\n@docs from, on, fromAzimuthAndElevation, perpendicularTo, perpendicularBasis, orthonormalize, orthogonalize, unsafe\n\n\n# Properties\n\n@docs components, xComponent, yComponent, zComponent, azimuth, elevation\n\n\n# Comparison\n\n@docs equalWithin\n\n\n# Measurement\n\n@docs componentIn, angleFrom\n\n\n# Conversion\n\n@docs toVector\n\n\n# Transformations\n\n@docs reverse, rotateAround, mirrorAcross, projectOnto\n\n\n# Coordinate conversions\n\nLike other transformations, coordinate transformations of directions depend only\non the orientations of the relevant frames, not their positions.\n\nFor the examples, assume the following definition of a local coordinate frame,\none that is rotated 30 degrees counterclockwise around the Z axis from the\nglobal XYZ frame:\n\n    rotatedFrame =\n        Frame3d.atOrigin\n            |> Frame3d.rotateAround Axis3d.z (degrees 30)\n\n@docs relativeTo, placeIn, projectInto\n\n","unions":[],"aliases":[{"name":"Direction3d","comment":" ","args":[],"type":"Geometry.Types.Direction3d"}],"values":[{"name":"angleFrom","comment":" Find the angle from one direction to another. The result will be in the\nrange 0 to π.\n\n    Direction3d.angleFrom Direction3d.x Direction3d.x\n    --> degrees 0\n\n    Direction3d.angleFrom Direction3d.x Direction3d.z\n    --> degrees 90\n\n    Direction3d.angleFrom\n        Direction3d.y\n        Direction3d.negativeY\n    --> degrees 180\n\n","type":"Direction3d.Direction3d -> Direction3d.Direction3d -> Basics.Float"},{"name":"azimuth","comment":" Get the angle of a direction in the XY plane, measured from the X axis\ntowards the Y axis (counterclockwise around the Z axis). The result will be in\nthe range -π to π.\n\n    Direction3d.azimuth Direction3d.x\n    --> 0\n\n    Direction3d.azimuth Direction3d.y\n    --> degrees 90\n\n    Direction3d.azimuth Direction3d.negativeY\n    --> degrees -90\n\n    Direction3d.azimuth Direction3d.negativeX\n    --> degrees 180\n\nVertical directions are considered to have an azimuth of zero:\n\n    Direction3d.azimuth Direction3d.z\n    --> 0\n\n","type":"Direction3d.Direction3d -> Basics.Float"},{"name":"componentIn","comment":" Find the component of one direction in another direction. This is equal to\nthe cosine of the angle between the directions, or equivalently the dot product\nof the two directions converted to unit vectors.\n\n    direction =\n        Direction3d.fromAzimuthAndElevation\n            (degrees 0)\n            (degrees 60)\n\n    Direction3d.componentIn Direction3d.x direction\n    --> 0.5\n\n    Direction3d.componentIn Direction3d.z direction\n    --> 0.866\n\n    Direction3d.componentIn direction direction\n    --> 1\n\n    direction\n        |> Direction3d.componentIn\n            (Direction3d.reverse direction)\n    --> -1\n\nThis is more general and flexible than using `xComponent`, `yComponent` or\n`zComponent`, all of which can be expressed in terms of `componentIn`; for\nexample,\n\n    Direction3d.zComponent direction\n\nis equivalent to\n\n    Direction3d.componentIn Direction3d.z direction\n\n","type":"Direction3d.Direction3d -> Direction3d.Direction3d -> Basics.Float"},{"name":"components","comment":" Get the components of a direction as a tuple (the components it would have\nas a unit vector, also know as its direction cosines).\n\n    ( x, y, z ) =\n        Direction3d.components direction\n\n","type":"Direction3d.Direction3d -> ( Basics.Float, Basics.Float, Basics.Float )"},{"name":"elevation","comment":" Get the angle of a direction from the XY plane towards positive Z. The\nresult will be in the range -π/2 to π/2.\n\n    Direction3d.elevation Direction3d.x\n    --> 0\n\n    Direction3d.elevation Direction3d.negativeY\n    --> 0\n\n    Direction3d.elevation Direction3d.z\n    --> degrees 90\n\n    Direction3d.elevation Direction3d.negativeZ\n    --> degrees -90\n\n","type":"Direction3d.Direction3d -> Basics.Float"},{"name":"equalWithin","comment":" Compare two directions within an angular tolerance. Returns true if the\nangle between the two given directions is less than the given tolerance.\n\n    rotatedDirection =\n        Direction3d.x\n            |> Direction3d.rotateAround Axis3d.z\n                (degrees 2)\n\n    Direction3d.equalWithin (degrees 5)\n        Direction3d.x\n        rotatedDirection\n    --> True\n\n    Direction3d.equalWithin (degrees 1)\n        Direction3d.x\n        rotatedDirection\n    --> False\n\n","type":"Basics.Float -> Direction3d.Direction3d -> Direction3d.Direction3d -> Basics.Bool"},{"name":"from","comment":" Attempt to construct the direction from the first given point to the second.\nIf the two points are coincident, returns `Nothing`.\n\n    point =\n        Point3d.fromCoordinates ( 1, 0, 1 )\n\n    Direction3d.from Point3d.origin point\n    --> Just\n    -->     (Direction3d.fromAzimuthAndElevation\n    -->         (degrees 0)\n    -->         (degrees 45)\n    -->     )\n\n    Direction3d.from point Point3d.origin\n    --> Just\n    -->     (Direction3d.fromAzimuthAndElevation\n    -->         (degrees 180)\n    -->         (degrees -45)\n    -->     )\n\n    Direction3d.from point point\n    --> Nothing\n\n","type":"Geometry.Types.Point3d -> Geometry.Types.Point3d -> Maybe.Maybe Direction3d.Direction3d"},{"name":"fromAzimuthAndElevation","comment":" Construct a direction using azimuthal and elevation angles relative to the\nglobal XYZ frame. The azimuth defines the direction's polar angle on the global\nXY plane (from X towards Y) and the elevation defines its angle out of the XY\nplane towards positive Z.\n\n    Direction3d.components\n        (Direction3d.fromAzimuthAndElevation\n            (degrees 45)\n            (degrees 45)\n        )\n    --> ( 0.5, 0.5, 0.7071 )\n\n","type":"Basics.Float -> Basics.Float -> Direction3d.Direction3d"},{"name":"mirrorAcross","comment":" Mirror a direction across a plane.\n\n    direction =\n        Direction3d.fromAzimuthAndElevation\n            (degrees 30)\n            (degrees 60)\n\n    Direction3d.mirrorAcross Plane3d.xy direction\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 30)\n    -->     (degrees -60)\n\nNote that only the normal direction of the plane affects the result, not the\nposition of its origin point, since directions are position-independent:\n\n    Direction3d.mirrorAcross Plane3d.yz direction\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 150)\n    -->     (degrees 60)\n\n    offsetPlane =\n        Plane3d.offsetBy 10 Plane3d.yz\n\n    Direction3d.mirrorAcross offsetPlane direction\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 150)\n    -->     (degrees 60)\n\n","type":"Geometry.Types.Plane3d -> Direction3d.Direction3d -> Direction3d.Direction3d"},{"name":"negativeX","comment":" The negative X direction.\n\n    Direction3d.components Direction3d.negativeX\n    --> ( -1, 0, 0 )\n\n","type":"Direction3d.Direction3d"},{"name":"negativeY","comment":" The negative Y direction.\n\n    Direction3d.components Direction3d.negativeY\n    --> ( 0, -1, 0 )\n\n","type":"Direction3d.Direction3d"},{"name":"negativeZ","comment":" The negative Z direction.\n\n    Direction3d.components Direction3d.negativeZ\n    --> ( 0, 0, -1 )\n\n","type":"Direction3d.Direction3d"},{"name":"on","comment":" Construct a 3D direction lying _on_ a sketch plane by providing a 2D\ndirection specified in XY coordinates _within_ the sketch plane.\n\n    horizontalDirection =\n        Direction3d.on SketchPlane3d.xy <|\n            Direction2d.fromAngle (degrees 45)\n\n    Direction3d.components horizontalDirection\n    --> ( 0.7071, 0.7071, 0 )\n\n    thirtyDegreesFromZ =\n        Direction3d.on SketchPlane3d.zx <|\n            Direction2d.fromAngle (degrees 30)\n\n    Direction3d.components thirtyDegreesFromZ\n    --> ( 0.5, 0, 0.866 )\n\n","type":"Geometry.Types.SketchPlane3d -> Direction2d.Direction2d -> Direction3d.Direction3d"},{"name":"orthogonalize","comment":" Attempt to form a set of three mutually perpendicular directions from the\nthree given directions;\n\n    Direction3d.orthogonalize\n        xDirection\n        yDirection\n        zDirection\n\nis equivalent to\n\n    Direction3d.orthonormalize\n        (Direction3d.toVector xDirection)\n        (Direction3d.toVector yDirection)\n        (Direction3d.toVector zDirection)\n\n","type":"Direction3d.Direction3d -> Direction3d.Direction3d -> Direction3d.Direction3d -> Maybe.Maybe ( Direction3d.Direction3d, Direction3d.Direction3d, Direction3d.Direction3d )"},{"name":"orthonormalize","comment":" Attempt to form a set of three mutually perpendicular directions from the\nthree given vectors by performing [Gram-Schmidt normalization](https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process):\n\n  - The first returned direction will be equal to the direction of the first\n    given vector\n  - The second returned direction will be as close as possible to the second\n    given vector while being perpendicular to the first returned direction\n  - The third returned direction will be as close as possible to the third given\n    vector while being perpendicular to the first and second returned directions\n\nIf any of the given vectors are zero, any two of them are parallel, or the three\nare coplanar, returns `Nothing`.\n\n    Direction3d.orthonormalize\n        (Vector3d.fromComponents ( 3, 3, 0 ))\n        (Vector3d.fromComponents ( 0, 2, 0 ))\n        (Vector3d.fromComponents ( 1, 2, 3 ))\n    --> Just\n    -->     ( Direction3d.fromAzimuthAndElevation\n    -->         (degrees 45)\n    -->         (degrees 0)\n    -->     , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 135)\n    -->         (degrees 0)\n    -->     , Direction3d.positiveZ\n    -->     )\n\n    -- Three vectors in the XY plane:\n    Direction3d.orthonormalize\n        (Vector3d.fromComponents ( 2, 0, 0 ))\n        (Vector3d.fromComponents ( 3, 1, 0 ))\n        (Vector3d.fromComponents ( 4, 2, 0 ))\n    --> Nothing\n\n","type":"Vector3d.Vector3d -> Vector3d.Vector3d -> Vector3d.Vector3d -> Maybe.Maybe ( Direction3d.Direction3d, Direction3d.Direction3d, Direction3d.Direction3d )"},{"name":"perpendicularBasis","comment":" Construct a pair of directions that are perpendicular to each other and both\nperpendicular to the given direction.\n\nThe given direction and the two returned directions will form a\n[right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\nsystem (that is, a right-handed `Frame3d` could be constructed by using the\ngiven direction as the X direction and the two returned directions as the Y and\nZ directions, or the given direction as the Z direction and the two returned\ndirections as the X and Y directions).\n\n    Direction3d.perpendicularBasis Direction3d.x\n    --> ( Direction3d.negativeZ\n    --> , Direction3d.positiveY\n    --> )\n\n    Direction3d.perpendicularBasis Direction3d.y\n    --> ( Direction3d.positiveZ\n    --> , Direction3d.positiveX\n    --> )\n\n","type":"Direction3d.Direction3d -> ( Direction3d.Direction3d, Direction3d.Direction3d )"},{"name":"perpendicularTo","comment":" Construct an arbitrary direction perpendicular to the given direction. The\nexact resulting direction is not specified, but it is guaranteed to be\nperpendicular to the given direction.\n\n    Direction3d.perpendicularTo Direction3d.x\n    --> Direction3d.negativeZ\n\n    Direction3d.perpendicularTo Direction3d.y\n    --> Direction3d.positiveZ\n\n    direction =\n        Direction3d.fromAzimuthAndElevation\n            (degrees 0)\n            (degrees 60)\n\n    Direction3d.perpendicularTo direction\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 0)\n    -->     (degrees -30)\n\n","type":"Direction3d.Direction3d -> Direction3d.Direction3d"},{"name":"placeIn","comment":" Take a direction defined in local coordinates relative to a given reference\nframe, and return that direction expressed in global coordinates.\n\n    Direction3d.placeIn rotatedFrame Direction3d.x\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 30)\n    -->     (degrees 0)\n\n    Direction3d.placeIn rotatedFrame Direction3d.y\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 120)\n    -->     (degrees 0)\n\n    Direction3d.placeIn rotatedFrame Direction3d.z\n    --> Direction3d.z\n\n","type":"Geometry.Types.Frame3d -> Direction3d.Direction3d -> Direction3d.Direction3d"},{"name":"positiveX","comment":" The positive X direction.\n\n    Direction3d.components Direction3d.positiveX\n    --> ( 1, 0, 0 )\n\n","type":"Direction3d.Direction3d"},{"name":"positiveY","comment":" The positive Y direction.\n\n    Direction3d.components Direction3d.positiveY\n    --> ( 0, 1, 0 )\n\n","type":"Direction3d.Direction3d"},{"name":"positiveZ","comment":" The positive Z direction.\n\n    Direction3d.components Direction3d.positiveZ\n    --> ( 0, 0, 1 )\n\n","type":"Direction3d.Direction3d"},{"name":"projectInto","comment":" Project a direction into a given sketch plane. Conceptually, this finds the\n[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof the direction onto the plane, re-normalizes it to have unit length, and then\nexpresses the projected direction in 2D sketch coordinates.\n\nThis is only possible if the direction is not perpendicular to the sketch\nplane; if it is perpendicular, `Nothing` is returned.\n\n    direction =\n        Direction3d.fromAzimuthAndElevation\n            (degrees -60)\n            (degrees 0)\n\n    Direction3d.projectInto SketchPlane3d.xy direction\n    --> Just (Direction2d.fromAngle (degrees -60))\n\n    Direction3d.projectInto SketchPlane3d.xz direction\n    --> Just Direction2d.x\n\n    Direction3d.projectInto SketchPlane3d.yz direction\n    --> Just Direction2d.negativeX\n\n    Direction3d.projectInto SketchPlane3d.xy Direction3d.z\n    --> Nothing\n\n","type":"Geometry.Types.SketchPlane3d -> Direction3d.Direction3d -> Maybe.Maybe Direction2d.Direction2d"},{"name":"projectOnto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof a direction onto a plane (renormalized to have unit length). If the given\ndirection is exactly perpendicular to the given plane, returns `Nothing`.\n\n    direction =\n        Direction3d.fromAzimuthAndElevation\n            (degrees -60)\n            (degrees 0)\n\n    Direction3d.projectOnto Plane3d.xy direction\n    --> Just direction\n\n    Direction3d.projectOnto Plane3d.xz direction\n    --> Just Direction3d.x\n\n    Direction3d.projectOnto Plane3d.yz direction\n    --> Just Direction3d.negativeY\n\n    Direction3d.projectOnto Plane3d.xy Direction3d.z\n    --> Nothing\n\n","type":"Geometry.Types.Plane3d -> Direction3d.Direction3d -> Maybe.Maybe Direction3d.Direction3d"},{"name":"relativeTo","comment":" Take a direction defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    Direction3d.relativeTo rotatedFrame Direction3d.x\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees -30)\n    -->     (degrees 0)\n\n    Direction3d.relativeTo rotatedFrame Direction3d.y\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 60)\n    -->     (degrees 0)\n\n    Direction3d.relativeTo rotatedFrame Direction3d.z\n    --> Direction3d.z\n\n","type":"Geometry.Types.Frame3d -> Direction3d.Direction3d -> Direction3d.Direction3d"},{"name":"reverse","comment":" Reverse a direction.\n\n    Direction3d.reverse Direction3d.y\n    --> Direction3d.negativeY\n\n","type":"Direction3d.Direction3d -> Direction3d.Direction3d"},{"name":"rotateAround","comment":" Rotate a direction around an axis by a given angle.\n\n    Direction3d.y\n        |> Direction3d.rotateAround Axis3d.x (degrees 90)\n    --> Direction3d.z\n\nNote that only the direction of the axis affects the result, not the position of\nits origin point, since directions are position-independent:\n\n    offsetAxis =\n        Axis3d.withDirection Direction3d.z\n            (Point3d.fromCoordinates ( 100, 200, 300 ))\n\n    Direction3d.x\n        |> Direction3d.rotateAround offsetAxis (degrees 90)\n    --> Direction3d.y\n\n","type":"Geometry.Types.Axis3d -> Basics.Float -> Direction3d.Direction3d -> Direction3d.Direction3d"},{"name":"toVector","comment":" Convert a direction to a unit vector.\n\n    Direction3d.toVector Direction3d.y\n    --> Vector3d.fromComponents ( 0, 1, 0 )\n\n","type":"Direction3d.Direction3d -> Vector3d.Vector3d"},{"name":"unsafe","comment":" Construct a direction directly from its X, Y and Z components. Note that\n**you must ensure that the sum of the squares of the given components is exactly\none**:\n\n    Direction3d.unsafe ( 1, 0, 0 )\n\n    Direction3d.unsafe ( 0, -1, 0 )\n\n    Direction3d.unsafe ( 0.6, 0, 0.8 )\n\nare all valid but\n\n    Direction3d.unsafe ( 2, 0, 0 )\n\n    Direction3d.unsafe ( 1, 1, 1 )\n\nare not. Instead of using `Direction3d.unsafe`, it may be easier to use\nconstructors like `Direction3d.on` or `Direction3d.fromAzimuthAndElevation`\n(which will always result in a valid direction), or start with existing\ndirections and transform them as necessary.\n\n","type":"( Basics.Float, Basics.Float, Basics.Float ) -> Direction3d.Direction3d"},{"name":"x","comment":" Synonym for `Direction3d.positiveX`.\n","type":"Direction3d.Direction3d"},{"name":"xComponent","comment":" Get the X component of a direction.\n\n    Direction3d.xComponent Direction3d.x\n    --> 1\n\n    Direction3d.xComponent Direction3d.y\n    --> 0\n\n","type":"Direction3d.Direction3d -> Basics.Float"},{"name":"y","comment":" Synonym for `Direction3d.positiveY`.\n","type":"Direction3d.Direction3d"},{"name":"yComponent","comment":" Get the Y component of a direction.\n\n    Direction3d.yComponent Direction3d.y\n    --> 1\n\n    Direction3d.yComponent Direction3d.z\n    --> 0\n\n","type":"Direction3d.Direction3d -> Basics.Float"},{"name":"z","comment":" Synonym for `Direction3d.positiveZ`.\n","type":"Direction3d.Direction3d"},{"name":"zComponent","comment":" Get the Z component of a direction.\n\n    Direction3d.zComponent Direction3d.z\n    --> 1\n\n    Direction3d.zComponent Direction3d.x\n    --> 0\n\n","type":"Direction3d.Direction3d -> Basics.Float"}],"binops":[]},{"name":"Ellipse2d","comment":" An [ellipse](https://en.wikipedia.org/wiki/Ellipse) is defined by a center\npoint, X and Y radius, and X and Y axes (which will always be perpendicular to\neach other). Ellipses are symmetric about their X and Y axes. This module\nincludes functionality for\n\n  - Constructing ellipses\n  - Scaling, rotating and translating ellipses\n  - Converting ellipses between different coordinate systems\n\n@docs Ellipse2d\n\n\n# Constructors\n\n@docs with\n\n\n# Properties\n\n@docs centerPoint, xAxis, yAxis, xDirection, yDirection, axes, xRadius, yRadius, area\n\n\n# Transformations\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Ellipse2d","comment":" ","args":[],"type":"Geometry.Types.Ellipse2d"}],"values":[{"name":"area","comment":" Get the area of an ellipse.\n\n    Ellipse2d.area exampleEllipse\n    --> 47.1239\n\n","type":"Ellipse2d.Ellipse2d -> Basics.Float"},{"name":"axes","comment":" Get the X and Y axes of an ellipse as a `Frame2d`.\n\n    Ellipse2d.axes exampleEllipse\n    --> Frame2d.withXDirection\n    -->     (Direction2d.fromAngle (degrees 30))\n    -->     (Point2d.fromCoordinates ( 10, 10 ))\n\n","type":"Ellipse2d.Ellipse2d -> Frame2d.Frame2d"},{"name":"centerPoint","comment":" Get the center point of an ellipse.\n\n    Ellipse2d.centerPoint exampleEllipse\n    --> Point2d.fromCoordinates ( 10, 10 )\n\n","type":"Ellipse2d.Ellipse2d -> Point2d.Point2d"},{"name":"mirrorAcross","comment":" Mirror an ellipse across a given axis.\n\n    mirroredEllipse =\n        Ellipse2d.mirrorAcross Axis2d.x exampleEllipse\n\n    Ellipse2d.centerPoint mirroredEllipse\n    --> Point2d.fromCoordinates ( 10, -10 )\n\n    Ellipse2d.xDirection mirroredEllipse\n    --> Direction2d.fromAngle (degrees -30)\n\n    Ellipse2d.yDirection mirroredEllipse\n    --> Direction2d.fromAngle (degrees -120)\n\nNote that if the axes of the original ellipse form a [right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\nframe, then the axes of the mirrored ellipse will form a left-handed frame (and\nvice versa).\n\n","type":"Axis2d.Axis2d -> Ellipse2d.Ellipse2d -> Ellipse2d.Ellipse2d"},{"name":"placeIn","comment":" Take an ellipse considered to be defined in local coordinates relative to a\ngiven reference frame, and return that circle expressed in global coordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates (15, 5))\n\n    Ellipse2d.placeIn localFrame exampleEllipse\n    --> Ellipse2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( 25, 15 )\n    -->     , xDirection =\n    -->         Direction2d.fromAngle (degrees 30)\n    -->     , xRadius = 5\n    -->     , yRadius = 3\n    -->     }\n\n","type":"Frame2d.Frame2d -> Ellipse2d.Ellipse2d -> Ellipse2d.Ellipse2d"},{"name":"relativeTo","comment":" Take an ellipse defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates (15, 5))\n\n    Ellipse2d.relativeTo localFrame exampleEllipse\n    --> Ellipse2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( -5, 5 )\n    -->     , xDirection =\n    -->         Direction2d.fromAngle (degrees 30)\n    -->     , xRadius = 5\n    -->     , yRadius = 3\n    -->     }\n\n","type":"Frame2d.Frame2d -> Ellipse2d.Ellipse2d -> Ellipse2d.Ellipse2d"},{"name":"rotateAround","comment":" Rotate an ellipse around a given point by a given angle (in radians).\n\n    exampleEllipse\n        |> Ellipse2d.rotateAround Point2d.origin\n            (degrees 45)\n    --> Ellipse2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( 0, 14.142 )\n    -->     , xDirection =\n    -->         Direction2d.fromAngle (degrees 75)\n    -->     , xRadius = 5\n    -->     , yRadius = 3\n    -->     }\n\n","type":"Point2d.Point2d -> Basics.Float -> Ellipse2d.Ellipse2d -> Ellipse2d.Ellipse2d"},{"name":"scaleAbout","comment":" Scale an ellipse about a given point by a given scale.\n\n    exampleEllipse\n        |> Ellipse2d.scaleAbout Point2d.origin 3\n    --> Ellipse2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( 30, 30 )\n    -->     , xDirection =\n    -->         Direction2d.fromAngle (degrees 30)\n    -->     , xRadius = 15\n    -->     , yRadius = 9\n    -->     }\n\n","type":"Point2d.Point2d -> Basics.Float -> Ellipse2d.Ellipse2d -> Ellipse2d.Ellipse2d"},{"name":"translateBy","comment":" Translate an ellipse by a given displacement.\n\n    exampleEllipse\n        |> Ellipse2d.translateBy\n            (Vector2d.fromComponents ( 5, 10 ))\n    --> Ellipse2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( 15, 20 )\n    -->     , xDirection =\n    -->         Direction2d.fromAngle (degrees 30)\n    -->     , xRadius = 5\n    -->     , yRadius = 3\n    -->     }\n\n","type":"Vector2d.Vector2d -> Ellipse2d.Ellipse2d -> Ellipse2d.Ellipse2d"},{"name":"translateIn","comment":" Translate an ellipse in a given direction by a given distance;\n\n    Ellipse2d.translateIn direction distance\n\nis equivalent to\n\n    Ellipse2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Ellipse2d.Ellipse2d -> Ellipse2d.Ellipse2d"},{"name":"with","comment":" Construct an ellipse from its center point, X direction, and X and Y radii.\nIf you pass a negative radius, the absolute value will be used.\n\n    exampleEllipse =\n        Ellipse2d.with\n            { centerPoint =\n                Point2d.fromCoordinates ( 10, 10 )\n            , xDirection =\n                Direction2d.fromAngle (degrees 30)\n            , xRadius = 5\n            , yRadius = 3\n            }\n\n","type":"{ centerPoint : Point2d.Point2d, xDirection : Direction2d.Direction2d, xRadius : Basics.Float, yRadius : Basics.Float } -> Ellipse2d.Ellipse2d"},{"name":"xAxis","comment":" Get the X axis of an ellipse.\n\n    Ellipse2d.xAxis exampleEllipse\n    --> Axis2d.through\n    -->     (Point2d.fromCoordinates ( 10, 10 ))\n    -->     (Direction2d.fromAngle (degrees 30))\n\n","type":"Ellipse2d.Ellipse2d -> Axis2d.Axis2d"},{"name":"xDirection","comment":" Get the direction of the ellipse's X axis.\n\n    Ellipse2d.xDirection exampleEllipse\n    --> Direction2d.fromAngle (degrees 30)\n\n","type":"Ellipse2d.Ellipse2d -> Direction2d.Direction2d"},{"name":"xRadius","comment":" Get the radius of an ellipse along its X axis. This may be either the\nminimum or maximum radius.\n\n    Ellipse2d.xRadius exampleEllipse\n    --> 5\n\n","type":"Ellipse2d.Ellipse2d -> Basics.Float"},{"name":"yAxis","comment":" Get the Y axis of an ellipse.\n\n    Ellipse2d.yAxis exampleEllipse\n    --> Axis2d.through\n    -->     (Point2d.fromCoordinates ( 10, 10 ))\n    -->     (Direction2d.fromAngle (degrees 120))\n\n","type":"Ellipse2d.Ellipse2d -> Axis2d.Axis2d"},{"name":"yDirection","comment":" Get the direction of an ellipse's Y axis.\n\n    Ellipse2d.yDirection exampleEllipse\n    --> Direction2d.fromAngle (degrees 120)\n\n","type":"Ellipse2d.Ellipse2d -> Direction2d.Direction2d"},{"name":"yRadius","comment":" Get the radius of an ellipse along its Y axis. This may be either the\nminimum or maximum radius.\n\n    Ellipse2d.yRadius exampleEllipse\n    --> 3\n\n","type":"Ellipse2d.Ellipse2d -> Basics.Float"}],"binops":[]},{"name":"EllipticalArc2d","comment":" An `EllipticalArc2d` is a section of an `Ellipse2d` with a start and end\npoint. This module includes functionality for\n\n  - Constructing an elliptical arc from its center or end points\n  - Scaling, rotating, translating and mirroring elliptical arcs\n  - Evaluating points and derivative vectors along elliptical arcs\n  - Forming arc length parameterizations of elliptical arcs\n\nThe `startAngle` and `sweptAngle` values referred to below are not actually\nproper angles but instead refer to values of the [ellipse parameter](https://en.wikipedia.org/wiki/Ellipse#Parametric_representation).\nHowever, in simple cases you don't need to worry about the difference - if\n`startAngle` and `sweptAngle` are both multiples of 90 degrees, then you can\ntreat them as actual angles and everything will behave as you expect.\n\n@docs EllipticalArc2d\n\n\n# Constructors\n\n@docs with, fromEndpoints\n\n\n# Properties\n\n@docs startAngle, sweptAngle, startPoint, endPoint\n\nAll remaining properties of elliptical arcs are actually just properties of the\nunderlying ellipse; check out the <Ellipse2d> module for details.\n\n@docs centerPoint, axes, xAxis, yAxis, xDirection, yDirection, xRadius, yRadius\n\n\n# Evaluation\n\n@docs pointOn, pointsAt\n@docs Nondegenerate, nondegenerate, fromNondegenerate\n@docs tangentDirection, tangentDirectionsAt, sample, samplesAt\n\n\n# Transformations\n\n@docs reverse, scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n\n# Arc length parameterization\n\n@docs ArcLengthParameterized, arcLengthParameterized, arcLength, pointAlong, tangentDirectionAlong, sampleAlong\n\n\n## Low level\n\nAn `ArcLengthParameterized` value is a combination of an\n[`ArcLengthParameterization`](Geometry-ArcLengthParameterization) and an\nunderlying `EllipticalArc2d`. If you need to do something fancy, you can extract\nthese two values separately.\n\n@docs arcLengthParameterization, fromArcLengthParameterized\n\n\n# Differentiation\n\nYou are unlikely to need to use these functions directly, but they are useful if\nyou are writing low-level geometric algorithms.\n\n@docs firstDerivative, firstDerivativesAt, maxSecondDerivativeMagnitude\n\n","unions":[{"name":"ArcLengthParameterized","comment":" An elliptical arc that has been parameterized by arc length.\n","args":[],"cases":[]},{"name":"Nondegenerate","comment":" If a curve has zero length (consists of just a single point), then we say\nthat it is 'degenerate'. Some operations such as computing tangent directions\nare not defined on degenerate curves.\n\nA `Nondegenerate` value represents an arc that is definitely not degenerate. It\nis used as input to functions such as `EllipticalArc2d.tangentDirection` and can\nbe constructed using `EllipticalArc2d.nondegenerate`.\n\n","args":[],"cases":[]}],"aliases":[{"name":"EllipticalArc2d","comment":" ","args":[],"type":"Geometry.Types.EllipticalArc2d"}],"values":[{"name":"arcLength","comment":" Find the total arc length of an elliptical arc. This will be accurate to\nwithin the tolerance given when calling `arcLengthParameterized`.\n\n    arcLength : Float\n    arcLength =\n        EllipticalArc2d.arcLength parameterizedArc\n\n    arcLength\n    --> 2.4221\n\n","type":"EllipticalArc2d.ArcLengthParameterized -> Basics.Float"},{"name":"arcLengthParameterization","comment":" ","type":"EllipticalArc2d.ArcLengthParameterized -> Curve.ArcLengthParameterization.ArcLengthParameterization"},{"name":"arcLengthParameterized","comment":" Build an arc length parameterization of the given elliptical arc, with a\ngiven accuracy. Generally speaking, all operations on the resulting\n`ArcLengthParameterized` value will be accurate to within the specified maximum\nerror.\n\n    parameterizedArc =\n        exampleArc\n            |> EllipticalArc2d.arcLengthParameterized\n                { maxError = 1.0e-4 }\n\n","type":"{ maxError : Basics.Float } -> EllipticalArc2d.EllipticalArc2d -> EllipticalArc2d.ArcLengthParameterized"},{"name":"axes","comment":" ","type":"EllipticalArc2d.EllipticalArc2d -> Frame2d.Frame2d"},{"name":"centerPoint","comment":" ","type":"EllipticalArc2d.EllipticalArc2d -> Point2d.Point2d"},{"name":"endPoint","comment":" Get the end point of an elliptical arc.\n\n    EllipticalArc2d.endPoint exampleArc\n    --> Point2d.fromCoordinates ( 0, 1 )\n\n","type":"EllipticalArc2d.EllipticalArc2d -> Point2d.Point2d"},{"name":"firstDerivative","comment":" Get the first derivative of an elliptical arc at a given parameter value:\n\n    EllipticalArc2d.firstDerivative exampleArc\n        ParameterValue.zero\n    --> Vector2d.fromComponents ( 0, 1.5708 )\n\n    EllipticalArc2d.firstDerivative exampleArc\n        ParameterValue.half\n    --> Vector2d.fromComponents ( -2.2214, 1.1107 )\n\n    EllipticalArc2d.firstDerivative exampleArc\n        ParameterValue.one\n    --> Vector2d.fromComponents ( -3.1416, 0 )\n\n","type":"EllipticalArc2d.EllipticalArc2d -> Curve.ParameterValue.ParameterValue -> Vector2d.Vector2d"},{"name":"firstDerivativesAt","comment":" Evaluate the first derivative of an elliptical arc at a given set of\nparameter values:\n\n    exampleArc\n        |> EllipticalArc2d.firstDerivativesAt\n            (ParameterValue.steps 2)\n    --> [ Vector2d.fromComponents ( 0, 1.5708 )\n    --> , Vector2d.fromComponents ( -2.2214, 1.1107 )\n    --> , Vector2d.fromComponents ( -3.1416, 0 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> EllipticalArc2d.EllipticalArc2d -> List.List Vector2d.Vector2d"},{"name":"fromArcLengthParameterized","comment":" ","type":"EllipticalArc2d.ArcLengthParameterized -> EllipticalArc2d.EllipticalArc2d"},{"name":"fromEndpoints","comment":" Attempt to construct an elliptical arc from its endpoints, X direction, and\nX and Y radii. For any given valid set of these inputs, there are four possible\nsolutions, so you also need to specify which of the four solutions you want -\nwhether the swept angle of the arc should be less than or greater than 180\ndegrees, and whether the swept angle should be positive (counterclockwise) or\nnegative (clockwise).\n\nThe example below is interactive; try dragging either endpoint or the tip of the\nX direction (or the center point to move the whole arc), clicking on the X or Y\nradial lines and then scrolling to changet that radius, or clicking/tapping on\nthe various dashed arcs to switch what kind of swept angle to use.\n\n<iframe src=\"https://ianmackenzie.github.io/elm-geometry/1.0.0/EllipticalArc2d/fromEndpoints.html\" style=\"width: 500px; height: 400px\" scrolling=no frameborder=0>\n`https://ianmackenzie.github.io/elm-geometry/1.0.0/EllipticalArc2d/fromEndpoints.html`\n</iframe>\n\nThis function will return `Nothing` if no solution can found. Typically this\nmeans that the two endpoints are too far apart, but could also mean that one of\nthe specified radii was negative or zero, or the two given points were\ncoincident.\n\nThe behavior of this function is very close to [the SVG spec](https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes),\nbut when 'out of range' parameters are given this function will simply return\n`Nothing` instead of attempting to degrade gracefully (for example, by\nincreasing X and Y radius slightly if the given endpoints are slightly too far\napart). Note that this means this function is dangerous to use for 180 degree\narcs, since then slight numerical roundoff can mean the difference between a\nsolution being found and not - for 180 degree arcs it is safer to use\n`EllipticalArc2d.with` instead.\n\n","type":"{ startPoint : Point2d.Point2d, endPoint : Point2d.Point2d, xRadius : Basics.Float, yRadius : Basics.Float, xDirection : Direction2d.Direction2d, sweptAngle : Arc.SweptAngle.SweptAngle } -> Maybe.Maybe EllipticalArc2d.EllipticalArc2d"},{"name":"fromNondegenerate","comment":" Convert a nondegenerate elliptical arc back to a general `EllipticalArc2d`.\n\n    EllipticalArc2d.fromNondegenerate\n        nondegenerateExampleArc\n    --> exampleArc\n\n","type":"EllipticalArc2d.Nondegenerate -> EllipticalArc2d.EllipticalArc2d"},{"name":"maxSecondDerivativeMagnitude","comment":" Find a conservative upper bound on the magnitude of the second derivative of\nan elliptical arc. This can be useful when determining error bounds for various\nkinds of linear approximations.\n\n    exampleArc\n        |> EllipticalArc2d.maxSecondDerivativeMagnitude\n    --> 4.935\n\n","type":"EllipticalArc2d.EllipticalArc2d -> Basics.Float"},{"name":"mirrorAcross","comment":" Mirror an elliptical arc across a given axis.\n\n    mirroredArc =\n        exampleArc\n            |> EllipticalArc2d.mirrorAcross Axis2d.y\n\n    EllipticalArc2d.startPoint mirroredArc\n    --> Point2d.fromCoordinates ( -2, 0 )\n\n    EllipticalArc2d.endPoint mirroredArc\n    --> Point2d.fromCoordinates ( 0, 1 )\n\n","type":"Axis2d.Axis2d -> EllipticalArc2d.EllipticalArc2d -> EllipticalArc2d.EllipticalArc2d"},{"name":"nondegenerate","comment":" Attempt to construct a nondegenerate elliptical arc from a general\n`EllipticalArc2d`. If the arc is in fact degenerate (consists of a single\npoint), returns an `Err` with that point.\n\n    EllipticalArc2d.nondegenerate exampleArc\n    --> Ok nondegenerateExampleArc\n\n","type":"EllipticalArc2d.EllipticalArc2d -> Result.Result Point2d.Point2d EllipticalArc2d.Nondegenerate"},{"name":"placeIn","comment":" Take an elliptical arc considered to be defined in local coordinates\nrelative to a given reference frame, and return that arc expressed in global\ncoordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    EllipticalArc2d.relativeTo localFrame exampleArc\n    --> EllipticalArc2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( 1, 2 )\n    -->     , xDirection = Direction2d.x\n    -->     , xRadius = 2\n    -->     , yRadius = 1\n    -->     , startAngle = 0\n    -->     , sweptAngle = degrees 90\n    -->     }\n\n","type":"Frame2d.Frame2d -> EllipticalArc2d.EllipticalArc2d -> EllipticalArc2d.EllipticalArc2d"},{"name":"pointAlong","comment":" Try to get the point along an elliptical arc at a given arc length. For\nexample, to get the true midpoint of `exampleArc`:\n\n    EllipticalArc2d.pointAlong parameterizedArc\n        (arcLength / 2)\n    --> Just (Point2d.fromCoordinates ( 1.1889, 0.8041 ))\n\nNote that this is not the same as evaulating at a parameter value of 0.5:\n\n    EllipticalArc2d.pointOn exampleArc\n        ParameterValue.half\n    --> Point2d.fromCoordinates ( 1.4142, 0.7071 )\n\nIf the given arc length is less than zero or greater than the arc length of the\narc, returns `Nothing`.\n\n","type":"EllipticalArc2d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Point2d.Point2d"},{"name":"pointOn","comment":" Get the point along an elliptical arc at a given parameter value:\n\n    EllipticalArc2d.pointOn exampleArc ParameterValue.zero\n    --> Point2d.fromCoordinates ( 2, 0 )\n\n    EllipticalArc2d.pointOn exampleArc ParameterValue.half\n    --> Point2d.fromCoordinates ( 1.4142, 0.7071 )\n\n    EllipticalArc2d.pointOn exampleArc ParameterValue.one\n    --> Point2d.fromCoordinates ( 0, 1 )\n\n","type":"EllipticalArc2d.EllipticalArc2d -> Curve.ParameterValue.ParameterValue -> Point2d.Point2d"},{"name":"pointsAt","comment":" Get points along an elliptical arc at a given set of parameter values:\n\n    exampleArc\n        |> EllipticalArc2d.pointsAt\n            (ParameterValue.steps 2)\n    --> [ Point2d.fromCoordinates ( 2, 0 )\n    --> , Point2d.fromCoordinates ( 1.4142, 0.7071 )\n    --> , Point2d.fromCoordinates ( 0, 1 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> EllipticalArc2d.EllipticalArc2d -> List.List Point2d.Point2d"},{"name":"relativeTo","comment":" Take an elliptical arc defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    EllipticalArc2d.relativeTo localFrame exampleArc\n    --> EllipticalArc2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( -1, -2 )\n    -->     , xDirection = Direction2d.x\n    -->     , xRadius = 2\n    -->     , yRadius = 1\n    -->     , startAngle = 0\n    -->     , sweptAngle = degrees 90\n    -->     }\n\n","type":"Frame2d.Frame2d -> EllipticalArc2d.EllipticalArc2d -> EllipticalArc2d.EllipticalArc2d"},{"name":"reverse","comment":" Reverse the direction of an elliptical arc, so that the start point becomes\nthe end point and vice versa. Does not change the shape of the arc or any\nproperties of the underlying ellipse.\n\n    EllipticalArc2d.reverse exampleArc\n    --> EllipticalArc2d.with\n    -->     { centerPoint = Point2d.origin\n    -->     , xDirection = Direction2d.x\n    -->     , xRadius = 2\n    -->     , yRadius = 1\n    -->     , startAngle = degrees 90\n    -->     , sweptAngle = degrees -90\n    -->     }\n\n","type":"EllipticalArc2d.EllipticalArc2d -> EllipticalArc2d.EllipticalArc2d"},{"name":"rotateAround","comment":" Rotate an elliptical arc around a given point by a given angle (in radians).\n\n    exampleArc\n        |> EllipticalArc2d.rotateAround Point2d.origin\n            (degrees 180)\n    --> EllipticalArc2d.with\n    -->     { centerPoint = Point2d.origin\n    -->     , xDirection = Direction2d.negativeX\n    -->     , xRadius = 2\n    -->     , yRadius = 1\n    -->     , startAngle = 0\n    -->     , sweptAngle = degrees 90\n    -->     }\n\n","type":"Point2d.Point2d -> Basics.Float -> EllipticalArc2d.EllipticalArc2d -> EllipticalArc2d.EllipticalArc2d"},{"name":"sample","comment":" Get both the point and tangent direction of a nondegenerate elliptical arc\nat a given parameter value:\n\n    EllipticalArc2d.sample nondegenerateExampleArc\n        ParameterValue.zero\n    --> ( Point2d.fromCoordinates ( 2, 0 )\n    --> , Direction2d.fromAngle (degrees 90)\n    --> )\n\n    EllipticalArc2d.sample nondegenerateExampleArc\n        ParameterValue.half\n    --> ( Point2d.fromCoordinates ( 1.4142, 0.7071 )\n    --> , Direction2d.fromAngle (degrees 153.4)\n    --> )\n\n    EllipticalArc2d.sample nondegenerateExampleArc\n        ParameterValue.one\n    --> ( Point2d.fromCoordinates ( 0, 1 )\n    --> , Direction2d.fromAngle (degrees 180)\n    --> )\n\n","type":"EllipticalArc2d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"sampleAlong","comment":" Try to get the point and tangent direction along an elliptical arc at a\ngiven arc length. To get the point and tangent direction at the midpoint of\n`exampleArc`:\n\n    EllipticalArc2d.sampleAlong parameterizedArc\n        (arcLength / 2)\n    --> Just\n    -->     ( Point2d.fromCoordinates ( 1.1889, 0.8041 )\n    -->     , Direction2d.fromAngle (degrees 159.7)\n    -->     )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline (or if the spline is degenerate), returns `Nothing`.\n\n","type":"EllipticalArc2d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"samplesAt","comment":" Get points and tangent directions of a nondegenerate arc at a given set of\nparameter values:\n\n    nondegenerateExampleArc\n        |> EllipticalArc2d.samplesAt\n            (ParameterValue.steps 2)\n    --> [ ( Point2d.fromCoordinates ( 2, 0 )\n    -->   , Direction2d.fromAngle (degrees 90)\n    -->   )\n    --> , ( Point2d.fromCoordinates ( 1.4142, 0.7071 )\n    -->   , Direction2d.fromAngle (degrees 153.4)\n    -->   )\n    --> , ( Point2d.fromCoordinates ( 0, 1 )\n    -->   , Direction2d.fromAngle (degrees 180)\n    -->   )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> EllipticalArc2d.Nondegenerate -> List.List ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"scaleAbout","comment":" Scale an elliptical arc about a given point by a given scale.\n\n    exampleArc\n        |> EllipticalArc2d.scaleAbout Point2d.origin 3\n    --> EllipticalArc2d.with\n    -->     { centerPoint = Point2d.origin\n    -->     , xDirection = Direction2d.x\n    -->     , xRadius = 6\n    -->     , yRadius = 3\n    -->     , startAngle = 0\n    -->     , sweptAngle = degrees 90\n    -->     }\n\n","type":"Point2d.Point2d -> Basics.Float -> EllipticalArc2d.EllipticalArc2d -> EllipticalArc2d.EllipticalArc2d"},{"name":"startAngle","comment":" The start angle of an elliptical arc is the value of the [ellipse parameter](https://en.wikipedia.org/wiki/Ellipse#Parametric_representation)\nat the start point of the arc.\n\n    EllipticalArc2d.startAngle exampleArc\n    --> 0\n\n","type":"EllipticalArc2d.EllipticalArc2d -> Basics.Float"},{"name":"startPoint","comment":" Get the start point of an elliptical arc.\n\n    EllipticalArc2d.startPoint exampleArc\n    --> Point2d.fromCoordinates ( 2, 0 )\n\n","type":"EllipticalArc2d.EllipticalArc2d -> Point2d.Point2d"},{"name":"sweptAngle","comment":" The swept angle of an elliptical arc is the difference between values of the\n[ellipse parameter](https://en.wikipedia.org/wiki/Ellipse#Parametric_representation)\nfrom the start point to the end point of the arc.\n\n    EllipticalArc2d.sweptAngle exampleArc\n    --> degrees 90\n\n","type":"EllipticalArc2d.EllipticalArc2d -> Basics.Float"},{"name":"tangentDirection","comment":" Get the tangent direction to a nondegenerate elliptical arc at a given\nparameter value:\n\n    EllipticalArc2d.tangentDirection nondegenerateExampleArc\n        ParameterValue.zero\n    --> Direction2d.fromAngle (degrees 90)\n\n    EllipticalArc2d.tangentDirection nondegenerateExampleArc\n        ParameterValue.half\n    --> Direction2d.fromAngle (degrees 153.4)\n\n    EllipticalArc2d.tangentDirection nondegenerateExampleArc\n        ParameterValue.one\n    --> Direction2d.fromAngle (degrees 180)\n\n","type":"EllipticalArc2d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> Direction2d.Direction2d"},{"name":"tangentDirectionAlong","comment":" Try to get the tangent direction along an elliptical arc at a given arc\nlength. To get the tangent direction at the midpoint of `exampleArc`:\n\n    EllipticalArc2d.tangentDirectionAlong parameterizedArc\n        (arcLength / 2)\n    --> Just (Direction2d.fromAngle (degrees 159.7))\n\nIf the given arc length is less than zero or greater than the arc length of the\nelliptical arc (or if the elliptical arc is degenerate), returns `Nothing`.\n\n","type":"EllipticalArc2d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Direction2d.Direction2d"},{"name":"tangentDirectionsAt","comment":" Get tangent directions to a nondegenerate elliptical arc at a given set of\nparameter values:\n\n    nondegenerateExampleArc\n        |> EllipticalArc2d.tangentDirectionsAt\n            (ParameterValue.steps 2)\n    --> [ Direction2d.fromAngle (degrees 90)\n    --> , Direction2d.fromAngle (degrees 153.4)\n    --> , Direction2d.fromAngle (degrees 180)\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> EllipticalArc2d.Nondegenerate -> List.List Direction2d.Direction2d"},{"name":"translateBy","comment":" Translate an elliptical arc by a given displacement.\n\n    exampleArc\n        |> EllipticalArc2d.translateBy\n            (Vector2d.fromComponents ( 2, 3 ))\n    --> EllipticalArc2d.with\n    -->     { centerPoint =\n    -->         Point2d.fromCoordinates ( 2, 3 )\n    -->     , xDirection = Direction2d.x\n    -->     , xRadius = 2\n    -->     , yRadius = 1\n    -->     , startAngle = 0\n    -->     , sweptAngle = degrees 90\n    -->     }\n\n","type":"Vector2d.Vector2d -> EllipticalArc2d.EllipticalArc2d -> EllipticalArc2d.EllipticalArc2d"},{"name":"translateIn","comment":" Translate an elliptical arc in a given direction by a given distance;\n\n    EllipticalArc2d.translateIn direction distance\n\nis equivalent to\n\n    EllipticalArc2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> EllipticalArc2d.EllipticalArc2d -> EllipticalArc2d.EllipticalArc2d"},{"name":"with","comment":" Construct an elliptical arc from its center point, X direction, X and Y\nradii, start angle and swept angle. If you pass a negative radius, the absolute\nvalue will be used.\n\nFor example, to construct a simple 90 degree elliptical arc, you might use\n\n    exampleArc =\n        EllipticalArc2d.with\n            { centerPoint = Point2d.origin\n            , xDirection = Direction2d.x\n            , xRadius = 2\n            , yRadius = 1\n            , startAngle = 0\n            , sweptAngle = degrees 90\n            }\n\n![90 degree elliptical arc](https://ianmackenzie.github.io/elm-geometry/1.0.0/EllipticalArc2d/with1.svg)\n\nTo make an inclined 180 degree elliptical arc, you might use\n\n    EllipticalArc2d.with\n        { centerPoint = Point2d.origin\n        , xDirection = Direction2d.fromAngle (degrees 30)\n        , xRadius = 2\n        , yRadius = 1\n        , startAngle = degrees -90\n        , sweptAngle = degrees 180\n        }\n\n![180 degree inclined elliptical arc](https://ianmackenzie.github.io/elm-geometry/1.0.0/EllipticalArc2d/with2.svg)\n\n","type":"{ centerPoint : Point2d.Point2d, xDirection : Direction2d.Direction2d, xRadius : Basics.Float, yRadius : Basics.Float, startAngle : Basics.Float, sweptAngle : Basics.Float } -> EllipticalArc2d.EllipticalArc2d"},{"name":"xAxis","comment":" ","type":"EllipticalArc2d.EllipticalArc2d -> Axis2d.Axis2d"},{"name":"xDirection","comment":" ","type":"EllipticalArc2d.EllipticalArc2d -> Direction2d.Direction2d"},{"name":"xRadius","comment":" ","type":"EllipticalArc2d.EllipticalArc2d -> Basics.Float"},{"name":"yAxis","comment":" ","type":"EllipticalArc2d.EllipticalArc2d -> Axis2d.Axis2d"},{"name":"yDirection","comment":" ","type":"EllipticalArc2d.EllipticalArc2d -> Direction2d.Direction2d"},{"name":"yRadius","comment":" ","type":"EllipticalArc2d.EllipticalArc2d -> Basics.Float"}],"binops":[]},{"name":"Frame2d","comment":" A `Frame2d` has an origin point and a pair of X and Y directions (which are\nalways perpendicular to each other). It can be thought of as:\n\n  - A local coordinate system: Most geometric types have associated `relativeTo`\n    and `placeIn` functions that convert values of that type from global\n    coordinates to local coordinates in a particular frame, and vice versa.\n  - A pair of X and Y axes: It is often convenient to (for example) mirror\n    across the X axis of a frame, or project onto its Y axis. Frames can\n    also themselves be translated, rotated and mirrored!\n  - A combined 2D position and orientation: For example, a `Frame2d` could be\n    used to define the position and orientation of a spaceship in a 2D game.\n    Movement of the ship would then be done by translating and rotating the\n    frame.\n\n@docs Frame2d\n\n\n# Constants\n\n@docs atOrigin, xy\n\n\n# Constructors\n\n@docs atPoint, atCoordinates, withXDirection, withYDirection, unsafe\n\n\n# Properties\n\n@docs originPoint, xDirection, yDirection, isRightHanded, xAxis, yAxis\n\n\n# Transformations\n\n@docs reverseX, reverseY, moveTo, rotateBy, rotateAround, translateBy, translateIn, translateAlongOwn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Frame2d","comment":" ","args":[],"type":"Geometry.Types.Frame2d"}],"values":[{"name":"atCoordinates","comment":" Shorthand for `Frame2d.atPoint`;\n\n    Frame2d.atCoordinates ( x, y )\n\nis equivalent to\n\n    Frame2d.atPoint (Point2d.fromCoordinates ( x, y ))\n\n","type":"( Basics.Float, Basics.Float ) -> Frame2d.Frame2d"},{"name":"atOrigin","comment":" The global XY frame, centered at the origin.\n\n    Frame2d.originPoint Frame2d.atOrigin\n    --> Point2d.origin\n\n    Frame2d.xDirection Frame2d.atOrigin\n    --> Direction2d.x\n\n    Frame2d.yDirection Frame2d.atOrigin\n    --> Direction2d.y\n\n","type":"Frame2d.Frame2d"},{"name":"atPoint","comment":" Construct a frame aligned with the global XY frame but with the given origin\npoint.\n\n    point =\n        Point2d.fromCoordinates ( 2, 3 )\n\n    frame =\n        Frame2d.atPoint point\n\n    Frame2d.originPoint frame\n    --> point\n\n    Frame2d.xDirection frame\n    --> Direction2d.x\n\n    Frame2d.yDirection frame\n    --> Direction2d.y\n\n","type":"Point2d.Point2d -> Frame2d.Frame2d"},{"name":"isRightHanded","comment":" Check if a frame is [right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness).\n\n    Frame2d.isRightHanded Frame2d.atOrigin\n    --> True\n\n    Frame2d.isRightHanded\n        (Frame2d.reverseX Frame2d.atOrigin)\n    --> False\n\nAll predefined frames are right-handed, and most operations on frames preserve\nhandedness, so about the only ways to end up with a left-handed frame are by\nconstructing one explicitly with `unsafe` or by mirroring a right-handed frame.\n\n","type":"Frame2d.Frame2d -> Basics.Bool"},{"name":"mirrorAcross","comment":" Mirror a frame across an axis.\n\n    frame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))\n\n    mirroredFrame =\n        Frame2d.mirrorAcross Axis2d.x frame\n\n    Frame2d.originPoint mirroredFrame\n    --> Point2d.fromCoordinates ( 2, -3 )\n\n    Frame2d.xDirection mirroredFrame\n    --> Direction2d.x\n\n    Frame2d.yDirection mirroredFrame\n    --> Direction2d.negativeY\n\nNote that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\nof the frame.\n\n","type":"Axis2d.Axis2d -> Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"moveTo","comment":" Move a frame so that it has the given origin point.\n\n    point =\n        Point2d.fromCoordinates ( 1, 1 )\n\n    Frame2d.atOrigin |> Frame2d.moveTo point\n    --> Frame2d.atPoint point\n\n","type":"Point2d.Point2d -> Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"originPoint","comment":" Get the origin point of a given frame.\n\n    Frame2d.originPoint Frame2d.atOrigin\n    --> Point2d.origin\n\n","type":"Frame2d.Frame2d -> Point2d.Point2d"},{"name":"placeIn","comment":" Take one frame defined in global coordinates and a second frame defined\nin local coordinates relative to the first frame, and return the second frame\nexpressed in global coordinates.\n","type":"Frame2d.Frame2d -> Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"relativeTo","comment":" Take two frames defined in global coordinates, and return the second one\nexpressed in local coordinates relative to the first.\n","type":"Frame2d.Frame2d -> Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"reverseX","comment":" Reverse the X direction of a frame, leaving its Y direction and origin point\nthe same.\n\n    point =\n        Point2d.fromCoordinates ( 2, 3 )\n\n    frame =\n        Frame2d.atPoint point |> Frame2d.reverseX\n\n    Frame2d.originPoint frame\n    --> point\n\n    Frame2d.xDirection frame\n    --> Direction2d.negativeX\n\n    Frame2d.yDirection frame\n    --> Direction2d.y\n\nNote that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\nof the frame.\n\n","type":"Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"reverseY","comment":" Reverse the Y direction of a frame, leaving its X direction and origin point\nthe same.\n\n    point =\n        Point2d.fromCoordinates ( 2, 3 )\n\n    frame =\n        Frame2d.atPoint point |> Frame2d.reverseY\n\n    Frame2d.originPoint frame\n    --> point\n\n    Frame2d.xDirection frame\n    --> Direction2d.x\n\n    Frame2d.yDirection frame\n    --> Direction2d.negativeY\n\nNote that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\nof the frame.\n\n","type":"Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"rotateAround","comment":" Rotate a frame counterclockwise around a given point by a given angle. The\nframe's origin point will be rotated around the given point by the given angle,\nand its X and Y basis directions will be rotated by the given angle.\n\n    rotatedFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 1 ))\n            |> Frame2d.rotateAround Point2d.origin\n                (degrees 45)\n\n    Frame2d.originPoint rotatedFrame\n    --> Point2d.fromCoordinates ( 0, 1.4142 )\n\n    Frame2d.xDirection rotatedFrame\n    --> Direction2d.fromAngle (degrees 45)\n\n    Frame2d.yDirection rotatedFrame\n    --> Direction2d.fromAngle (degrees 135)\n\n","type":"Point2d.Point2d -> Basics.Float -> Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"rotateBy","comment":" Rotate a frame counterclockwise by a given angle around the frame's own\norigin point. The resulting frame will have the same origin point, and its X and\nY directions will be rotated by the given angle.\n\n    rotatedFrame =\n        Frame2d.rotateBy (degrees 30) Frame2d.atOrigin\n\n    Frame2d.xDirection rotatedFrame\n    --> Direction2d.fromAngle (degrees 30)\n\n    Frame2d.yDirection rotatedFrame\n    --> Direction2d.fromAngle (degrees 120)\n\n","type":"Basics.Float -> Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"translateAlongOwn","comment":" Translate a frame along one of its own axes by a given distance.\n\nThe first argument is a function that returns the axis to translate along, given\nthe current frame. The majority of the time this argument will be either\n`Frame2d.xAxis` or `Frame2d.yAxis`. The second argument is the distance to\ntranslate along the given axis.\n\nThis function is convenient when constructing frames via a series of\ntransformations. For example,\n\n    frame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 2, 0 ))\n            |> Frame2d.rotateBy (degrees 45)\n            |> Frame2d.translateAlongOwn Frame2d.xAxis 2\n\nmeans \"construct a frame at the point (2, 0), rotate it around its own origin\npoint by 45 degrees, then translate it along its own X axis by 2 units\",\nresulting in\n\n    Frame2d.originPoint frame\n    --> Point2d.fromCoordinates ( 3.4142, 1.4142 )\n\n    Frame2d.xDirection frame\n    --> Direction2d.fromAngle (degrees 45)\n\n    Frame2d.yDirection frame\n    --> Direction2d.fromAngle (degrees 135)\n\n","type":"(Frame2d.Frame2d -> Axis2d.Axis2d) -> Basics.Float -> Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"translateBy","comment":" Translate a frame by a given displacement.\n\n    frame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))\n\n    displacement =\n        Vector2d.fromComponents ( 1, 1 )\n\n    Frame2d.translateBy displacement frame\n    --> Frame2d.atPoint (Point2d.fromCoordinates ( 3, 4 ))\n\n","type":"Vector2d.Vector2d -> Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"translateIn","comment":" Translate a frame in a given direction by a given distance;\n\n    Frame2d.translateIn direction distance\n\nis equivalent to\n\n    Frame2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Frame2d.Frame2d -> Frame2d.Frame2d"},{"name":"unsafe","comment":" Construct a frame directly from its origin point and X and Y directions:\n\n    frame =\n        Frame2d.unsafe\n            { originPoint =\n                Point2d.fromCoordinates ( 2, 3 )\n            , xDirection =\n                Direction2d.fromAngle (degrees 45)\n            , yDirection =\n                Direction2d.fromAngle (degrees 135)\n            }\n\nIn this case **you must be careful to ensure that the X and Y directions are\nperpendicular**. To construct pairs of perpendicular directions,\n[`Direction2d.orthonormalize`](Direction2d#orthonormalize) or\n[`Direction2d.orthogonalize`](Direction2d#orthogonalize) may be useful.\n\n","type":"{ originPoint : Point2d.Point2d, xDirection : Direction2d.Direction2d, yDirection : Direction2d.Direction2d } -> Frame2d.Frame2d"},{"name":"withXDirection","comment":" Construct a frame with the given X axis direction, having the given origin\npoint. The Y axis direction will be constructed by rotating the given X\ndirection 90 degrees counterclockwise:\n\n    frame =\n        Frame2d.withXDirection\n            (Direction2d.fromAngle (degrees 30))\n            (Point2d.fromCoordinates ( 2, 3 ))\n\n    Frame2d.yDirection frame\n    --> Direction2d.fromAngle (degrees 120)\n\n","type":"Direction2d.Direction2d -> Point2d.Point2d -> Frame2d.Frame2d"},{"name":"withYDirection","comment":" Construct a frame with the given Y axis direction, having the given origin\npoint. The X axis direction will be constructed by rotating the given X\ndirection 90 degrees clockwise:\n\n    frame =\n        Frame2d.withYDirection\n            (Direction2d.fromAngle (degrees 30))\n            (Point2d.fromCoordinates ( 2, 3 ))\n\n    Frame2d.yDirection frame\n    --> Direction2d.fromAngle (degrees -60)\n\n","type":"Direction2d.Direction2d -> Point2d.Point2d -> Frame2d.Frame2d"},{"name":"xAxis","comment":" Get the X axis of a given frame (the axis formed from the frame's origin\npoint and X direction).\n\n    Frame2d.xAxis Frame2d.atOrigin\n    --> Axis2d.x\n\n","type":"Frame2d.Frame2d -> Axis2d.Axis2d"},{"name":"xDirection","comment":" Get the X direction of a given frame.\n\n    Frame2d.xDirection Frame2d.atOrigin\n    --> Direction2d.x\n\n","type":"Frame2d.Frame2d -> Direction2d.Direction2d"},{"name":"xy","comment":" DEPRECATED: Alias for `Frame2d.atOrigin`, kept for compatibility. Will be\nremoved in the next major release.\n","type":"Frame2d.Frame2d"},{"name":"yAxis","comment":" Get the Y axis of a given frame (the axis formed from the frame's origin\npoint and Y direction).\n\n    Frame2d.yAxis Frame2d.atOrigin\n    --> Axis2d.y\n\n","type":"Frame2d.Frame2d -> Axis2d.Axis2d"},{"name":"yDirection","comment":" Get the Y direction of a given frame.\n\n    Frame2d.yDirection Frame2d.atOrigin\n    --> Direction2d.y\n\n","type":"Frame2d.Frame2d -> Direction2d.Direction2d"}],"binops":[]},{"name":"Frame3d","comment":" A `Frame3d` has an origin point and a set of X, Y and Z directions (which\nare always perpendicular to each other). It can be thought of as:\n\n  - A local coordinate system: Most geometric types have associated `relativeTo`\n    and `placeIn` functions that convert values of that type from global\n    coordinates to local coordinates in a particular frame, and vice versa.\n  - A set of axes and planes: It is often convenient to (for example) rotate\n    around the Z axis of a frame, or mirror across its XY plane. Frames can\n    also themselves be translated, rotated and mirrored!\n  - A combined 3D position and orientation: For example, a `Frame3d` could be\n    used to define the position and orientation of a spaceship in a 3D game.\n    Movement of the ship would then be done by translating and rotating the\n    frame.\n\n@docs Frame3d\n\n\n# Constants\n\n@docs atOrigin, xyz\n\n\n# Constructors\n\nThe `withXDirection`, `withYDirection` and `withZDirection` functions all\nconstruct a new `Frame3d` with the given axis direction, having the given origin\npoint. The other two directions will be chosen arbitrarily. This can be useful\nwhen constructing 'scratch' frames where (for example) you want a particular Z\ndirection but the specific X/Y directions are unimportant:\n\n    zDirection =\n        Direction3d.fromAzimuthAndElevation\n            (degrees 0)\n            (degrees 60)\n\n    frame =\n        Frame3d.withZDirection zDirection Point3d.origin\n\n    Frame3d.zDirection frame\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 0)\n    -->     (degrees 60)\n\n    Frame3d.originPoint frame\n    --> Point3d.origin\n\n    Frame3d.xDirection frame\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 0)\n    -->     (degrees -30)\n\n    Frame3d.yDirection frame\n    --> Direction3d.y\n\nNo guarantees are given about the other two directions other than that the three\ndirections will be mutually perpendicular, and will be oriented so that the\nresulting frame is [right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness).\n\n@docs withXDirection, withYDirection, withZDirection, atPoint, atCoordinates, unsafe\n\n\n# Properties\n\n@docs originPoint, xDirection, yDirection, zDirection, isRightHanded\n\n\n## Axes\n\n@docs xAxis, yAxis, zAxis\n\n\n## Planes\n\nThe following functions all return planes with the same origin point as the\ngiven frame, but with varying normal directions. In each case the normal\ndirection of the resulting plane is given by the cross product of the two\nindicated basis directions (assuming a right-handed frame); for example,\n\n    Frame3d.xyPlane Frame3d.atOrigin\n    --> Plane3d.through Point3d.origin\n    -->     Direction3d.positiveZ\n\nsince the cross product of the X and Y basis directions of a frame is equal to\nits Z basis direction. And since reversing the order of arguments in a cross\nproduct reverses the sign of the result,\n\n    Frame3d.yxPlane Frame3d.atOrigin\n    --> Plane3d.through Point3d.origin\n    -->     Direction3d.negativeZ\n\n@docs xyPlane, yxPlane, yzPlane, zyPlane, zxPlane, xzPlane\n\n\n## Sketch planes\n\nThese functions all form a `SketchPlane3d` from two axes of the given frame. The\nX and Y axes of the sketch plane will correspond to the two indicated axes. For\nexample,\n\n    yzSketchPlane =\n        Frame3d.yzSketchPlane Frame3d.atOrigin\n\n    SketchPlane3d.originPoint yzSketchPlane\n    --> Point3d.origin\n\n    SketchPlane3d.xDirection yzSketchPlane\n    --> Direction3d.y\n\n    SketchPlane3d.yDirection yzSketchPlane\n    --> Direction3d.z\n\nNote that this can be confusing - for example, a local X coordinate in the above\nsketch plane corresponds to a global Y coordinate, and a local Y coordinate\ncorresponds to a global Z coordinate!\n\n@docs xySketchPlane, yxSketchPlane, yzSketchPlane, zySketchPlane, zxSketchPlane, xzSketchPlane\n\n\n# Transformations\n\n@docs reverseX, reverseY, reverseZ, moveTo, rotateAround, rotateAroundOwn, translateBy, translateIn, translateAlongOwn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Frame3d","comment":" ","args":[],"type":"Geometry.Types.Frame3d"}],"values":[{"name":"atCoordinates","comment":" Shorthand for `Frame3d.atPoint`;\n\n    Frame3d.atCoordinates ( x, y, z )\n\nis equivalent to\n\n    Frame3d.atPoint (Point3d.fromCoordinates ( x, y, z ))\n\n","type":"( Basics.Float, Basics.Float, Basics.Float ) -> Frame3d.Frame3d"},{"name":"atOrigin","comment":" The global XYZ frame, centered at the origin.\n\n    Frame3d.originPoint Frame3d.atOrigin\n    --> Point3d.origin\n\n    Frame3d.xDirection Frame3d.atOrigin\n    --> Direction3d.x\n\n    Frame3d.yDirection Frame3d.atOrigin\n    --> Direction3d.y\n\n    Frame3d.zDirection Frame3d.atOrigin\n    --> Direction3d.z\n\n","type":"Frame3d.Frame3d"},{"name":"atPoint","comment":" Construct a frame aligned with the global XYZ frame but with the given\norigin point.\n\n    frame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 2, 1, 3 ))\n\n    Frame3d.originPoint frame\n    --> Point3d.fromCoordinates ( 2, 1, 3 )\n\n    Frame3d.xDirection frame\n    --> Direction3d.x\n\n    Frame3d.yDirection frame\n    --> Direction3d.y\n\n    Frame3d.zDirection frame\n    --> Direction3d.z\n\n","type":"Point3d.Point3d -> Frame3d.Frame3d"},{"name":"isRightHanded","comment":" Check if a frame is [right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness).\n\n    Frame3d.isRightHanded Frame3d.atOrigin\n    --> True\n\n    Frame3d.isRightHanded\n        (Frame3d.reverseZ Frame3d.atOrigin)\n    --> False\n\nAll predefined frames are right-handed, and most operations on frames preserve\nhandedness, so about the only ways to end up with a left-handed frame are by\nconstructing one explicitly with `unsafe` or by mirroring a right-handed frame.\n\n","type":"Frame3d.Frame3d -> Basics.Bool"},{"name":"mirrorAcross","comment":" Mirror a frame across a plane.\n\n    frame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 2, 1, 3 ))\n\n    mirroredFrame =\n        Frame3d.mirrorAcross Plane3d.xy frame\n\n    Frame3d.originPoint mirroredFrame\n    --> Point3d.fromCoordinates ( 2, 1, -3 )\n\n    Frame3d.xDirection mirroredFrame\n    --> Direction3d.x\n\n    Frame3d.yDirection mirroredFrame\n    --> Direction3d.y\n\n    Frame3d.zDirection mirroredFrame\n    --> Direction3d.negativeZ\n\nNote that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\nof the frame.\n\n","type":"Plane3d.Plane3d -> Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"moveTo","comment":" Move a frame so that it has the given origin point but unchanged\norientation.\n\n    point =\n        Point3d.fromCoordinates ( 2, 1, 3 )\n\n    Frame3d.atOrigin |> Frame3d.moveTo point\n    --> Frame3d.atPoint point\n\n","type":"Point3d.Point3d -> Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"originPoint","comment":" Get the origin point of a given frame.\n\n    Frame3d.originPoint Frame3d.atOrigin\n    --> Point3d.origin\n\n","type":"Frame3d.Frame3d -> Point3d.Point3d"},{"name":"placeIn","comment":" Take one frame defined in global coordinates and a second frame defined\nin local coordinates relative to the first frame, and return the second frame\nexpressed in global coordinates.\n","type":"Frame3d.Frame3d -> Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"relativeTo","comment":" Take two frames defined in global coordinates, and return the second one\nexpressed in local coordinates relative to the first.\n","type":"Frame3d.Frame3d -> Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"reverseX","comment":" Reverse the X direction of a frame.\n\n    Frame3d.xDirection (Frame3d.reverseX Frame3d.atOrigin)\n    --> Direction3d.negativeX\n\nNote that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\nof the frame.\n\n","type":"Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"reverseY","comment":" Reverse the Y direction of a frame.\n\n    Frame3d.yDirection (Frame3d.reverseY Frame3d.atOrigin)\n    --> Direction3d.negativeY\n\nNote that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\nof the frame.\n\n","type":"Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"reverseZ","comment":" Reverse the Z direction of a frame.\n\n    Frame3d.zDirection (Frame3d.reverseZ Frame3d.atOrigin)\n    --> Direction3d.negativeZ\n\nNote that this will switch the [handedness](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\nof the frame.\n\n","type":"Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"rotateAround","comment":" Rotate a frame around an axis by a given angle (in radians). The frame's\norigin point and basis directions will all be rotated around the given axis.\n\n    frame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 2, 1, 3 ))\n\n    rotatedFrame =\n        Frame3d.rotateAround Axis3d.z (degrees 90) frame\n\n    Frame3d.originPoint rotatedFrame\n    --> Point3d.fromCoordinates ( -1, 2, 3 )\n\n    Frame3d.xDirection rotatedFrame\n    --> Direction3d.y\n\n    Frame3d.yDirection rotatedFrame\n    --> Direction3d.negativeX\n\n    Frame3d.zDirection rotatedFrame\n    --> Direction3d.z\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"rotateAroundOwn","comment":" Rotate a frame around one of its own axes by a given angle (in radians).\n\nThe first argument is a function that returns the axis to rotate around, given\nthe current frame. The majority of the time this will be either `Frame3d.xAxis`,\n`Frame3d.yAxis` or `Frame3d.zAxis`. Compare the following to the above example\nfor `rotateAround`:\n\n    frame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 2, 1, 3 ))\n\n    rotatedFrame =\n        frame\n            |> Frame3d.rotateAroundOwn Frame3d.zAxis\n                (degrees 90)\n\n    Frame3d.originPoint rotatedFrame\n    --> Point3d.fromCoordinates ( 2, 1, 3 )\n\n    Frame3d.xDirection rotatedFrame\n    --> Direction3d.y\n\n    Frame3d.yDirection rotatedFrame\n    --> Direction3d.negativeX\n\n    Frame3d.zDirection rotatedFrame\n    --> Direction3d.z\n\nSince the rotation is done around the frame's own Z axis (which passes through\nthe frame's origin point), the origin point remains the same after rotation.\n\nIn this example the frame's Z axis has the same orientation as the global Z axis\nso the frame's basis directions are rotated the same way, but in more complex\nexamples involving rotated frames a rotation around (for example) the frame's\nown Z axis may be completely different from a rotation around the global Z axis.\n\n","type":"(Frame3d.Frame3d -> Axis3d.Axis3d) -> Basics.Float -> Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"translateAlongOwn","comment":" Translate a frame along one of its own axes by a given distance.\n\nThe first argument is a function that returns the axis to translate along, given\nthe current frame. The majority of the time this will be either `Frame3d.xAxis`,\n`Frame3d.yAxis` or `Frame3d.zAxis`.\n\nThis function is convenient when constructing frames via a series of\ntransformations. For example,\n\n    point =\n        Point3d.fromCoordinates ( 2, 0, 0 )\n\n    frame =\n        Frame3d.atPoint point\n            |> Frame3d.rotateAroundOwn Frame3d.zAxis\n                (degrees 45)\n            |> Frame3d.translateAlongOwn Frame3d.xAxis 2\n\nmeans \"construct a frame at the point (2, 0, 0), rotate it around its own Z axis\ncounterclockwise by 45 degrees, then translate it along its own (rotated) X axis\nby 2 units\", resulting in\n\n    Frame3d.originPoint frame\n    --> Point3d.fromCoordinates ( 3.4142, 1.4142, 0 )\n\n    Frame3d.xDirection frame\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 45)\n    -->     (degrees 0)\n\n    Frame3d.yDirection frame\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 135)\n    -->     (degrees 0)\n\n    Frame3d.zDirection frame\n    --> Direction3d.z\n\n","type":"(Frame3d.Frame3d -> Axis3d.Axis3d) -> Basics.Float -> Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"translateBy","comment":" Translate a frame by a given displacement.\n\n    frame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 2, 1, 3 ))\n\n    displacement =\n        Vector3d.fromComponents ( 1, 1, 1 )\n\n    Frame3d.translateBy displacement frame\n    --> Frame3d.atPoint\n    -->     (Point3d.fromCoordinates ( 3, 2, 4 ))\n\n","type":"Vector3d.Vector3d -> Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"translateIn","comment":" Translate a frame in a given direction by a given distance;\n\n    Frame3d.translateIn direction distance\n\nis equivalent to\n\n    Frame3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> Frame3d.Frame3d -> Frame3d.Frame3d"},{"name":"unsafe","comment":" Construct a frame directly from its origin point and X, Y and Z directions:\n\n    frame =\n        Frame3d.unsafe\n            { originPoint =\n                Point3d.fromCoordinates ( 2, 1, 3 )\n            , xDirection =\n                Direction3d.unsafe ( 0.8, 0.6, 0 )\n            , yDirection =\n                Direction3d.unsafe ( -0.6, 0.8, 0 )\n            , zDirection =\n                Direction3d.unsafe ( 0, 0, 1 )\n            }\n\nIn this case **you must be careful to ensure that the X, Y and Z directions are\nperpendicular**. (You will likely also want to make sure that they form a\n[right-handed](https://en.wikipedia.org/wiki/Cartesian_coordinate_system#Orientation_and_handedness)\ncoordinate system.) To construct sets of mutually perpendicular directions,\n[`Direction3d.orthonormalize`](Direction3d#orthonormalize),\n[`Direction3d.orthogonalize`](Direction3d#orthogonalize), or\n[`Direction3d.perpendicularBasis`](Direction3d#perpendicularBasis) may be\nuseful.\n\n","type":"{ originPoint : Point3d.Point3d, xDirection : Direction3d.Direction3d, yDirection : Direction3d.Direction3d, zDirection : Direction3d.Direction3d } -> Frame3d.Frame3d"},{"name":"withXDirection","comment":" Construct a frame with the given origin point and X direction.\n","type":"Direction3d.Direction3d -> Point3d.Point3d -> Frame3d.Frame3d"},{"name":"withYDirection","comment":" Construct a frame with the given origin point and Y direction.\n","type":"Direction3d.Direction3d -> Point3d.Point3d -> Frame3d.Frame3d"},{"name":"withZDirection","comment":" Construct a frame with the given origin point and Z direction.\n","type":"Direction3d.Direction3d -> Point3d.Point3d -> Frame3d.Frame3d"},{"name":"xAxis","comment":" Get the X axis of a given frame (the axis formed from the frame's origin\npoint and X direction).\n\n    Frame3d.xAxis Frame3d.atOrigin\n    --> Axis3d.x\n\n","type":"Frame3d.Frame3d -> Axis3d.Axis3d"},{"name":"xDirection","comment":" Get the X direction of a given frame.\n\n    Frame3d.xDirection Frame3d.atOrigin\n    --> Direction3d.x\n\n","type":"Frame3d.Frame3d -> Direction3d.Direction3d"},{"name":"xyPlane","comment":" Get a plane with normal direction equal to the frame's positive Z direction.\n","type":"Frame3d.Frame3d -> Plane3d.Plane3d"},{"name":"xySketchPlane","comment":" Form a sketch plane from the given frame's X and Y axes.\n","type":"Frame3d.Frame3d -> SketchPlane3d.SketchPlane3d"},{"name":"xyz","comment":" DEPRECATED: Alias for `Frame3d.atOrigin`, kept for compatibility. Will be\nremoved in the next major release.\n","type":"Frame3d.Frame3d"},{"name":"xzPlane","comment":" Get a plane with normal direction equal to the frame's negative Y direction.\n","type":"Frame3d.Frame3d -> Plane3d.Plane3d"},{"name":"xzSketchPlane","comment":" Form a sketch plane from the given frame's X and Z axes.\n","type":"Frame3d.Frame3d -> SketchPlane3d.SketchPlane3d"},{"name":"yAxis","comment":" Get the Y axis of a given frame (the axis formed from the frame's origin\npoint and Y direction).\n\n    Frame3d.yAxis Frame3d.atOrigin\n    --> Axis3d.y\n\n","type":"Frame3d.Frame3d -> Axis3d.Axis3d"},{"name":"yDirection","comment":" Get the Y direction of a given frame.\n\n    Frame3d.yDirection Frame3d.atOrigin\n    --> Direction3d.y\n\n","type":"Frame3d.Frame3d -> Direction3d.Direction3d"},{"name":"yxPlane","comment":" Get a plane with normal direction equal to the frame's negative Z direction.\n","type":"Frame3d.Frame3d -> Plane3d.Plane3d"},{"name":"yxSketchPlane","comment":" Form a sketch plane from the given frame's Y and X axes.\n","type":"Frame3d.Frame3d -> SketchPlane3d.SketchPlane3d"},{"name":"yzPlane","comment":" Get a plane with normal direction equal to the frame's positive X direction.\n","type":"Frame3d.Frame3d -> Plane3d.Plane3d"},{"name":"yzSketchPlane","comment":" Form a sketch plane from the given frame's Y and Z axes.\n","type":"Frame3d.Frame3d -> SketchPlane3d.SketchPlane3d"},{"name":"zAxis","comment":" Get the Z axis of a given frame (the axis formed from the frame's origin\npoint and Z direction).\n\n    Frame3d.zAxis Frame3d.atOrigin\n    --> Axis3d.z\n\n","type":"Frame3d.Frame3d -> Axis3d.Axis3d"},{"name":"zDirection","comment":" Get the Z direction of a given frame.\n\n    Frame3d.zDirection Frame3d.atOrigin\n    --> Direction3d.z\n\n","type":"Frame3d.Frame3d -> Direction3d.Direction3d"},{"name":"zxPlane","comment":" Get a plane with normal direction equal to the frame's positive Y direction.\n","type":"Frame3d.Frame3d -> Plane3d.Plane3d"},{"name":"zxSketchPlane","comment":" Form a sketch plane from the given frame's Z and X axes.\n","type":"Frame3d.Frame3d -> SketchPlane3d.SketchPlane3d"},{"name":"zyPlane","comment":" Get a plane with normal direction equal to the frame's negative X direction.\n","type":"Frame3d.Frame3d -> Plane3d.Plane3d"},{"name":"zySketchPlane","comment":" Form a sketch plane from the given frame's Z and Y axes.\n","type":"Frame3d.Frame3d -> SketchPlane3d.SketchPlane3d"}],"binops":[]},{"name":"LineSegment2d","comment":" A `LineSegment2d` is a line between two points in 2D. This module contains\nfunctionality such as:\n\n  - Interpolating within a line segment or measuring its length\n  - Scaling, rotating, translating, mirroring or projecting a line segment\n  - Converting a line segment between local and global coordinates in different\n    reference frames\n\n@docs LineSegment2d\n\n\n# Constructors\n\n@docs fromEndpoints, from, along\n\n\n# Properties\n\n@docs startPoint, endPoint, endpoints, midpoint, length, squaredLength, direction, perpendicularDirection, vector, boundingBox\n\n\n# Interpolation\n\n@docs interpolate\n\n\n# Intersection\n\n@docs intersectionPoint, intersectionWithAxis\n\n\n# Transformations\n\nTransforming a line segment is equivalent to transforming its start and end\npoints and forming a new line segment between the resulting points.\n\n@docs reverse, scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto, mapEndpoints\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"LineSegment2d","comment":" ","args":[],"type":"Geometry.Types.LineSegment2d"}],"values":[{"name":"along","comment":" Construct a line segment lying on the given axis, with its endpoints at the\ngiven distances from the axis' origin point.\n\n    LineSegment2d.along Axis2d.x 3 5\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 3, 0 )\n    -->     , Point2d.fromCoordinates ( 5, 0 )\n    -->     )\n\n    LineSegment2d.along Axis2d.y 2 -4\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 0, 2 )\n    -->     , Point2d.fromCoordinates ( 0, -4 )\n    -->     )\n\n","type":"Axis2d.Axis2d -> Basics.Float -> Basics.Float -> LineSegment2d.LineSegment2d"},{"name":"boundingBox","comment":" Get the minimal bounding box containing a given line segment.\n\n    LineSegment2d.boundingBox exampleLineSegment\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 3\n    -->     , minY = 2\n    -->     , maxY = 4\n    -->     }\n\n","type":"LineSegment2d.LineSegment2d -> BoundingBox2d.BoundingBox2d"},{"name":"direction","comment":" Get the direction from a line segment's start point to its end point. If the\nline segment has zero length (the start and end points are the same), returns\n`Nothing`.\n\n    LineSegment2d.direction exampleLineSegment\n    --> Just (Direction2d.fromAngle (degrees 45))\n\n","type":"LineSegment2d.LineSegment2d -> Maybe.Maybe Direction2d.Direction2d"},{"name":"endPoint","comment":" Get the end point of a line segment.\n\n    LineSegment2d.endPoint exampleLineSegment\n    --> Point2d.fromCoordinates ( 3, 4 )\n\n","type":"LineSegment2d.LineSegment2d -> Point2d.Point2d"},{"name":"endpoints","comment":" Get the endpoints of a line segment as a tuple.\n\n    ( p1, p2 ) =\n        LineSegment2d.endpoints lineSegment\n\n","type":"LineSegment2d.LineSegment2d -> ( Point2d.Point2d, Point2d.Point2d )"},{"name":"from","comment":" Construct a line segment from the first point to the second;\n\n    LineSegment2d.from firstPoint secondPoint\n\nis equivalent to\n\n    LineSegment2d.fromEndpoints ( firstPoint, secondPoint )\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> LineSegment2d.LineSegment2d"},{"name":"fromEndpoints","comment":" Construct a line segment from its two endpoints:\n\n    exampleLineSegment =\n        LineSegment2d.fromEndpoints\n            ( Point2d.fromCoordinates ( 1, 2 )\n            , Point2d.fromCoordinates ( 3, 4 )\n            )\n\n","type":"( Point2d.Point2d, Point2d.Point2d ) -> LineSegment2d.LineSegment2d"},{"name":"interpolate","comment":" Interpolate a line segment between its start and end points; a value of 0.0\ncorresponds to the start point of the line segment, a value of 0.5 corresponds\nto its midpoint and a value of 1.0 corresponds to its end point. Values less\nthan 0.0 or greater than 1.0 can be used to extrapolate.\n\n    LineSegment2d.interpolate exampleLineSegment 0.25\n    --> Point2d.fromCoordinates ( 1.5, 2.5 )\n\n    LineSegment2d.interpolate exampleLineSegment 1.5\n    --> Point2d.fromCoordinates ( 4, 5 )\n\n","type":"LineSegment2d.LineSegment2d -> Basics.Float -> Point2d.Point2d"},{"name":"intersectionPoint","comment":" Attempt to find the unique intersection point of two line segments. If there\nis no such point (the two line segments do not touch, or they overlap), returns\n`Nothing`.\n\n    -- 4 corners of a square\n\n    a =\n        Point2d.fromCoordinates ( 0, 0 )\n\n    b =\n        Point2d.fromCoordinates ( 1, 0 )\n\n    c =\n        Point2d.fromCoordinates ( 1, 1 )\n\n    d =\n        Point2d.fromCoordinates ( 0, 1 )\n\n    -- definition of some segments with those points\n\n    ab =\n        LineSegment2d.from a b\n    ...\n\n    -- searching for intersections\n\n    LineSegment2d.intersectionPoint ab bc\n    --> Just (Point2d.fromCoordinates ( 1, 0 ))\n    -- corner point b\n\n    LineSegment2d.intersectionPoint ac bd\n    --> Just (Point2d.fromCoordinates ( 0.5, 0.5 ))\n    -- diagonal crossing at square center\n\n    LineSegment2d.intersectionPoint ab cd\n    --> Nothing -- parallel lines\n\n    LineSegment2d.intersectionPoint ab ab\n    --> Nothing -- collinear lines\n\nNote that if the endpoint of one line segment lies on the other line segment,\nnumerical roundoff means that the intersection may or may not be found. If two\nsegments have a shared endpoint (the two segments meet in something like a 'V',\nwhere the end point of one segment is the start point of the next), that point\nis guaranteed to be returned as the intersection point, but if two segments meet\nin a 'T' shape the intersection point may or may not be found.\n\n","type":"LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d -> Maybe.Maybe Point2d.Point2d"},{"name":"intersectionWithAxis","comment":" Attempt to find the unique intersection point of a line segment with an\naxis. If there is no such point (the line segment does not touch the axis, or\nlies perfectly along it), returns `Nothing`.\n\n    lineSegment =\n        LineSegment2d.fromEndpoints\n            ( Point2d.fromCoordinates ( 1, -1 )\n            , Point2d.fromCoordinates ( 4, 1 )\n            )\n\n    LineSegment2d.intersectionWithAxis Axis2d.x lineSegment\n    --> Just (Point2d.fromCoordinates ( 2.5, 0 ))\n\n    LineSegment2d.intersectionWithAxis Axis2d.y lineSegment\n    --> Nothing\n\n","type":"Axis2d.Axis2d -> LineSegment2d.LineSegment2d -> Maybe.Maybe Point2d.Point2d"},{"name":"length","comment":" Get the length of a line segment.\n\n    LineSegment2d.length exampleLineSegment\n    --> 2.8284\n\n","type":"LineSegment2d.LineSegment2d -> Basics.Float"},{"name":"mapEndpoints","comment":" Transform the start and end points of a line segment by a given function\nand create a new line segment from the resulting points. Most other\ntransformation functions can be defined in terms of `mapEndpoints`; for example,\n\n    LineSegment2d.projectOnto axis\n\nis equivalent to\n\n    LineSegment2d.mapEndpoints (Point2d.projectOnto axis)\n\n","type":"(Point2d.Point2d -> Point2d.Point2d) -> LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"midpoint","comment":" Get the midpoint of a line segment.\n\n    LineSegment2d.midpoint exampleLineSegment\n    --> Point2d.fromCoordinates ( 2, 3 )\n\n","type":"LineSegment2d.LineSegment2d -> Point2d.Point2d"},{"name":"mirrorAcross","comment":" Mirror a line segment across an axis.\n\n    LineSegment2d.mirrorAcross Axis2d.y exampleLineSegment\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( -1, 2 )\n    -->     , Point2d.fromCoordinates ( -3, 4 )\n    -->     )\n\nNote that the endpoints of a mirrored segment are equal to the mirrored\nendpoints of the original segment, but as a result the normal direction of a\nmirrored segment is the _opposite_ of the mirrored normal direction of the\noriginal segment (since the normal direction is always considered to be 'to the\nleft' of the line segment).\n\n","type":"Axis2d.Axis2d -> LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"perpendicularDirection","comment":" Get the direction perpendicular to a line segment, pointing to the left. If\nthe line segment has zero length, returns `Nothing`.\n\n    LineSegment2d.perpendicularDirection exampleLineSegment\n    --> Just (Direction2d.fromAngle (degrees 135))\n\n","type":"LineSegment2d.LineSegment2d -> Maybe.Maybe Direction2d.Direction2d"},{"name":"placeIn","comment":" Take a line segment considered to be defined in local coordinates relative\nto a given reference frame, and return that line segment expressed in global\ncoordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    LineSegment2d.placeIn localFrame exampleLineSegment\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 2, 4 )\n    -->     , Point2d.fromCoordinates ( 4, 6 )\n    -->     )\n\n","type":"Frame2d.Frame2d -> LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"projectOnto","comment":" Project a line segment onto an axis.\n\n    LineSegment2d.projectOnto Axis2d.x exampleLineSegment\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 1, 0 )\n    -->     , Point2d.fromCoordinates ( 3, 0 )\n    -->     )\n\n    LineSegment2d.projectOnto Axis2d.y exampleLineSegment\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 0, 2 )\n    -->     , Point2d.fromCoordinates ( 0, 4 )\n    -->     )\n\n","type":"Axis2d.Axis2d -> LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"relativeTo","comment":" Take a line segment defined in global coordinates, and return it expressed\nin local coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    LineSegment2d.relativeTo localFrame exampleLineSegment\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 0, 0 )\n    -->     , Point2d.fromCoordinates ( 2, 2 )\n    -->     )\n\n","type":"Frame2d.Frame2d -> LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"reverse","comment":" Reverse a line segment, swapping its start and end points.\n\n    LineSegment2d.reverse exampleLineSegment\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 3, 4 )\n    -->     , Point2d.fromCoordinates ( 1, 2 )\n    -->     )\n\n","type":"LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"rotateAround","comment":" Rotate a line segment counterclockwise around a given center point by a\ngiven angle (in radians).\n\n    exampleLineSegment\n        |> LineSegment2d.rotateAround Point2d.origin\n            (degrees 90)\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( -2, 1 )\n    -->     , Point2d.fromCoordinates ( -4, 3 )\n    -->     )\n\n","type":"Point2d.Point2d -> Basics.Float -> LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"scaleAbout","comment":" Scale a line segment about the given center point by the given scale.\n\n    point =\n        Point2d.fromCoordinates ( 1, 1 )\n\n    LineSegment2d.scaleAbout point 2 exampleLineSegment\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 1, 3 )\n    -->     , Point2d.fromCoordinates ( 5, 7 )\n    -->     )\n\n","type":"Point2d.Point2d -> Basics.Float -> LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"squaredLength","comment":" Get the squared length of a line segment. Slightly more efficient than\n`length` since it avoids a square root.\n\n    LineSegment2d.squaredLength exampleLineSegment\n    --> 8\n\n","type":"LineSegment2d.LineSegment2d -> Basics.Float"},{"name":"startPoint","comment":" Get the start point of a line segment.\n\n    LineSegment2d.startPoint exampleLineSegment\n    --> Point2d.fromCoordinates ( 1, 2 )\n\n","type":"LineSegment2d.LineSegment2d -> Point2d.Point2d"},{"name":"translateBy","comment":" Translate a line segment by a given displacement.\n\n    displacement =\n        Vector2d.fromComponents ( 1, 2 )\n\n    exampleLineSegment\n        |> LineSegment2d.translateBy displacement\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 2, 4 )\n    -->     , Point2d.fromCoordinates ( 4, 6 )\n    -->     )\n\n","type":"Vector2d.Vector2d -> LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"translateIn","comment":" Translate a line segment in a given direction by a given distance;\n\n    LineSegment2d.translateIn direction distance\n\nis equivalent to\n\n    LineSegment2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> LineSegment2d.LineSegment2d -> LineSegment2d.LineSegment2d"},{"name":"vector","comment":" Get the vector from a given line segment's start point to its end point.\n\n    LineSegment2d.vector exampleLineSegment\n    --> Vector2d.fromComponents ( 2, 2 )\n\n","type":"LineSegment2d.LineSegment2d -> Vector2d.Vector2d"}],"binops":[]},{"name":"LineSegment3d","comment":" A `LineSegment3d` is a line between two points in 3D. This module contains\nfunctionality such as:\n\n  - Interpolating within a line segment or measuring its length\n  - Scaling, rotating, translating, mirroring or projecting a line segment\n  - Converting a line segment between local and global coordinates in different\n    reference frames\n\n@docs LineSegment3d\n\n\n# Constructors\n\n@docs fromEndpoints, from, along, on\n\n\n# Properties\n\n@docs startPoint, endPoint, endpoints, midpoint, length, squaredLength, direction, perpendicularDirection, vector, boundingBox\n\n\n# Interpolation\n\n@docs interpolate\n\n\n# Transformations\n\nTransforming a line segment is equivalent to transforming its start and end\npoints and forming a new line segment between the resulting points.\n\n@docs reverse, scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto, mapEndpoints\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn, projectInto\n\n","unions":[],"aliases":[{"name":"LineSegment3d","comment":" ","args":[],"type":"Geometry.Types.LineSegment3d"}],"values":[{"name":"along","comment":" Construct a line segment lying on the given axis, with its endpoints at the\ngiven distances from the axis' origin point.\n\n    LineSegment3d.along Axis3d.x 3 5\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 3, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 5, 0, 0 )\n    -->     )\n\n    LineSegment3d.along Axis3d.y 2 -4\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 0, 2, 0 )\n    -->     , Point3d.fromCoordinates ( 0, -4, 0 )\n    -->     )\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Basics.Float -> LineSegment3d.LineSegment3d"},{"name":"boundingBox","comment":" Get the minimal bounding box containing a line segment.\n\n    LineSegment3d.boundingBox exampleLineSegment\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 4\n    -->     , minY = 2\n    -->     , maxY = 5\n    -->     , minZ = 3\n    -->     , maxZ = 6\n    -->     }\n\n","type":"LineSegment3d.LineSegment3d -> BoundingBox3d.BoundingBox3d"},{"name":"direction","comment":" Get the direction from a line segment's start point to its end point. If the\nline segment has zero length (the start and end points are the same), returns\n`Nothing`.\n\n    LineSegment3d.direction exampleLineSegment\n    --> Just\n    -->     (Direction3d.fromAzimuthAndElevation\n    -->         (degrees 45)\n    -->         (degrees 35.26)\n    -->     )\n\n","type":"LineSegment3d.LineSegment3d -> Maybe.Maybe Direction3d.Direction3d"},{"name":"endPoint","comment":" Get the end point of a line segment.\n\n    LineSegment3d.endPoint exampleLineSegment\n    --> Point3d.fromCoordinates ( 4, 5, 6 )\n\n","type":"LineSegment3d.LineSegment3d -> Point3d.Point3d"},{"name":"endpoints","comment":" Get the endpoints of a line segment as a tuple.\n\n    ( p1, p2 ) =\n        LineSegment3d.endpoints lineSegment\n\n","type":"LineSegment3d.LineSegment3d -> ( Point3d.Point3d, Point3d.Point3d )"},{"name":"from","comment":" Construct a line segment from the first point to the second;\n\n    LineSegment3d.from firstPoint secondPoint\n\nis equivalent to\n\n    LineSegment3d.fromEndpoints ( firstPoint, secondPoint )\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> LineSegment3d.LineSegment3d"},{"name":"fromEndpoints","comment":" Construct a line segment from its two endpoints:\n\n    exampleLineSegment =\n        LineSegment3d.fromEndpoints\n            ( Point3d.fromCoordinates ( 1, 2, 3 )\n            , Point3d.fromCoordinates ( 4, 5, 6 )\n            )\n\n","type":"( Point3d.Point3d, Point3d.Point3d ) -> LineSegment3d.LineSegment3d"},{"name":"interpolate","comment":" Interpolate a line segment between its start and end points; a value of 0.0\ncorresponds to the start point of the line segment, a value of 0.5 corresponds\nto its midpoint and a value of 1.0 corresponds to its end point. Values less\nthan 0.0 or greater than 1.0 can be used to extrapolate.\n\n    LineSegment3d.interpolate exampleLineSegment (1 / 3)\n    --> Point3d.fromCoordinates ( 2, 4, 5 )\n\n    LineSegment3d.interpolate exampleLineSegment (-1 / 3)\n    --> Point3d.fromCoordinates ( 0, 1, 2 )\n\n","type":"LineSegment3d.LineSegment3d -> Basics.Float -> Point3d.Point3d"},{"name":"length","comment":" Get the length of a line segment.\n\n    LineSegment3d.length exampleLineSegment\n    --> 5.1962\n\n","type":"LineSegment3d.LineSegment3d -> Basics.Float"},{"name":"mapEndpoints","comment":" Transform the start and end points of a line segment by a given function\nand create a new line segment from the resulting points. Most other\ntransformation functions can be defined in terms of `mapEndpoints`; for example,\n\n    LineSegment3d.projectOnto plane\n\nis equivalent to\n\n    LineSegment3d.mapEndpoints (Point3d.projectOnto plane)\n\n","type":"(Point3d.Point3d -> Point3d.Point3d) -> LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"midpoint","comment":" Get the midpoint of a line segment.\n\n    LineSegment3d.midpoint exampleLineSegment\n    --> Point3d.fromCoordinates ( 2.5, 3.5, 4.5 )\n\n","type":"LineSegment3d.LineSegment3d -> Point3d.Point3d"},{"name":"mirrorAcross","comment":" Mirror a line segment across a plane.\n\n    exampleLineSegment\n        |> LineSegment3d.mirrorAcross Plane3d.xy\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 1, 2, -3 )\n    -->     , Point3d.fromCoordinates ( 4, 5, -6 )\n    -->     )\n\n","type":"Plane3d.Plane3d -> LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"on","comment":" Construct a 3D line segment lying _on_ a sketch plane by providing a 2D line\nsegment specified in XY coordinates _within_ the sketch plane.\n\n    LineSegment3d.on SketchPlane3d.yz <|\n        LineSegment2d.fromEndpoints\n            ( Point2d.fromCoordinates ( 1, 2 )\n            , Point2d.fromCoordinates ( 3, 4 )\n            )\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 0, 1, 2 )\n    -->     , Point3d.fromCoordinates ( 0, 3, 4 )\n    -->     )\n\n","type":"SketchPlane3d.SketchPlane3d -> LineSegment2d.LineSegment2d -> LineSegment3d.LineSegment3d"},{"name":"perpendicularDirection","comment":" Get an arbitrary direction perpendicular to a line segment. If the line\nsegment has zero length, returns `Nothing`.\n\n    LineSegment3d.perpendicularDirection exampleLineSegment\n    --> Just\n    -->     (Direction3d.fromAzimuthAndElevation\n    -->         (degrees -90)\n    -->         (degrees 45)\n    -->     )\n\n","type":"LineSegment3d.LineSegment3d -> Maybe.Maybe Direction3d.Direction3d"},{"name":"placeIn","comment":" Take a line segment considered to be defined in local coordinates relative\nto a given reference frame, and return that line segment expressed in global\ncoordinates.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    LineSegment3d.placeIn localFrame exampleLineSegment\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 2, 4, 6 )\n    -->     , Point3d.fromCoordinates ( 5, 7, 9 )\n    -->     )\n\n","type":"Frame3d.Frame3d -> LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"projectInto","comment":" Project a line segment into a given sketch plane. Conceptually, this finds\nthe [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof the line segment onto the plane and then expresses the projected line segment\nin 2D sketch coordinates.\n\n    exampleLineSegment\n        |> LineSegment3d.projectInto SketchPlane3d.xy\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 1, 2 )\n    -->     , Point2d.fromCoordinates ( 4, 5 )\n    -->     )\n\n    exampleLineSegment\n        |> LineSegment3d.projectInto SketchPlane3d.yz\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 2, 3 )\n    -->     , Point2d.fromCoordinates ( 5, 6 )\n    -->     )\n\n    exampleLineSegment\n        |> LineSegment3d.projectInto SketchPlane3d.zx\n    --> LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 3, 1 )\n    -->     , Point2d.fromCoordinates ( 6, 4 )\n    -->     )\n\n","type":"SketchPlane3d.SketchPlane3d -> LineSegment3d.LineSegment3d -> LineSegment2d.LineSegment2d"},{"name":"projectOnto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof a line segment onto a plane.\n\n    LineSegment3d.projectOnto Plane3d.yz exampleLineSegment\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 0, 2, 3 )\n    -->     , Point3d.fromCoordinates ( 0, 5, 6 )\n    -->     )\n\n","type":"Plane3d.Plane3d -> LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"relativeTo","comment":" Take a line segment defined in global coordinates, and return it expressed\nin local coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    LineSegment3d.relativeTo localFrame exampleLineSegment\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 0, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 3, 3, 3 )\n    -->     )\n\n","type":"Frame3d.Frame3d -> LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"reverse","comment":" Reverse a line segment, swapping its start and end points.\n\n    LineSegment3d.reverse exampleLineSegment\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 4, 5, 6 )\n    -->     , Point3d.fromCoordinates ( 1, 2, 3 )\n    -->     )\n\n","type":"LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"rotateAround","comment":" Rotate a line segment around a given axis by a given angle (in radians).\n\n    exampleLineSegment\n        |> LineSegment3d.rotateAround Axis3d.z (degrees 90)\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( -2, 1, 3 )\n    -->     , Point3d.fromCoordinates ( -5, 4, 6 )\n    -->     )\n\n","type":"Axis3d.Axis3d -> Basics.Float -> LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"scaleAbout","comment":" Scale a line segment about the given center point by the given scale.\n\n    point =\n        Point3d.fromCoordinates ( 1, 1, 1 )\n\n    LineSegment3d.scaleAbout point 2 exampleLineSegment\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 1, 3, 5 )\n    -->     , Point3d.fromCoordinates ( 7, 9, 11 )\n    -->     )\n\n","type":"Point3d.Point3d -> Basics.Float -> LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"squaredLength","comment":" Get the squared length of a line segment. Slightly more efficient than\n`length` since it avoids a square root.\n\n    LineSegment3d.squaredLength exampleLineSegment\n    --> 27\n\n","type":"LineSegment3d.LineSegment3d -> Basics.Float"},{"name":"startPoint","comment":" Get the start point of a line segment.\n\n    LineSegment3d.startPoint exampleLineSegment\n    --> Point3d.fromCoordinates ( 1, 2, 3 )\n\n","type":"LineSegment3d.LineSegment3d -> Point3d.Point3d"},{"name":"translateBy","comment":" Translate a line segment by a given displacement.\n\n    displacement =\n        Vector3d.fromComponents ( 1, 2, 3 )\n\n    exampleLineSegment\n        |> LineSegment3d.translateBy displacement\n    --> LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 2, 4, 6 )\n    -->     , Point3d.fromCoordinates ( 5, 7, 9 )\n    -->     )\n\n","type":"Vector3d.Vector3d -> LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"translateIn","comment":" Translate a line segment in a given direction by a given distance;\n\n    LineSegment3d.translateIn direction distance\n\nis equivalent to\n\n    LineSegment3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> LineSegment3d.LineSegment3d -> LineSegment3d.LineSegment3d"},{"name":"vector","comment":" Get the vector from a line segment's start point to its end point.\n\n    LineSegment3d.vector exampleLineSegment\n    --> Vector3d.fromComponents ( 2, 2, 2 )\n\n","type":"LineSegment3d.LineSegment3d -> Vector3d.Vector3d"}],"binops":[]},{"name":"Plane3d","comment":" A `Plane3d` is an infinite flat plane in 3D. It is defined by an origin\npoint and normal direction and is useful for several operations including:\n\n  - Mirroring across the plane\n  - Projecting onto the plane\n  - Measuring distance from the plane\n\n@docs Plane3d\n\n\n# Constants\n\n@docs xy, yz, zx\n\n\n# Constructors\n\n@docs through, withNormalDirection, throughPoints\n\n\n# Properties\n\n@docs originPoint, normalDirection, normalAxis\n\n\n# Transformations\n\n@docs offsetBy, reverseNormal, rotateAround, translateBy, translateIn, moveTo, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Plane3d","comment":" ","args":[],"type":"Geometry.Types.Plane3d"}],"values":[{"name":"mirrorAcross","comment":" Mirror one plane across another. The plane to mirror across is given first\nand the plane to mirror is given second.\n\n    plane =\n        Plane3d.withNormalDirection Direction3d.z\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Plane3d.mirrorAcross Plane3d.xy plane\n    --> Plane3d.withNormalDirection Direction3d.negativeZ\n    -->     (Point3d.fromCoordinates ( 1, 2, -3 ))\n\n","type":"Plane3d.Plane3d -> Plane3d.Plane3d -> Plane3d.Plane3d"},{"name":"moveTo","comment":" Move a plane so that it has the given origin point but unchanged normal\ndirection.\n\n    newOrigin =\n        Point3d.fromCoordinates ( 1, 2, 3 )\n\n    Plane3d.moveTo newOrigin Plane3d.xy\n    --> Plane3d.through newOrigin Direction3d.z\n\n","type":"Point3d.Point3d -> Plane3d.Plane3d -> Plane3d.Plane3d"},{"name":"normalAxis","comment":" Construct an axis from the origin point and normal direction of a plane.\n\n    Plane3d.normalAxis Plane3d.zx\n    --> Axis3d.y\n\n","type":"Plane3d.Plane3d -> Axis3d.Axis3d"},{"name":"normalDirection","comment":" Get the normal direction of a plane.\n\n    Plane3d.normalDirection Plane3d.xy\n    --> Direction3d.z\n\n","type":"Plane3d.Plane3d -> Direction3d.Direction3d"},{"name":"offsetBy","comment":" Shift a plane in its own normal direction by the given (signed) distance.\n\n    Plane3d.offsetBy 1.0 Plane3d.zx\n    --> Plane3d.withNormalDirection Direction3d.y\n    -->     (Point3d.fromCoordinates ( 0, 1, 0 ))\n\n    Plane3d.offsetBy -2.0 Plane3d.xy\n    --> Plane3d.withNormalDirection Direction3d.z\n    -->     (Point3d.fromCoordinates ( 0, 0, -2 ))\n\n","type":"Basics.Float -> Plane3d.Plane3d -> Plane3d.Plane3d"},{"name":"originPoint","comment":" Get the origin point of a plane.\n\n    Plane3d.originPoint Plane3d.xy\n    --> Point3d.origin\n\n","type":"Plane3d.Plane3d -> Point3d.Point3d"},{"name":"placeIn","comment":" Take a plane defined in local coordinates relative to a given reference\nframe, and return that plane expressed in global coordinates.\n\n    referenceFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 1, 1 ))\n\n    plane =\n        Plane3d.withNormalDirection Direction3d.z\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Plane3d.placeIn referenceFrame plane\n    --> Plane3d.withNormalDirection Direction3d.z\n    -->     (Point3d.fromCoordinates ( 2, 3, 4 ))\n\n","type":"Geometry.Types.Frame3d -> Plane3d.Plane3d -> Plane3d.Plane3d"},{"name":"relativeTo","comment":" Take a plane defined in global coordinates, and return it expressed in local\ncoordinates relative to a given reference frame.\n\n    referenceFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 1, 1 ))\n\n    plane =\n        Plane3d.withNormalDirection Direction3d.z\n            (Point3d.fromCoordinates ( 0, 0, 2 ))\n\n    Plane3d.relativeTo referenceFrame plane\n    --> Plane3d.withNormalDirection Direction3d.z\n    -->     (Point3d.fromCoordinates ( -1, -1, 1 ))\n\n","type":"Geometry.Types.Frame3d -> Plane3d.Plane3d -> Plane3d.Plane3d"},{"name":"reverseNormal","comment":" Reverse a plane's normal direction while leaving its origin point unchanged.\n\n    Plane3d.reverseNormal Plane3d.xy\n    --> Plane3d.through Point3d.origin\n    -->     Direction3d.negativeZ\n\n","type":"Plane3d.Plane3d -> Plane3d.Plane3d"},{"name":"rotateAround","comment":" Rotate a plane around an axis by a given angle.\n\n    Plane3d.rotateAround Axis3d.y (degrees 90) Plane3d.xy\n    --> Plane3d.yz\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Plane3d.Plane3d -> Plane3d.Plane3d"},{"name":"through","comment":" Construct a plane through the given point, with the given normal direction.\n\n    xyPlane =\n        Plane3d.through Point3d.origin Direction3d.z\n\n","type":"Point3d.Point3d -> Direction3d.Direction3d -> Plane3d.Plane3d"},{"name":"throughPoints","comment":" Attempt to construct a plane passing through the three given points. The\norigin point of the resulting plane will be equal to the first given point, and\nthe normal direction will be such that the three given points are in\ncounterclockwise order around it according to the right-hand rule. If the three\ngiven points are collinear, returns `Nothing`.\n\n    Plane3d.throughPoints\n        (Point3d.fromCoordinates ( 2, 0, 0 ))\n        (Point3d.fromCoordinates ( 3, 0, 0 ))\n        (Point3d.fromCoordinates ( 4, 1, 1 ))\n    --> Just\n    -->     (Plane3d.through\n    -->         (Point3d.fromCoordinates ( 2, 0, 0 ))\n    -->         (Direction3d.fromAzimuthAndElevation\n    -->             (degrees -90)\n    -->             (degrees 45)\n    -->         )\n    -->     )\n\n    Plane3d.throughPoints\n        (Point3d.fromCoordinates ( 2, 0, 0 ))\n        (Point3d.fromCoordinates ( 3, 0, 0 ))\n        (Point3d.fromCoordinates ( 4, 0, 0 ))\n    --> Nothing\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Point3d.Point3d -> Maybe.Maybe Plane3d.Plane3d"},{"name":"translateBy","comment":" Translate a plane by a given displacement. Applies the given displacement to\nthe plane's origin point and leaves its normal direction unchanged.\n\n    plane =\n        Plane3d.withNormalDirection Direction3d.z\n            (Point3d.fromCoordinates ( 1, 1, 1 ))\n\n    displacement =\n        Vector3d.fromComponents ( 1, 2, 3 )\n\n    Plane3d.translateBy displacement plane\n    --> Plane3d.withNormalDirection Direction3d.z\n    -->     (Point3d.fromCoordinates ( 2, 3, 4 ))\n\n","type":"Vector3d.Vector3d -> Plane3d.Plane3d -> Plane3d.Plane3d"},{"name":"translateIn","comment":" Translate a plane in a given direction by a given distance;\n\n    Plane3d.translateIn direction distance\n\nis equivalent to\n\n    Plane3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> Plane3d.Plane3d -> Plane3d.Plane3d"},{"name":"withNormalDirection","comment":" Construct a plane with the given normal direction, through the given point.\nFlipped version of `through`.\n\n    plane =\n        Plane3d.withNormalDirection Direction3d.y\n            (Point3d.fromCoordinates ( 2, 1, 3 ))\n\n","type":"Direction3d.Direction3d -> Point3d.Point3d -> Plane3d.Plane3d"},{"name":"xy","comment":" The global XY plane, centered at the origin with a normal in the positive Z\ndirection.\n\n    Plane3d.xy\n    --> Plane3d.through Point3d.origin Direction3d.z\n\n","type":"Plane3d.Plane3d"},{"name":"yz","comment":" The global YZ plane, centered at the origin with a normal in the positive X\ndirection.\n\n    Plane3d.yz\n    --> Plane3d.through Point3d.origin Direction3d.x\n\n","type":"Plane3d.Plane3d"},{"name":"zx","comment":" The global ZX plane, centered at the origin with a normal in the positive Y\ndirection.\n\n    Plane3d.zx\n    --> through Point3d.origin Direction3d.y\n\n","type":"Plane3d.Plane3d"}],"binops":[]},{"name":"Point2d","comment":" A `Point2d` represents a position in 2D space and is defined by its X and Y\ncoordinates. This module contains a variety of point-related functionality, such\nas\n\n  - Measuring distance between points\n  - Scaling, rotating, translating, mirroring and projecting points\n  - Converting points between different coordinate systems\n\nPoints are distinct from vectors but interact with them in well-defined ways;\nyou can translate a point by a vector to result in a new point, or you can\ncompute the vector from one point to another, but you cannot 'add' two points\nlike you can add two vectors.\n\n@docs Point2d\n\n\n# Constants\n\n@docs origin\n\n\n# Constructors\n\n@docs fromCoordinates, fromCoordinatesIn, fromPolarCoordinates, fromPolarCoordinatesIn, midpoint, centroid, interpolateFrom, along, circumcenter\n\n\n# Properties\n\n@docs coordinates, xCoordinate, yCoordinate, polarCoordinates\n\n\n# Comparison\n\n@docs equalWithin\n\n\n# Measurement\n\n@docs distanceFrom, squaredDistanceFrom, signedDistanceAlong, signedDistanceFrom\n\n\n# Transformations\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Point2d","comment":" ","args":[],"type":"Geometry.Types.Point2d"}],"values":[{"name":"along","comment":" Construct a point along an axis at a particular distance from the axis'\norigin point.\n\n    Point2d.along Axis2d.y 3\n    --> Point2d.fromCoordinates ( 0, 3 )\n\nPositive and negative distances will be interpreted relative to the direction of\nthe axis:\n\n    horizontalAxis =\n        Axis2d.withDirection Direction2d.negativeX\n            (Point2d.fromCoordinates ( 1, 1 ))\n\n    Point2d.along horizontalAxis 3\n    --> Point2d.fromCoordinates ( -2, 1 )\n\n    Point2d.along horizontalAxis -3\n    --> Point2d.fromCoordinates ( 4, 1 )\n\n","type":"Geometry.Types.Axis2d -> Basics.Float -> Point2d.Point2d"},{"name":"centroid","comment":" Find the centroid of a list of points. Returns `Nothing` if the list is\nempty.\n\n    p0 =\n        Point2d.origin\n\n    p1 =\n        Point2d.fromCoordinates ( 1, 0 )\n\n    p2 =\n        Point2d.fromCoordinates ( 1, 1 )\n\n    Point2d.centroid [ p0, p1, p2 ]\n    --> Just (Point2d.fromCoordinates ( 0.6667, 0.3333 ))\n\n","type":"List.List Point2d.Point2d -> Maybe.Maybe Point2d.Point2d"},{"name":"circumcenter","comment":" Attempt to find the circumcenter of three points; this is the center of the\ncircle that passes through all three points. If the three given points are\ncollinear, returns `Nothing`.\n\n    Point2d.circumcenter\n        ( Point2d.origin\n        , Point2d.fromCoordinates ( 1, 0 )\n        , Point2d.fromCoordinates ( 0, 1 )\n        )\n    --> Just (Point2d.fromCoordinates ( 0.5, 0.5 ))\n\n    Point2d.circumcenter\n        ( Point2d.origin\n        , Point2d.fromCoordinates ( 2, 1 )\n        , Point2d.fromCoordinates ( 4, 0 )\n        )\n    --> Just (Point2d.fromCoordinates ( 2, -1.5 ))\n\n    Point2d.circumCenter\n        ( Point2d.origin\n        , Point2d.fromCoordinates ( 2, 0 )\n        , Point2d.fromCoordinates ( 4, 0 )\n        )\n    --> Nothing\n\n    Point2d.circumCenter\n        ( Point2d.origin\n        , Point2d.origin\n        , Point2d.fromCoordinates ( 1, 0 )\n        )\n    --> Nothing\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Point2d.Point2d -> Maybe.Maybe Point2d.Point2d"},{"name":"coordinates","comment":" Get the coordinates of a point as a tuple.\n\n    ( x, y ) =\n        Point2d.coordinates point\n\n","type":"Point2d.Point2d -> ( Basics.Float, Basics.Float )"},{"name":"distanceFrom","comment":" Find the distance from the first point to the second.\n\n    p1 =\n        Point2d.fromCoordinates ( 2, 3 )\n\n    p2 =\n        Point2d.fromCoordinates ( 5, 7 )\n\n    Point2d.distanceFrom p1 p2\n    --> 5\n\nPartial application can be useful:\n\n    points =\n        [ Point2d.fromCoordinates ( 3, 4 )\n        , Point2d.fromCoordinates ( 10, 0 )\n        , Point2d.fromCoordinates ( -1, 2 )\n        ]\n\n    points\n        |> List.sortBy\n            (Point2d.distanceFrom Point2d.origin)\n    --> [ Point2d.fromCoordinates ( -1, 2 )\n    --> , Point2d.fromCoordinates ( 3, 4 )\n    --> , Point2d.fromCoordinates ( 10, 0 )\n    --> ]\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Basics.Float"},{"name":"equalWithin","comment":" Compare two points within a tolerance. Returns true if the distance\nbetween the two given points is less than the given tolerance.\n\n    firstPoint =\n        Point2d.fromCoordinates ( 1, 2 )\n\n    secondPoint =\n        Point2d.fromCoordinates ( 0.9999, 2.0002 )\n\n    Point2d.equalWithin 1e-3 firstPoint secondPoint\n    --> True\n\n    Point2d.equalWithin 1e-6 firstPoint secondPoint\n    --> False\n\n","type":"Basics.Float -> Point2d.Point2d -> Point2d.Point2d -> Basics.Bool"},{"name":"fromCoordinates","comment":" Construct a point from its X and Y coordinates.\n\n    point =\n        Point2d.fromCoordinates ( 2, 3 )\n\n","type":"( Basics.Float, Basics.Float ) -> Point2d.Point2d"},{"name":"fromCoordinatesIn","comment":" Construct a point given its local coordinates within a particular frame.\n\n    rotatedFrame =\n        Frame2d.atOrigin |> Frame2d.rotateBy (degrees 45)\n\n    Point2d.fromCoordinatesIn rotatedFrame ( 2, 0 )\n    --> Point2d.fromCoordinates ( 1.4142, 1.4142 )\n\nThis is shorthand for using `Point2d.placeIn`;\n\n    Point2d.fromCoordinatesIn frame localCoordinates\n\nis equivalent to\n\n    Point2d.fromCoordinates localCoordinates\n        |> Point2d.placeIn frame\n\n","type":"Geometry.Types.Frame2d -> ( Basics.Float, Basics.Float ) -> Point2d.Point2d"},{"name":"fromPolarCoordinates","comment":" Construct a point from a radius and angle. Radius is measured from the\norigin and angle is measured counterclockwise from the positive X direction.\n\n    Point2d.fromPolarCoordinates ( 2, degrees 135 )\n    --> Point2d.fromCoordinates ( -1.4142, 1.4142 )\n\n","type":"( Basics.Float, Basics.Float ) -> Point2d.Point2d"},{"name":"fromPolarCoordinatesIn","comment":" Construct a point given its local polar coordinates within a particular\nframe.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 2, 1 ))\n\n    Point2d.fromPolarCoordinatesIn localFrame\n        ( 2, degrees 45 )\n    --> Point2d.fromCoordinates ( 3.4142, 2.4142 )\n\n","type":"Geometry.Types.Frame2d -> ( Basics.Float, Basics.Float ) -> Point2d.Point2d"},{"name":"interpolateFrom","comment":" Construct a point by interpolating from the first given point to the second,\nbased on a parameter that ranges from zero to one.\n\n    startPoint =\n        Point2d.origin\n\n    endPoint =\n        Point2d.fromCoordinates ( 8, 12 )\n\n    Point2d.interpolateFrom startPoint endPoint 0.25\n    --> Point2d.fromCoordinates ( 2, 3 )\n\nPartial application may be useful:\n\n    interpolatedPoint : Float -> Point2d\n    interpolatedPoint =\n        Point2d.interpolateFrom startPoint endPoint\n\n    List.map interpolatedPoint [ 0, 0.5, 1 ]\n    --> [ Point2d.fromCoordinates ( 0, 0 )\n    --> , Point2d.fromCoordinates ( 4, 6 )\n    --> , Point2d.fromCoordinates ( 8, 12 )\n    --> ]\n\nYou can pass values less than zero or greater than one to extrapolate:\n\n    interpolatedPoint -0.5\n    --> Point2d.fromCoordinates ( -4, -6 )\n\n    interpolatedPoint 1.25\n    --> Point2d.fromCoordinates ( 10, 15 )\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Basics.Float -> Point2d.Point2d"},{"name":"midpoint","comment":" Construct a point halfway between two other points.\n\n    p1 =\n        Point2d.fromCoordinates ( 1, 1 )\n\n    p2 =\n        Point2d.fromCoordinates ( 3, 7 )\n\n    Point2d.midpoint p1 p2\n    --> Point2d.fromCoordinates ( 2, 4 )\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Point2d.Point2d"},{"name":"mirrorAcross","comment":" Mirror a point across an axis. The result will be the same distance from the\naxis but on the opposite side.\n\n    point =\n        Point2d.fromCoordinates ( 2, 3 )\n\n    Point2d.mirrorAcross Axis2d.x point\n    --> Point2d.fromCoordinates ( 2, -3 )\n\n    Point2d.mirrorAcross Axis2d.y point\n    --> Point2d.fromCoordinates ( -2, 3 )\n\n","type":"Geometry.Types.Axis2d -> Point2d.Point2d -> Point2d.Point2d"},{"name":"origin","comment":" The point (0, 0).\n\n    Point2d.origin\n    --> Point2d.fromCoordinates ( 0, 0 )\n\n","type":"Point2d.Point2d"},{"name":"placeIn","comment":" Take a point defined in local coordinates relative to a given reference\nframe, and return that point expressed in global coordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Point2d.placeIn localFrame\n        (Point2d.fromCoordinates ( 3, 3 ))\n    --> Point2d.fromCoordinates ( 4, 5 )\n\n    Point2d.placeIn localFrame\n        (Point2d.fromCoordinates ( 0, 1 ))\n    --> Point2d.fromCoordinates ( 1, 1 )\n\n","type":"Geometry.Types.Frame2d -> Point2d.Point2d -> Point2d.Point2d"},{"name":"polarCoordinates","comment":" Get the polar coordinates (radius and polar angle) of a point.\n\n    Point2d.polarCoordinates\n        (Point2d.fromCoordinates ( 1, 1 ))\n    --> ( 1.4142, degrees 45 )\n\n","type":"Point2d.Point2d -> ( Basics.Float, Basics.Float )"},{"name":"projectOnto","comment":" Project a point perpendicularly onto an axis.\n\n    point =\n        Point2d.fromCoordinates ( 2, 3 )\n\n    Point2d.projectOnto Axis2d.x point\n    --> Point2d.fromCoordinates ( 2, 0 )\n\n    Point2d.projectOnto Axis2d.y point\n    --> Point2d.fromCoordinates ( 0, 3 )\n\nThe axis does not have to pass through the origin:\n\n    offsetYAxis =\n        Axis2d.withDirection Direction2d.y\n            (Point2d.fromCoordinates ( 1, 0 ))\n\n    Point2d.projectOnto offsetYAxis point\n    --> Point2d.fromCoordinates ( 1, 3 )\n\n","type":"Geometry.Types.Axis2d -> Point2d.Point2d -> Point2d.Point2d"},{"name":"relativeTo","comment":" Take a point defined in global coordinates, and return it expressed in local\ncoordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Point2d.relativeTo localFrame\n        (Point2d.fromCoordinates ( 4, 5 ))\n    --> Point2d.fromCoordinates ( 3, 3 )\n\n    Point2d.relativeTo localFrame\n        (Point2d.fromCoordinates ( 1, 1 ))\n    --> Point2d.fromCoordinates ( 0, -1 )\n\n","type":"Geometry.Types.Frame2d -> Point2d.Point2d -> Point2d.Point2d"},{"name":"rotateAround","comment":" Rotate around a given center point counterclockwise by a given angle (in\nradians). The point to rotate around is given first and the point to rotate is\ngiven last.\n\n    centerPoint =\n        Point2d.fromCoordinates ( 2, 0 )\n\n    angle =\n        degrees 45\n\n    point =\n        Point2d.fromCoordinates ( 3, 0 )\n\n    Point2d.rotateAround centerPoint angle point\n    --> Point2d.fromCoordinates ( 2.7071, 0.7071 )\n\n","type":"Point2d.Point2d -> Basics.Float -> Point2d.Point2d -> Point2d.Point2d"},{"name":"scaleAbout","comment":" Perform a uniform scaling about the given center point. The center point is\ngiven first and the point to transform is given last. Points will contract or\nexpand about the center point by the given scale. Scaling by a factor of 1 is a\nno-op, and scaling by a factor of 0 collapses all points to the center point.\n\n    centerPoint =\n        Point2d.fromCoordinates ( 1, 1 )\n\n    point =\n        Point2d.fromCoordinates ( 2, 3 )\n\n    Point2d.scaleAbout centerPoint 3 point\n    --> Point2d.fromCoordinates ( 4, 7 )\n\n    Point2d.scaleAbout centerPoint 0.5 point\n    --> Point2d.fromCoordinates ( 1.5, 2 )\n\nAvoid scaling by a negative scaling factor - while this may sometimes do what\nyou want it is confusing and error prone. Try a combination of mirror and/or\nrotation operations instead.\n\n","type":"Point2d.Point2d -> Basics.Float -> Point2d.Point2d -> Point2d.Point2d"},{"name":"signedDistanceAlong","comment":" Determine how far along an axis a particular point lies. Conceptually, the\npoint is projected perpendicularly onto the axis, and then the distance of this\nprojected point from the axis' origin point is measured. The result will be\npositive if the projected point is ahead the axis' origin point and negative if\nit is behind, with 'ahead' and 'behind' defined by the direction of the axis.\n\n    axis =\n        Axis2d.withDirection Direction2d.x\n            (Point2d.fromCoordinates ( 1, 2 ))\n\n    point =\n        Point2d.fromCoordinates ( 3, 3 )\n\n    Point2d.signedDistanceAlong axis point\n    --> 2\n\n    Point2d.signedDistanceAlong axis Point2d.origin\n    --> -1\n\n","type":"Geometry.Types.Axis2d -> Point2d.Point2d -> Basics.Float"},{"name":"signedDistanceFrom","comment":" Find the perpendicular distance of a point from an axis. The result\nwill be positive if the point is to the left of the axis and negative if it is\nto the right, with the forwards direction defined by the direction of the axis.\n\n    -- A horizontal axis through a point with a Y\n    -- coordinate of 2 is effectively the line Y=2\n    axis =\n        Axis2d.withDirection Direction2d.x\n            (Point2d.fromCoordinates ( 1, 2 ))\n\n    point =\n        Point2d.fromCoordinates ( 3, 3 )\n\n    -- Since the axis is in the positive X direction,\n    -- points above the axis are to the left (positive)\n    Point2d.signedDistanceFrom axis point\n    -->  1\n\n    -- and points below are to the right (negative)\n    Point2d.signedDistanceFrom axis Point2d.origin\n    --> -2\n\nThis means that reversing an axis will also flip the sign of the result of this\nfunction:\n\n    -- Reversing an axis reverses its direction\n    reversedAxis =\n        Axis2d.reverse axis\n\n    Point2d.signedDistanceFrom reversedAxis point\n    --> -1\n\n    Point2d.signedDistanceFrom reversedAxis Point2d.origin\n    --> 2\n\n","type":"Geometry.Types.Axis2d -> Point2d.Point2d -> Basics.Float"},{"name":"squaredDistanceFrom","comment":" Find the square of the distance from one point to another.\n`squaredDistanceFrom` is slightly faster than `distanceFrom`, so for example\n\n    Point2d.squaredDistanceFrom p1 p2\n        > (tolerance * tolerance)\n\nis equivalent to but slightly more efficient than\n\n    Point2d.distanceFrom p1 p2 > tolerance\n\nsince the latter requires a square root under the hood. In many cases, however,\nthe speed difference will be negligible and using `distanceFrom` is much more\nreadable!\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Basics.Float"},{"name":"translateBy","comment":" Translate a point by a given displacement.\n\n    point =\n        Point2d.fromCoordinates ( 3, 4 )\n\n    displacement =\n        Vector2d.fromComponents ( 1, 2 )\n\n    Point2d.translateBy displacement point\n    --> Point2d.fromCoordinates ( 4, 6 )\n\nIn more mathematical terms, this is 'point plus vector'. For 'point minus point'\n(giving the vector from one point to another), there is [`Vector2d.from`](Vector2d#from).\n\n","type":"Vector2d.Vector2d -> Point2d.Point2d -> Point2d.Point2d"},{"name":"translateIn","comment":" Translate a point in a given direction by a given distance.\n\n    point =\n        Point2d.fromCoordinates ( 3, 4 )\n\n    point |> Point2d.translateIn Direction2d.x 2\n    --> Point2d.fromCoordinates ( 5, 4 )\n\n    point |> Point2d.translateIn Direction2d.y 2\n    --> Point2d.fromCoordinates ( 3, 6 )\n\n    angledDirection =\n        Direction2d.fromAngle (degrees 45)\n\n    point |> Point2d.translateIn angledDirection 1\n    --> Point2d.fromCoordinates ( 3.7071, 4.7071 )\n\nThe distance can be negative:\n\n    Point2d.translateIn Direction2d.x -2\n    --> Point2d.fromCoordinates ( 1, 4 )\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Point2d.Point2d -> Point2d.Point2d"},{"name":"xCoordinate","comment":" Get the X coordinate of a point.\n\n    Point2d.xCoordinate (Point2d.fromCoordinates ( 2, 3 ))\n    --> 2\n\n","type":"Point2d.Point2d -> Basics.Float"},{"name":"yCoordinate","comment":" Get the Y coordinate of a point.\n\n    Point2d.yCoordinate (Point2d.fromCoordinates ( 2, 3 ))\n    --> 3\n\n","type":"Point2d.Point2d -> Basics.Float"}],"binops":[]},{"name":"Point3d","comment":" A `Point3d` represents a position in 3D space and is defined by its X, Y and\nZ coordinates. This module contains a variety of point-related functionality,\nsuch as\n\n  - Measuring distance between points, or the distance of a point from an axis\n    or a plane\n  - Scaling, rotating, translating, mirroring and projecting points\n  - Converting points between different coordinate systems\n\nPoints are distinct from vectors but interact with them in well-defined ways;\nyou can translate a point by a vector to result in a new point, or you can\ncompute the vector from one point to another, but you cannot 'add' two points\nlike you can add two vectors.\n\n@docs Point3d\n\n\n# Constants\n\n@docs origin\n\n\n# Constructors\n\n@docs fromCoordinates, fromCoordinatesIn, midpoint, centroid, interpolateFrom, along, on, circumcenter\n\n\n# Properties\n\n@docs coordinates, xCoordinate, yCoordinate, zCoordinate\n\n\n# Comparison\n\n@docs equalWithin\n\n\n# Measurement\n\n@docs distanceFrom, squaredDistanceFrom, signedDistanceAlong, distanceFromAxis, squaredDistanceFromAxis, signedDistanceFrom\n\n\n# Transformations\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto, projectOntoAxis\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn, projectInto\n\n","unions":[],"aliases":[{"name":"Point3d","comment":" ","args":[],"type":"Geometry.Types.Point3d"}],"values":[{"name":"along","comment":" Construct a point along an axis at a particular distance from the axis'\norigin point.\n\n    Point3d.along Axis3d.z 2\n    --> Point3d.fromCoordinates ( 0, 0, 2 )\n\nPositive and negative distances are interpreted relative to the direction of the\naxis:\n\n    horizontalAxis =\n        Axis3d.withDirection Direction3d.negativeX\n            (Point3d.fromCoordinates ( 1, 1, 1 ))\n\n    Point3d.along horizontalAxis 3\n    --> Point3d.fromCoordinates ( -2, 1, 1 )\n\n    Point3d.along horizontalAxis -3\n    --> Point3d.fromCoordinates ( 4, 1, 1 )\n\n","type":"Geometry.Types.Axis3d -> Basics.Float -> Point3d.Point3d"},{"name":"centroid","comment":" Find the centroid of a list of points. Returns `Nothing` if the list is\nempty.\n\n    p0 =\n        Point3d.origin\n\n    p1 =\n        Point3d.fromCoordinates ( 1, 0, 1 )\n\n    p2 =\n        Point3d.fromCoordinates ( 0, 1, 1 )\n\n    Point3d.centroid [ p0, p1, p2 ]\n    --> Just (Point3d.fromCoordinates ( 0.3333, 0.3333, 0.6667 ))\n\n","type":"List.List Point3d.Point3d -> Maybe.Maybe Point3d.Point3d"},{"name":"circumcenter","comment":" Attempt to find the circumcenter of three points; this is the center of the\ncircle that passes through all three points. If the three given points are\ncollinear, returns `Nothing`.\n\n    Point3d.circumcenter\n        (Point3d.fromCoordinates ( 1, 0, 0 ))\n        (Point3d.fromCoordinates ( 0, 1, 0 ))\n        (Point3d.fromCoordinates ( 0, 0, 1 ))\n    --> Just (Point3d.fromCoordinates (0.33, 0.33, 0.33))\n\n    Point3d.circumcenter\n        Point3d.origin\n        (Point3d.fromCoordinates ( 1, 0, 0 ))\n        (Point3d.fromCoordinates ( 2, 0, 0 ))\n    --> Nothing\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Point3d.Point3d -> Maybe.Maybe Point3d.Point3d"},{"name":"coordinates","comment":" Get the coordinates of a point as a tuple.\n\n    ( x, y, z ) =\n        Point3d.coordinates point\n\n","type":"Point3d.Point3d -> ( Basics.Float, Basics.Float, Basics.Float )"},{"name":"distanceFrom","comment":" Find the distance from the first point to the second.\n\n    p1 =\n        Point3d.fromCoordinates ( 1, 1, 2 )\n\n    p2 =\n        Point3d.fromCoordinates ( 2, 3, 4 )\n\n    Point3d.distanceFrom p1 p2\n    --> 3\n\nPartial application can be useful:\n\n    points =\n        [ Point3d.fromCoordinates ( 3, 4, 5 )\n        , Point3d.fromCoordinates ( 10, 10, 10 )\n        , Point3d.fromCoordinates ( -1, 2, -3 )\n        ]\n\n    points\n        |> List.sortBy\n            (Point3d.distanceFrom Point3d.origin)\n    --> [ Point3d.fromCoordinates ( -1, 2, -3 )\n    --> , Point3d.fromCoordinates ( 3, 4, 5 )\n    --> , Point3d.fromCoordinates ( 10, 10, 10 )\n    --> ]\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Basics.Float"},{"name":"distanceFromAxis","comment":" Find the perpendicular (nearest) distance of a point from an axis.\n\n    point =\n        Point3d.fromCoordinates ( -3, 4, 0 )\n\n    Point3d.distanceFromAxis Axis3d.x point\n    --> 4\n\n    Point3d.distanceFromAxis Axis3d.y point\n    --> 3\n\n    Point3d.distanceFromAxis Axis3d.z point\n    --> 5\n\nNote that unlike in 2D, the result is always positive (unsigned) since there is\nno such thing as the left or right side of an axis in 3D.\n\n","type":"Geometry.Types.Axis3d -> Point3d.Point3d -> Basics.Float"},{"name":"equalWithin","comment":" Compare two points within a tolerance. Returns true if the distance\nbetween the two given points is less than the given tolerance.\n\n    firstPoint =\n        Point3d.fromCoordinates ( 2, 1, 3 )\n\n    secondPoint =\n        Point3d.fromCoordinates ( 2.0002, 0.9999, 3.0001 )\n\n    Point3d.equalWithin 1e-3 firstPoint secondPoint\n    --> True\n\n    Point3d.equalWithin 1e-6 firstPoint secondPoint\n    --> False\n\n","type":"Basics.Float -> Point3d.Point3d -> Point3d.Point3d -> Basics.Bool"},{"name":"fromCoordinates","comment":" Construct a point from its X, Y and Z coordinates.\n\n    point =\n        Point3d.fromCoordinates ( 2, 1, 3 )\n\n","type":"( Basics.Float, Basics.Float, Basics.Float ) -> Point3d.Point3d"},{"name":"fromCoordinatesIn","comment":" Construct a point given its local coordinates within a particular frame.\n\n    frame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 1, 1 ))\n\n    Point3d.fromCoordinatesIn frame ( 1, 2, 3 )\n    --> Point3d.fromCoordinates ( 2, 3, 4 )\n\nThis is shorthand for using `Point3d.placeIn`;\n\n    Point3d.fromCoordinatesIn frame localCoordinates\n\nis equivalent to\n\n    Point3d.fromCoordinates localCoordinates\n        |> Point3d.placeIn frame\n\n","type":"Geometry.Types.Frame3d -> ( Basics.Float, Basics.Float, Basics.Float ) -> Point3d.Point3d"},{"name":"interpolateFrom","comment":" Construct a point by interpolating from the first given point to the second,\nbased on a parameter that ranges from zero to one.\n\n    startPoint =\n        Point3d.fromCoordinates ( 1, 2, 4 )\n\n    endPoint =\n        Point3d.fromCoordinates ( 1, 2, 8 )\n\n    Point3d.interpolateFrom startPoint endPoint 0.25\n    --> Point3d.fromCoordinates ( 1, 2, 5 )\n\nPartial application may be useful:\n\n    interpolatedPoint : Float -> Point3d\n    interpolatedPoint =\n        Point3d.interpolateFrom startPoint endPoint\n\n    List.map interpolatedPoint [ 0, 0.5, 1 ]\n    --> [ Point3d.fromCoordinates ( 1, 2, 4 )\n    --> , Point3d.fromCoordinates ( 1, 2, 6 )\n    --> , Point3d.fromCoordinates ( 1, 2, 8 )\n    --> ]\n\nYou can pass values less than zero or greater than one to extrapolate:\n\n    interpolatedPoint -0.5\n    --> Point3d.fromCoordinates ( 1, 2, 2 )\n\n    interpolatedPoint 1.25\n    --> Point3d.fromCoordinates ( 1, 2, 9 )\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Basics.Float -> Point3d.Point3d"},{"name":"midpoint","comment":" Construct a point halfway between two other points.\n\n    p1 =\n        Point3d.fromCoordinates ( 1, 1, 1 )\n\n    p2 =\n        Point3d.fromCoordinates ( 3, 7, 9 )\n\n    Point3d.midpoint p1 p2\n    --> Point3d.fromCoordinates ( 2, 4, 5 )\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Point3d.Point3d"},{"name":"mirrorAcross","comment":" Mirror a point across a plane. The result will be the same distance from the\nplane but on the opposite side.\n\n    point =\n        Point3d.fromCoordinates ( 1, 2, 3 )\n\n    -- Plane3d.xy is the plane Z=0\n    Point3d.mirrorAcross Plane3d.xy point\n    --> Point3d.fromCoordinates ( 1, 2, -3 )\n\n    -- Plane3d.yz is the plane X=0\n    Point3d.mirrorAcross Plane3d.yz point\n    --> Point3d.fromCoordinates ( -1, 2, 3 )\n\nThe plane does not have to pass through the origin:\n\n    -- offsetPlane is the plane Z=1\n    offsetPlane =\n        Plane3d.offsetBy 1 Plane3d.xy\n\n    -- The origin point is 1 unit below the offset\n    -- plane, so its mirrored copy is one unit above\n    Point3d.mirrorAcross offsetPlane Point3d.origin\n    --> Point3d.fromCoordinates ( 0, 0, 2 )\n\n","type":"Geometry.Types.Plane3d -> Point3d.Point3d -> Point3d.Point3d"},{"name":"on","comment":" Construct a 3D point lying _on_ a sketch plane by providing a 2D point\nspecified in XY coordinates _within_ the sketch plane.\n\n    Point3d.on SketchPlane3d.xy <|\n        Point2d.fromCoordinates ( 2, 1 )\n    --> Point3d.fromCoordinates ( 2, 1, 0 )\n\n    Point3d.on SketchPlane3d.xz <|\n        Point2d.fromCoordinates ( 2, 1 )\n    --> Point3d.fromCoordinates ( 2, 0, 1 )\n\nThe sketch plane can have any position and orientation:\n\n    tiltedSketchPlane =\n        SketchPlane3d.xy\n            |> SketchPlane3d.rotateAround Axis3d.x\n                (degrees 45)\n            |> SketchPlane3d.moveTo\n                (Point3d.fromCoordinates ( 10, 10, 10 ))\n\n    Point3d.on tiltedSketchPlane <|\n        Point2d.fromCoordinates ( 2, 1 )\n    --> Point3d.fromCoordinates ( 12, 10.7071, 10.7071 )\n\n","type":"Geometry.Types.SketchPlane3d -> Point2d.Point2d -> Point3d.Point3d"},{"name":"origin","comment":" The point (0, 0, 0).\n\n    Point3d.origin\n    --> Point3d.fromCoordinates ( 0, 0, 0 )\n\n","type":"Point3d.Point3d"},{"name":"placeIn","comment":" Take a point defined in local coordinates relative to a given reference\nframe, and return that point expressed in global coordinates.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Point3d.placeIn localFrame\n        (Point3d.fromCoordinates ( 3, 3, 3 ))\n    --> Point3d.fromCoordinates ( 4, 5, 6 )\n\n    Point3d.placeIn localFrame\n        (Point3d.fromCoordinates ( 0, -1, -2 ))\n    --> Point3d.fromCoordinates ( 1, 1, 1 )\n\n","type":"Geometry.Types.Frame3d -> Point3d.Point3d -> Point3d.Point3d"},{"name":"projectInto","comment":" Project a point into a given sketch plane. Conceptually, this finds the\n[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof the point onto the plane and then expresses the projected point in 2D sketch\ncoordinates.\n\n    point =\n        Point3d.fromCoordinates ( 2, 1, 3 )\n\n    Point3d.projectInto SketchPlane3d.xy point\n    --> Point2d.fromCoordinates ( 2, 1 )\n\n    Point3d.projectInto SketchPlane3d.yz point\n    --> Point2d.fromCoordinates ( 1, 3 )\n\n    Point3d.projectInto SketchPlane3d.zx point\n    --> Point2d.fromCoordinates ( 3, 2 )\n\n","type":"Geometry.Types.SketchPlane3d -> Point3d.Point3d -> Point2d.Point2d"},{"name":"projectOnto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof a point onto a plane:\n\n    point =\n        Point3d.fromCoordinates ( 1, 2, 3 )\n\n    Point3d.projectOnto Plane3d.xy point\n    --> Point3d.fromCoordinates ( 1, 2, 0 )\n\n    Point3d.projectOnto Plane3d.yz point\n    --> Point3d.fromCoordinates ( 0, 2, 3 )\n\nThe plane does not have to pass through the origin:\n\n    offsetPlane =\n        Plane3d.offsetBy 1 Plane3d.xy\n\n    Point3d.projectOnto offsetPlane point\n    --> Point3d.fromCoordinates ( 1, 2, 1 )\n\n","type":"Geometry.Types.Plane3d -> Point3d.Point3d -> Point3d.Point3d"},{"name":"projectOntoAxis","comment":" Project a point perpendicularly onto an axis.\n\n    point =\n        Point3d.fromCoordinates ( 1, 2, 3 )\n\n    Point3d.projectOntoAxis Axis3d.x\n    --> Point3d.fromCoordinates ( 1, 0, 0 )\n\n    verticalAxis =\n        Axis3d.withDirection Direction3d.z\n            (Point3d.fromCoordinates ( 0, 1, 2 ))\n\n    Point3d.projectOntoAxis verticalAxis\n    --> Point3d.fromCoordinates ( 0, 1, 3 )\n\n","type":"Geometry.Types.Axis3d -> Point3d.Point3d -> Point3d.Point3d"},{"name":"relativeTo","comment":" Take a point defined in global coordinates, and return it expressed in local\ncoordinates relative to a given reference frame.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Point3d.relativeTo localFrame\n        (Point3d.fromCoordinates ( 4, 5, 6 ))\n    --> Point3d.fromCoordinates ( 3, 3, 3 )\n\n    Point3d.relativeTo localFrame\n        (Point3d.fromCoordinates ( 1, 1, 1 ))\n    --> Point3d.fromCoordinates ( 0, -1, -2 )\n\n","type":"Geometry.Types.Frame3d -> Point3d.Point3d -> Point3d.Point3d"},{"name":"rotateAround","comment":" Rotate a point around an axis by a given angle (in radians).\n\n    axis =\n        Axis3d.x\n\n    angle =\n        degrees 45\n\n    point =\n        Point3d.fromCoordinates ( 3, 1, 0 )\n\n    Point3d.rotateAround axis angle point\n    --> Point3d.fromCoordinates ( 3, 0.7071, 0.7071 )\n\nRotation direction is given by the right-hand rule, counterclockwise around the\ndirection of the axis.\n\n","type":"Geometry.Types.Axis3d -> Basics.Float -> Point3d.Point3d -> Point3d.Point3d"},{"name":"scaleAbout","comment":" Perform a uniform scaling about the given center point. The center point is\ngiven first and the point to transform is given last. Points will contract or\nexpand about the center point by the given scale. Scaling by a factor of 1 is a\nno-op, and scaling by a factor of 0 collapses all points to the center point.\n\n    centerPoint =\n        Point3d.fromCoordinates ( 1, 1, 1 )\n\n    point =\n        Point3d.fromCoordinates ( 1, 2, 3 )\n\n    Point3d.scaleAbout centerPoint 3 point\n    --> Point3d.fromCoordinates ( 1, 4, 7 )\n\n    Point3d.scaleAbout centerPoint 0.5 point\n    --> Point3d.fromCoordinates ( 1, 1.5, 2 )\n\nAvoid scaling by a negative scaling factor - while this may sometimes do what\nyou want it is confusing and error prone. Try a combination of mirror and/or\nrotation operations instead.\n\n","type":"Point3d.Point3d -> Basics.Float -> Point3d.Point3d -> Point3d.Point3d"},{"name":"signedDistanceAlong","comment":" Determine how far along an axis a particular point lies. Conceptually, the\npoint is projected perpendicularly onto the axis, and then the distance of this\nprojected point from the axis' origin point is measured. The result will be\npositive if the projected point is ahead the axis' origin point and negative if\nit is behind, with 'ahead' and 'behind' defined by the direction of the axis.\n\n    axis =\n        Axis3d.withDirection Direction3d.x\n            (Point3d.fromCoordinates ( 1, 0, 0 ))\n\n    point =\n        Point3d.fromCoordinates ( 3, 3, 3 )\n\n    Point3d.signedDistanceAlong axis point\n    --> 2\n\n    Point3d.signedDistanceAlong axis Point3d.origin\n    --> -1\n\n","type":"Geometry.Types.Axis3d -> Point3d.Point3d -> Basics.Float"},{"name":"signedDistanceFrom","comment":" Find the perpendicular distance of a point from a plane. The result will be\npositive if the point is 'above' the plane and negative if it is 'below', with\n'up' defined by the normal direction of the plane.\n\n    plane =\n        Plane3d.withNormalDirection Direction3d.y\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    point =\n        Point3d.fromCoordinates ( 3, 3, 3 )\n\n    Point3d.signedDistanceFrom plane point\n    --> 1\n\n    Point3d.signedDistanceFrom plane Point3d.origin\n    --> -2\n\nThis means that flipping a plane (reversing its normal direction) will also flip\nthe sign of the result of this function:\n\n    flippedPlane =\n        Plane3d.reverseNormal plane\n\n    Point3d.signedDistanceFrom flippedPlane point\n    --> -1\n\n    Point3d.signedDistanceFrom flippedPlane Point3d.origin\n    --> 2\n\n","type":"Geometry.Types.Plane3d -> Point3d.Point3d -> Basics.Float"},{"name":"squaredDistanceFrom","comment":" Find the square of the distance from one point to another.\n`squaredDistanceFrom` is slightly faster than `distanceFrom`, so for example\n\n    Point3d.squaredDistanceFrom p1 p2\n        > (tolerance * tolerance)\n\nis equivalent to but slightly more efficient than\n\n    Point3d.distanceFrom p1 p2 > tolerance\n\nsince the latter requires a square root under the hood. In many cases, however,\nthe speed difference will be negligible and using `distanceFrom` is much more\nreadable!\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Basics.Float"},{"name":"squaredDistanceFromAxis","comment":" Find the square of the perpendicular distance of a point from an axis. As\nwith `distanceFrom`/`squaredDistanceFrom` this is slightly more efficient than\n`distanceFromAxis` since it avoids a square root.\n","type":"Geometry.Types.Axis3d -> Point3d.Point3d -> Basics.Float"},{"name":"translateBy","comment":" Translate a point by a given displacement.\n\n    point =\n        Point3d.fromCoordinates ( 3, 4, 5 )\n\n    displacement =\n        Vector3d.fromComponents ( 1, 2, 3 )\n\n    Point3d.translateBy displacement point\n    --> Point3d.fromCoordinates ( 4, 6, 8 )\n\nIn more mathematical terms, this is 'point plus vector'. For 'point minus point'\n(giving the vector from one point to another), there is [`Vector3d.from`](Vector3d#from).\n\n","type":"Vector3d.Vector3d -> Point3d.Point3d -> Point3d.Point3d"},{"name":"translateIn","comment":" Translate a point in a given direction by a given distance.\n\n    point =\n        Point3d.fromCoordinates ( 3, 4, 5 )\n\n    point |> Point3d.translateIn Direction3d.x 2\n    --> Point3d.fromCoordinates ( 5, 4, 5 )\n\n    point |> Point3d.translateIn Direction3d.y 2\n    --> Point3d.fromCoordinates ( 3, 6, 5 )\n\nThe distance can be negative:\n\n    Point3d.translateIn Direction3d.x -2\n    --> Point3d.fromCoordinates ( 1, 4, 5 )\n\n","type":"Direction3d.Direction3d -> Basics.Float -> Point3d.Point3d -> Point3d.Point3d"},{"name":"xCoordinate","comment":" Get the X coordinate of a point.\n\n    Point3d.fromCoordinates ( 2, 1, 3 )\n        |> Point3d.xCoordinate\n    --> 2\n\n","type":"Point3d.Point3d -> Basics.Float"},{"name":"yCoordinate","comment":" Get the Y coordinate of a point.\n\n    Point3d.fromCoordinates ( 2, 1, 3 )\n        |> Point3d.yCoordinate\n    --> 1\n\n","type":"Point3d.Point3d -> Basics.Float"},{"name":"zCoordinate","comment":" Get the Z coordinate of a point.\n\n    Point3d.fromCoordinates ( 2, 1, 3 )\n        |> Point3d.zCoordinate\n    --> 3\n\n","type":"Point3d.Point3d -> Basics.Float"}],"binops":[]},{"name":"Polygon2d","comment":" A `Polygon2d` represents a closed polygon in 2D, optionally with holes. It\nis defined by an outer loop of vertices and a list of inner loops defining any\nholes. This module contains a variety of polygon-related functionality, such as\n\n  - Computing the perimeter and area of polygons\n  - Scaling, rotating, translating and mirroring polygons\n  - Converting polygons between different coordinate systems\n  - Triangulating polygons\n\n@docs Polygon2d\n\n\n# Constructors\n\n@docs singleLoop, with, convexHull\n\n\n# Properties\n\n@docs outerLoop, innerLoops, vertices, edges, perimeter, area, boundingBox\n\n\n# Transformations\n\nTransforming a polygon is equivalent to transforming each of its vertices.\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n\n# Triangulation\n\n@docs triangulate\n\n","unions":[],"aliases":[{"name":"Polygon2d","comment":" ","args":[],"type":"Geometry.Types.Polygon2d"}],"values":[{"name":"area","comment":" Get the area of a polygon. This value will never be negative.\n\n    Polygon2d.area squareWithHole\n    --> 8\n\n","type":"Polygon2d.Polygon2d -> Basics.Float"},{"name":"boundingBox","comment":" Get the minimal bounding box containing a given polygon. Returns `Nothing`\nif the polygon has no vertices.\n\n    Polygon2d.boundingBox rectangle\n    --> Just\n    -->     (BoundingBox2d.fromExtrema\n    -->         { minX = 1\n    -->         , maxX = 3\n    -->         , minY = 1\n    -->         , maxY = 2\n    -->         }\n    -->     )\n\n","type":"Polygon2d.Polygon2d -> Maybe.Maybe BoundingBox2d.BoundingBox2d"},{"name":"convexHull","comment":" Build the [convex hull](https://en.wikipedia.org/wiki/Convex_hull) of a list\nof points:\n\n![Convex hull of a set of points](https://ianmackenzie.github.io/elm-geometry/1.0.0/Polygon2d/convexHull.svg)\n\nThis is an O(n log n) operation.\n\n","type":"List.List Point2d.Point2d -> Polygon2d.Polygon2d"},{"name":"edges","comment":" Get all edges of a polygon. This will include both outer edges and inner\n(hole) edges.\n\n    Polygon2d.edges squareWithHole\n    --> [ LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 0, 0 )\n    -->     , Point2d.fromCoordinates ( 3, 0 )\n    -->     )\n    --> , LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 3, 0 )\n    -->     , Point2d.fromCoordinates ( 3, 3 )\n    -->     )\n    --> , LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 3, 3 )\n    -->     , Point2d.fromCoordinates ( 0, 3 )\n    -->     )\n    --> , LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 0, 3 )\n    -->     , Point2d.fromCoordinates ( 0, 0 )\n    -->     )\n    --> , LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 1, 1 )\n    -->     , Point2d.fromCoordinates ( 1, 2 )\n    -->     )\n    --> , LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 1, 2 )\n    -->     , Point2d.fromCoordinates ( 2, 2 )\n    -->     )\n    --> , LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 2, 2 )\n    -->     , Point2d.fromCoordinates ( 2, 1 )\n    -->     )\n    --> , LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 2, 1 )\n    -->     , Point2d.fromCoordinates ( 1, 1 )\n    -->     )\n    --> ]\n\n","type":"Polygon2d.Polygon2d -> List.List LineSegment2d.LineSegment2d"},{"name":"innerLoops","comment":" Get the holes (if any) of a polygon, each defined by a list of vertices.\nEach list of vertices will be in clockwise order.\n\n    Polygon2d.innerLoops squareWithHole\n    --> [ [ Point2d.fromCoordinates ( 1, 1 )\n    -->   , Point2d.fromCoordinates ( 1, 2 )\n    -->   , Point2d.fromCoordinates ( 2, 2 )\n    -->   , Point2d.fromCoordinates ( 2, 1 )\n    -->   ]\n    --> ]\n\n","type":"Polygon2d.Polygon2d -> List.List (List.List Point2d.Point2d)"},{"name":"mirrorAcross","comment":" Mirror a polygon across the given axis.\n\n    Polygon2d.mirrorAcross Axis2d.x rectangle\n    --> Polygon2d.singleLoop\n    -->     [ Point2d.fromCoordinates ( 1, -1 )\n    -->     , Point2d.fromCoordinates ( 3, -1 )\n    -->     , Point2d.fromCoordinates ( 3, -2 )\n    -->     , Point2d.fromCoordinates ( 1, -2 )\n    -->     ]\n\nThe order of the polygon's vertices will be reversed so that the resulting\npolygon still has its outer vertices in counterclockwise order and its inner\nvertices in clockwise order.\n\n","type":"Axis2d.Axis2d -> Polygon2d.Polygon2d -> Polygon2d.Polygon2d"},{"name":"outerLoop","comment":" Get the list of vertices definining the outer loop (border) of a polygon.\nThe vertices will be in counterclockwise order.\n\n    Polygon2d.outerLoop squareWithHole\n    --> [ Point2d.fromCoordinates ( 0, 0 )\n    --> , Point2d.fromCoordinates ( 3, 0 )\n    --> , Point2d.fromCoordinates ( 3, 3 )\n    --> , Point2d.fromCoordinates ( 0, 3 )\n    --> ]\n\n","type":"Polygon2d.Polygon2d -> List.List Point2d.Point2d"},{"name":"perimeter","comment":" Get the perimeter of a polygon (the sum of the lengths of its edges). This\nincludes the outer perimeter and the perimeter of any holes.\n\n    Polygon2d.perimeter squareWithHole\n    --> 16\n\n","type":"Polygon2d.Polygon2d -> Basics.Float"},{"name":"placeIn","comment":" Take a polygon considered to be defined in local coordinates relative\nto a given reference frame, and return that polygon expressed in global\ncoordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Polygon2d.placeIn localFrame rectangle\n    --> Polygon2d.singleLoop\n    -->     [ Point2d.fromCoordinates ( 2, 3 )\n    -->     , Point2d.fromCoordinates ( 4, 3 )\n    -->     , Point2d.fromCoordinates ( 4, 4 )\n    -->     , Point2d.fromCoordinates ( 2, 4 )\n    -->     ]\n\nIf the given frame is left-handed, the order of the polygon's vertices will be\nreversed so that the resulting polygon still has its outer vertices in\ncounterclockwise order and its inner vertices in clockwise order.\n\n","type":"Frame2d.Frame2d -> Polygon2d.Polygon2d -> Polygon2d.Polygon2d"},{"name":"relativeTo","comment":" Take a polygon defined in global coordinates, and return it expressed\nin local coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Polygon2d.relativeTo localFrame rectangle\n    --> Polygon2d.singleLoop\n    -->     [ Point2d.fromCoordinates ( 0, -1 )\n    -->     , Point2d.fromCoordinates ( 2, -1 )\n    -->     , Point2d.fromCoordinates ( 2, 0 )\n    -->     , Point2d.fromCoordinates ( 0, 0 )\n    -->     ]\n\nIf the given frame is left-handed, the order of the polygon's vertices will be\nreversed so that the resulting polygon still has its outer vertices in\ncounterclockwise order and its inner vertices in clockwise order.\n\n","type":"Frame2d.Frame2d -> Polygon2d.Polygon2d -> Polygon2d.Polygon2d"},{"name":"rotateAround","comment":" Rotate a polygon around the given center point counterclockwise by the given\nangle (in radians).\n\n    rectangle\n        |> Polygon2d.rotateAround Point2d.origin\n            (degrees 90)\n    --> Polygon2d.singleLoop\n    -->     [ Point2d.fromCoordinates ( -1, 1 )\n    -->     , Point2d.fromCoordinates ( -1, 3 )\n    -->     , Point2d.fromCoordinates ( -2, 3 )\n    -->     , Point2d.fromCoordinates ( -2, 1 )\n    -->     ]\n\n","type":"Point2d.Point2d -> Basics.Float -> Polygon2d.Polygon2d -> Polygon2d.Polygon2d"},{"name":"scaleAbout","comment":" Scale a polygon about a given center point by a given scale.\n\n    point =\n        Point2d.fromCoordinates ( 2, 1 )\n\n    Polygon2d.scaleAbout point 2 rectangle\n    --> Polygon2d.singleLoop\n    -->     [ Point2d.fromCoordinates ( 0, 1 )\n    -->     , Point2d.fromCoordinates ( 4, 1 )\n    -->     , Point2d.fromCoordinates ( 4, 3 )\n    -->     , Point2d.fromCoordinates ( 0, 3 )\n    -->     ]\n\nIf the given scale is negative, the order of the polygon's vertices will be\nreversed so that the resulting polygon still has its outer vertices in\ncounterclockwise order and its inner vertices in clockwise order.\n\n","type":"Point2d.Point2d -> Basics.Float -> Polygon2d.Polygon2d -> Polygon2d.Polygon2d"},{"name":"singleLoop","comment":" Construct a polygon without holes from a list of its vertices:\n\n    rectangle =\n        Polygon2d.singleLoop\n            [ Point2d.fromCoordinates ( 1, 1 )\n            , Point2d.fromCoordinates ( 3, 1 )\n            , Point2d.fromCoordinates ( 3, 2 )\n            , Point2d.fromCoordinates ( 1, 2 )\n            ]\n\nThe last vertex is implicitly considered to be connected back to the first\nvertex (you do not have to close the polygon explicitly). Vertices should\nideally be provided in counterclockwise order; if they are provided in clockwise\norder they will be reversed.\n\n","type":"List.List Point2d.Point2d -> Polygon2d.Polygon2d"},{"name":"translateBy","comment":" Translate a polygon by the given displacement.\n\n    displacement =\n        Vector2d.fromComponents ( 2, 3 )\n\n    Polygon2d.translateBy displacement rectangle\n    --> Polygon2d.singleLoop\n    -->     [ Point2d.fromCoordinates ( 3, 4 )\n    -->     , Point2d.fromCoordinates ( 5, 4 )\n    -->     , Point2d.fromCoordinates ( 5, 5 )\n    -->     , Point2d.fromCoordinates ( 3, 5 )\n    -->     ]\n\n","type":"Vector2d.Vector2d -> Polygon2d.Polygon2d -> Polygon2d.Polygon2d"},{"name":"translateIn","comment":" Translate a polygon in a given direction by a given distance;\n\n    Polygon2d.translateIn direction distance\n\nis equivalent to\n\n    Polygon2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Polygon2d.Polygon2d -> Polygon2d.Polygon2d"},{"name":"triangulate","comment":" Triangulate a polygon. This uses the `TriangularMesh` data types from\n[`ianmackenzie/elm-triangular-mesh`](http://package.elm-lang.org/packages/ianmackenzie/elm-triangular-mesh/latest).\nTriangulation is useful for things like WebGL rendering; you can define a\npolygon just by specifying its outline (and holes, if it has any)\n\n![Polygon with hole](https://ianmackenzie.github.io/elm-geometry/1.0.0/Polygon2d/triangulate1.svg)\n\nthen use this function to turn that polygon into a list of triangles which you\ncan render using WebGL:\n\n![Polygon with hole](https://ianmackenzie.github.io/elm-geometry/1.0.0/Polygon2d/triangulate2.svg)\n\n","type":"Polygon2d.Polygon2d -> TriangularMesh.TriangularMesh Point2d.Point2d"},{"name":"vertices","comment":" Get all vertices of a polygon; this will include vertices from the outer\nloop of the polygon and all inner loops. The order of the returned vertices is\nundefined.\n\n    Polygon2d.vertices squareWithHole\n    --> [ Point2d ( 0, 0 )\n    --> , Point2d ( 3, 0 )\n    --> , Point2d ( 3, 3 )\n    --> , Point2d ( 0, 3 )\n    --> , Point2d ( 1, 1 )\n    --> , Point2d ( 1, 2 )\n    --> , Point2d ( 2, 2 )\n    --> , Point2d ( 2, 1 )\n    --> ]\n\n","type":"Polygon2d.Polygon2d -> List.List Point2d.Point2d"},{"name":"with","comment":" Construct a polygon with holes from one outer loop and a list of inner\nloops. The loops must not touch or intersect each other.\n\n    outerLoop =\n        [ Point2d.fromCoordinates ( 0, 0 )\n        , Point2d.fromCoordinates ( 3, 0 )\n        , Point2d.fromCoordinates ( 3, 3 )\n        , Point2d.fromCoordinates ( 0, 3 )\n        ]\n\n    innerLoop =\n        [ Point2d.fromCoordinates ( 1, 1 )\n        , Point2d.fromCoordinates ( 1, 2 )\n        , Point2d.fromCoordinates ( 2, 2 )\n        , Point2d.fromCoordinates ( 2, 1 )\n        ]\n\n    squareWithHole =\n        Polygon2d.with\n            { outerLoop = outerLoop\n            , innerLoops = [ innerLoop ]\n            }\n\nAs with `Polygon2d.singleLoop`, the last vertex of each loop is considered to be\nconnected back to the first. Vertices of the outer loop should ideally be\nprovided in counterclockwise order and vertices of the inner loops should\nideally be provided in clockwise order.\n\n","type":"{ outerLoop : List.List Point2d.Point2d, innerLoops : List.List (List.List Point2d.Point2d) } -> Polygon2d.Polygon2d"}],"binops":[]},{"name":"Polyline2d","comment":" A `Polyline2d` represents a sequence of vertices in 2D connected by line\nsegments. This module contains a variety of polyline-related functionality, such\nas\n\n  - Computing the length of polylines\n  - Scaling, rotating, translating and mirroring polylines\n  - Converting polylines between different coordinate systems\n\n@docs Polyline2d\n\n\n# Constructors\n\n@docs fromVertices\n\n\n# Properties\n\n@docs vertices, segments, length, boundingBox\n\n\n# Transformations\n\nTransforming a polyline is equivalent to transforming each of its vertices.\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto, mapVertices\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Polyline2d","comment":" ","args":[],"type":"Geometry.Types.Polyline2d"}],"values":[{"name":"boundingBox","comment":" Get the minimal bounding box containing a given polyline. Returns `Nothing`\nif the polyline has no vertices.\n\n    Polyline2d.boundingBox stepShape\n    --> Just\n    -->     (BoundingBox2d.fromExtrema\n    -->         { minX = 0\n    -->         , maxX = 2\n    -->         , minY = 0\n    -->         , maxY = 1\n    -->         }\n    -->     )\n\n","type":"Polyline2d.Polyline2d -> Maybe.Maybe BoundingBox2d.BoundingBox2d"},{"name":"fromVertices","comment":" Construct a polyline from a list of vertices:\n\n    stepShape =\n        Polyline2d.fromVertices\n            [ Point2d.fromCoordinates ( 0, 0 )\n            , Point2d.fromCoordinates ( 1, 0 )\n            , Point2d.fromCoordinates ( 1, 1 )\n            , Point2d.fromCoordinates ( 2, 1 )\n            ]\n\n","type":"List.List Point2d.Point2d -> Polyline2d.Polyline2d"},{"name":"length","comment":" Get the overall length of a polyline (the sum of the lengths of its\nsegments).\n\n    Polyline2d.length stepShape\n    --> 3\n\n","type":"Polyline2d.Polyline2d -> Basics.Float"},{"name":"mapVertices","comment":" Transform each vertex of a polyline by the given function. All other\ntransformations can be defined in terms of `mapVertices`; for example,\n\n    Polyline2d.mirrorAcross axis\n\nis equivalent to\n\n    Polyline2d.mapVertices (Point2d.mirrorAcross axis)\n\n","type":"(Point2d.Point2d -> Point2d.Point2d) -> Polyline2d.Polyline2d -> Polyline2d.Polyline2d"},{"name":"mirrorAcross","comment":" Mirror a polyline across the given axis.\n\n    Polyline2d.mirrorAcross Axis2d.x stepShape\n    --> Polyline2d.fromVertices\n    -->     [ Point2d.fromCoordinates ( 0, 0 )\n    -->     , Point2d.fromCoordinates ( 1, 0 )\n    -->     , Point2d.fromCoordinates ( 1, -1 )\n    -->     , Point2d.fromCoordinates ( 2, -1 )\n    -->     ]\n\n","type":"Axis2d.Axis2d -> Polyline2d.Polyline2d -> Polyline2d.Polyline2d"},{"name":"placeIn","comment":" Take a polyline considered to be defined in local coordinates relative\nto a given reference frame, and return that polyline expressed in global\ncoordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Polyline2d.placeIn localFrame stepShape\n    --> Polyline2d.fromVertices\n    -->     [ Point2d.fromCoordinates ( 1, 2 )\n    -->     , Point2d.fromCoordinates ( 2, 2 )\n    -->     , Point2d.fromCoordinates ( 2, 3 )\n    -->     , Point2d.fromCoordinates ( 3, 3 )\n    -->     ]\n\n","type":"Frame2d.Frame2d -> Polyline2d.Polyline2d -> Polyline2d.Polyline2d"},{"name":"projectOnto","comment":" Project (flatten) a polyline onto the given axis.\n\n    Polyline2d.projectOnto Axis2d.x stepShape\n    --> Polyline2d.fromVertices\n    -->     [ Point2d.fromCoordinates ( 0, 0 )\n    -->     , Point2d.fromCoordinates ( 1, 0 )\n    -->     , Point2d.fromCoordinates ( 1, 0 )\n    -->     , Point2d.fromCoordinates ( 2, 0 )\n    -->     ]\n\n","type":"Axis2d.Axis2d -> Polyline2d.Polyline2d -> Polyline2d.Polyline2d"},{"name":"relativeTo","comment":" Take a polyline defined in global coordinates, and return it expressed\nin local coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Polyline2d.relativeTo localFrame stepShape\n    --> Polyline2d.fromVertices\n    -->     [ Point2d.fromCoordinates ( -1, -2 )\n    -->     , Point2d.fromCoordinates ( 0, -2 )\n    -->     , Point2d.fromCoordinates ( 0, -1 )\n    -->     , Point2d.fromCoordinates ( 1, -1 )\n    -->     ]\n\n","type":"Frame2d.Frame2d -> Polyline2d.Polyline2d -> Polyline2d.Polyline2d"},{"name":"rotateAround","comment":" Rotate a polyline around the given center point counterclockwise by the\ngiven angle (in radians).\n\n    stepShape\n        |> Polyline2d.rotateAround Point2d.origin\n            (degrees 90)\n    --> Polyline2d.fromVertices\n    -->     [ Point2d.fromCoordinates ( 0, 0 )\n    -->     , Point2d.fromCoordinates ( 0, 1 )\n    -->     , Point2d.fromCoordinates ( -1, 1 )\n    -->     , Point2d.fromCoordinates ( -1, 2 )\n    -->     ]\n\n","type":"Point2d.Point2d -> Basics.Float -> Polyline2d.Polyline2d -> Polyline2d.Polyline2d"},{"name":"scaleAbout","comment":" Scale a polyline about a given center point by a given scale.\n\n    point =\n        Point2d.fromCoordinates ( 1, 0 )\n\n    Polyline2d.scaleAbout point 2 stepShape\n    --> Polyline2d.fromVertices\n    -->     [ Point2d.fromCoordinates ( -1, 0 )\n    -->     , Point2d.fromCoordinates ( 1, 0 )\n    -->     , Point2d.fromCoordinates ( 1, 2 )\n    -->     , Point2d.fromCoordinates ( 3, 2 )\n    -->     ]\n\n","type":"Point2d.Point2d -> Basics.Float -> Polyline2d.Polyline2d -> Polyline2d.Polyline2d"},{"name":"segments","comment":" Get the individual segments of a polyline.\n\n    Polyline2d.segments stepShape\n    --> [ LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 0, 0 )\n    -->     , Point2d.fromCoordinates ( 1, 0 )\n    -->     )\n    --> , LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 1, 0 )\n    -->     , Point2d.fromCoordinates ( 1, 1 )\n    -->     )\n    --> , LineSegment2d.fromEndpoints\n    -->     ( Point2d.fromCoordinates ( 1, 1 )\n    -->     , Point2d.fromCoordinates ( 2, 1 )\n    -->     )\n    --> ]\n\n","type":"Polyline2d.Polyline2d -> List.List LineSegment2d.LineSegment2d"},{"name":"translateBy","comment":" Translate a polyline by the given displacement.\n\n    displacement =\n        Vector2d.fromComponents ( 2, 3 )\n\n    Polyline2d.translateBy displacement stepShape\n    --> Polyline2d.fromVertices\n    -->     [ Point2d.fromCoordinates ( 2, 3 )\n    -->     , Point2d.fromCoordinates ( 3, 3 )\n    -->     , Point2d.fromCoordinates ( 3, 4 )\n    -->     , Point2d.fromCoordinates ( 4, 4 )\n    -->     ]\n\n","type":"Vector2d.Vector2d -> Polyline2d.Polyline2d -> Polyline2d.Polyline2d"},{"name":"translateIn","comment":" Translate a polyline in a given direction by a given distance;\n\n    Polyline2d.translateIn direction distance\n\nis equivalent to\n\n    Polyline2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Polyline2d.Polyline2d -> Polyline2d.Polyline2d"},{"name":"vertices","comment":" Get the vertices of a polyline.\n\n    Polyline2d.vertices stepShape\n    --> [ Point2d.fromCoordinates ( 0, 0 )\n    --> , Point2d.fromCoordinates ( 1, 0 )\n    --> , Point2d.fromCoordinates ( 1, 1 )\n    --> , Point2d.fromCoordinates ( 2, 1 )\n    --> ]\n\n","type":"Polyline2d.Polyline2d -> List.List Point2d.Point2d"}],"binops":[]},{"name":"Polyline3d","comment":" A `Polyline3d` represents a sequence of vertices in 3D connected by line\nsegments. This module contains a variety of polyline-related functionality, such\nas\n\n  - Computing the length of polylines\n  - Scaling, rotating, translating and mirroring polylines\n  - Converting polylines between different coordinate systems\n\n@docs Polyline3d\n\n\n# Constructors\n\n@docs fromVertices, on\n\n\n# Properties\n\n@docs vertices, segments, length, boundingBox\n\n\n# Transformations\n\nTransforming a polyline is equivalent to transforming each of its vertices.\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto, mapVertices\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn, projectInto\n\n","unions":[],"aliases":[{"name":"Polyline3d","comment":" ","args":[],"type":"Geometry.Types.Polyline3d"}],"values":[{"name":"boundingBox","comment":" Get the minimal bounding box containing a given polyline. Returns `Nothing`\nif the polyline has no vertices.\n\n    Polyline3d.boundingBox examplePolyline\n    --> Just\n    -->     (BoundingBox3d.fromExtrema\n    -->         { minX = 0\n    -->         , maxX = 1\n    -->         , minY = 0\n    -->         , maxY = 2\n    -->         , minZ = 0\n    -->         , maxZ = 3\n    -->         }\n    -->     )\n\n","type":"Polyline3d.Polyline3d -> Maybe.Maybe BoundingBox3d.BoundingBox3d"},{"name":"fromVertices","comment":" Construct a polyline from its vertices:\n\n    examplePolyline =\n        Polyline3d.fromVertices\n            [ Point2d.fromCoordinates ( 0, 0, 0 )\n            , Point2d.fromCoordinates ( 1, 0, 0 )\n            , Point2d.fromCoordinates ( 1, 2, 0 )\n            , Point2d.fromCoordinates ( 1, 2, 3 )\n            ]\n\n","type":"List.List Point3d.Point3d -> Polyline3d.Polyline3d"},{"name":"length","comment":" Get the overall length of a polyline (the sum of the lengths of its\nsegments).\n\n    Polyline3d.length examplePolyline\n    --> 6\n\n","type":"Polyline3d.Polyline3d -> Basics.Float"},{"name":"mapVertices","comment":" Transform each vertex of a polyline by the given function. All other\ntransformations can be defined in terms of `mapVertices`; for example,\n\n    Polyline3d.mirrorAcross plane\n\nis equivalent to\n\n    Polyline3d.mapVertices (Point3d.mirrorAcross plane)\n\n","type":"(Point3d.Point3d -> Point3d.Point3d) -> Polyline3d.Polyline3d -> Polyline3d.Polyline3d"},{"name":"mirrorAcross","comment":" Mirror a polyline across the given plane.\n\n    Polyline3d.mirrorAcross Plane3d.xz examplePolyline\n    --> Polyline3d.fromVertices\n    -->     [ Point3d.fromCoordinates ( 0, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 1, -2, 0 )\n    -->     , Point3d.fromCoordinates ( 1, -2, 3 )\n    -->     ]\n\n","type":"Plane3d.Plane3d -> Polyline3d.Polyline3d -> Polyline3d.Polyline3d"},{"name":"on","comment":" Construct a 3D polyline lying _on_ a sketch plane by providing a 2D polyline\nspecified in XY coordinates _within_ the sketch plane.\n\n    Polyline3d.on SketchPlane3d.yz <|\n        Polyline2d.fromVertices\n            [ Point2d.fromCoordinates ( 0, 0 )\n            , Point2d.fromCoordinates ( 1, 0 )\n            , Point2d.fromCoordinates ( 1, 1 )\n            , Point2d.fromCoordinates ( 2, 1 )\n            ]\n    --> Polyline3d.fromVertices\n    -->     [ Point3d.fromCoordinates ( 0, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 0, 1, 0 )\n    -->     , Point3d.fromCoordinates ( 0, 1, 1 )\n    -->     , Point3d.fromCoordinates ( 0, 2, 1 )\n    -->     ]\n\n","type":"SketchPlane3d.SketchPlane3d -> Polyline2d.Polyline2d -> Polyline3d.Polyline3d"},{"name":"placeIn","comment":" Take a polyline considered to be defined in local coordinates relative\nto a given reference frame, and return that polyline expressed in global\ncoordinates.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Polyline3d.placeIn localFrame examplePolyline\n    --> Polyline3d.fromVertices\n    -->     [ Point3d.fromCoordinates ( 1, 2, 3 )\n    -->     , Point3d.fromCoordinates ( 2, 2, 3 )\n    -->     , Point3d.fromCoordinates ( 2, 4, 3 )\n    -->     , Point3d.fromCoordinates ( 2, 4, 6 )\n    -->     ]\n\n","type":"Frame3d.Frame3d -> Polyline3d.Polyline3d -> Polyline3d.Polyline3d"},{"name":"projectInto","comment":" Project a polyline into a given sketch plane. Conceptually, this finds the\n[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof the polyline onto the plane and then expresses the projected polyline in 2D\nsketch coordinates.\n\n    Polyline3d.projectInto Plane3d.xy examplePolyline\n    --> Polyline2d.fromVertices\n    -->     [ Point2d.fromCoordinates ( 0, 0 )\n    -->     , Point2d.fromCoordinates ( 1, 0 )\n    -->     , Point2d.fromCoordinates ( 1, 2 )\n    -->     , Point2d.fromCoordinates ( 1, 2 )\n    -->     ]\n\n","type":"SketchPlane3d.SketchPlane3d -> Polyline3d.Polyline3d -> Polyline2d.Polyline2d"},{"name":"projectOnto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof a polyline onto a plane. This will flatten the polyline.\n\n    Polyline3d.projectOnto Plane3d.xz examplePolyline\n    --> Polyline3d.fromVertices\n    -->     [ Point3d.fromCoordinates ( 0, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 0, 3 )\n    -->     ]\n\n","type":"Plane3d.Plane3d -> Polyline3d.Polyline3d -> Polyline3d.Polyline3d"},{"name":"relativeTo","comment":" Take a polyline defined in global coordinates, and return it expressed\nin local coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    Polyline3d.relativeTo localFrame examplePolyline\n    --> Polyline3d.fromVertices\n    -->     [ Point3d.fromCoordinates ( -1, -2, -3 )\n    -->     , Point3d.fromCoordinates ( 0, -2, -3 )\n    -->     , Point3d.fromCoordinates ( 0, 0, -3 )\n    -->     , Point3d.fromCoordinates ( 0, 0, 0 )\n    -->     ]\n\n","type":"Frame3d.Frame3d -> Polyline3d.Polyline3d -> Polyline3d.Polyline3d"},{"name":"rotateAround","comment":" Rotate a polyline around the given axis by the given angle (in radians).\n\n    examplePolyline\n        |> Polyline3d.rotateAround Axis3d.z (degrees 90)\n    --> Polyline3d.fromVertices\n    -->     [ Point3d.fromCoordinates ( 0, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 0, 1, 0 )\n    -->     , Point3d.fromCoordinates ( -2, 1, 0 )\n    -->     , Point3d.fromCoordinates ( -2, 1, 3 )\n    -->     ]\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Polyline3d.Polyline3d -> Polyline3d.Polyline3d"},{"name":"scaleAbout","comment":" Scale a polyline about the given center point by the given scale.\n\n    point =\n        Point3d.fromCoordinates ( 1, 0, 0 )\n\n    Polyline3d.scaleAbout point 2 examplePolyline\n    --> Polyline3d.fromVertices\n    -->     [ Point3d.fromCoordinates ( -1, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 4, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 4, 6 )\n    -->     ]\n\n","type":"Point3d.Point3d -> Basics.Float -> Polyline3d.Polyline3d -> Polyline3d.Polyline3d"},{"name":"segments","comment":" Get the individual segments of a polyline.\n\n    Polyline3d.segments examplePolyline\n    --> [ LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 0, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 0, 0 )\n    -->     )\n    --> , LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 1, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 2, 0 )\n    -->     )\n    --> , LineSegment3d.fromEndpoints\n    -->     ( Point3d.fromCoordinates ( 1, 2, 0 )\n    -->     , Point3d.fromCoordinates ( 1, 2, 3 )\n    -->     )\n    --> ]\n\n","type":"Polyline3d.Polyline3d -> List.List LineSegment3d.LineSegment3d"},{"name":"translateBy","comment":" Translate a polyline by the given displacement.\n\n    displacement =\n        Vector3d.fromComponents ( 1, 2, 3 )\n\n    Polyline3d.translateBy displacement examplePolyline\n    --> Polyline3d.fromVertices\n    -->     [ Point3d.fromCoordinates ( 1, 2, 3 )\n    -->     , Point3d.fromCoordinates ( 2, 2, 3 )\n    -->     , Point3d.fromCoordinates ( 2, 4, 3 )\n    -->     , Point3d.fromCoordinates ( 2, 4, 6 )\n    -->     ]\n\n","type":"Vector3d.Vector3d -> Polyline3d.Polyline3d -> Polyline3d.Polyline3d"},{"name":"translateIn","comment":" Translate a polyline in a given direction by a given distance;\n\n    Polyline3d.translateIn direction distance\n\nis equivalent to\n\n    Polyline3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> Polyline3d.Polyline3d -> Polyline3d.Polyline3d"},{"name":"vertices","comment":" Get the vertices of a polyline.\n\n    Polyline3d.vertices examplePolyline\n    --> [ Point3d.fromCoordinates ( 0, 0, 0 )\n    --> , Point3d.fromCoordinates ( 1, 0, 0 )\n    --> , Point3d.fromCoordinates ( 1, 2, 0 )\n    --> , Point3d.fromCoordinates ( 1, 2, 3 )\n    --> ]\n\n","type":"Polyline3d.Polyline3d -> List.List Point3d.Point3d"}],"binops":[]},{"name":"QuadraticSpline2d","comment":" A `QuadraticSpline2d` is a quadratic [Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve)\nin 2D defined by a start point, control point and end point. This module\ncontains functionality for\n\n  - Evaluating points and derivatives along a spline\n  - Scaling, rotating, translating or mirroring a spline\n  - Converting a spline between local and global coordinates in different\n    reference frames\n\n@docs QuadraticSpline2d\n\n\n# Constructors\n\n@docs with\n\n\n# Properties\n\n@docs startPoint, endPoint, controlPoint, startDerivative, endDerivative, boundingBox\n\n\n# Evaluation\n\n@docs pointOn, pointsAt\n@docs Nondegenerate, nondegenerate, fromNondegenerate\n@docs tangentDirection, tangentDirectionsAt, sample, samplesAt\n\n\n# Transformations\n\n@docs reverse, scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n\n# Subdivision\n\n@docs bisect, splitAt\n\n\n# Arc length parameterization\n\n@docs ArcLengthParameterized, arcLengthParameterized, arcLength, pointAlong, tangentDirectionAlong, sampleAlong\n\n\n## Low level\n\nAn `ArcLengthParameterized` value is a combination of an\n[`ArcLengthParameterization`](Geometry-ArcLengthParameterization) and an\nunderlying `QuadraticSpline2d`. If you need to do something fancy, you can\nextract these two values separately.\n\n@docs arcLengthParameterization, fromArcLengthParameterized\n\n\n# Differentiation\n\nYou are unlikely to need to use these functions directly, but they are useful if\nyou are writing low-level geometric algorithms.\n\n@docs firstDerivative, firstDerivativesAt, secondDerivative\n\n","unions":[{"name":"ArcLengthParameterized","comment":" A spline that has been parameterized by arc length.\n","args":[],"cases":[]},{"name":"Nondegenerate","comment":" If a curve has zero length (consists of just a single point), then we say\nthat it is 'degenerate'. Some operations such as computing tangent directions\nare not defined on degenerate curves.\n\nA `Nondegenerate` value represents a spline that is definitely not degenerate.\nIt is used as input to functions such as `QuadraticSpline2d.tangentDirection`\nand can be constructed using `QuadraticSpline2d.nondegenerate`.\n\n","args":[],"cases":[]}],"aliases":[{"name":"QuadraticSpline2d","comment":" ","args":[],"type":"Geometry.Types.QuadraticSpline2d"}],"values":[{"name":"arcLength","comment":" Find the total arc length of a spline:\n\n    QuadraticSpline2d.arcLength parameterizedSpline\n    --> 5.1986\n\nIn this example, the result will be accurate to within `1.0e-4` since that was\nthe tolerance used when constructing `parameterizedSpline`.\n\n","type":"QuadraticSpline2d.ArcLengthParameterized -> Basics.Float"},{"name":"arcLengthParameterization","comment":" ","type":"QuadraticSpline2d.ArcLengthParameterized -> Curve.ArcLengthParameterization.ArcLengthParameterization"},{"name":"arcLengthParameterized","comment":" Build an arc length parameterization of the given spline, with a given\naccuracy. Generally speaking, all operations on the resulting\n`ArcLengthParameterized` value will be accurate to within the specified maximum\nerror.\n\n    parameterizedSpline =\n        exampleSpline\n            |> QuadraticSpline2d.arcLengthParameterized\n                { maxError = 1.0e-4 }\n\n","type":"{ maxError : Basics.Float } -> QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline2d.ArcLengthParameterized"},{"name":"bisect","comment":" Split a spline into two roughly equal halves.\n\n    QuadraticSpline2d.bisect exampleSpline\n    --> ( QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 1, 1 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 2, 2.5 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 3, 2.5 )\n    -->     }\n    --> , QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 3, 2.5 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 4, 2.5 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 5, 1 )\n    -->     }\n    --> )\n\nEquivalent to `QuadraticSpline2d.splitAt ParameterValue.half`.\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> ( QuadraticSpline2d.QuadraticSpline2d, QuadraticSpline2d.QuadraticSpline2d )"},{"name":"boundingBox","comment":" Compute a bounding box for a given spline. It is not guaranteed that the\nresult will be the _smallest_ possible bounding box, since for efficiency the\nbounding box is computed from the spline's control points (which cover a larger\narea than the spline itself).\n\n    QuadraticSpline2d.boundingBox exampleSpline\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 5\n    -->     , minY = 1\n    -->     , maxY = 4\n    -->     }\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> BoundingBox2d.BoundingBox2d"},{"name":"controlPoint","comment":" Get the control point of a spline.\n\n    QuadraticSpline2d.controlPoint exampleSpline\n    --> Point2d.fromCoordinates ( 3, 4 )\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> Point2d.Point2d"},{"name":"endDerivative","comment":" Get the end derivative of a spline. This is equal to twice the vector from\nthe spline's second control point to its third.\n\n    QuadraticSpline2d.endDerivative exampleSpline\n    --> Vector2d.fromComponents ( 4, -6 )\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> Vector2d.Vector2d"},{"name":"endPoint","comment":" Get the end point of a spline.\n\n    QuadraticSpline2d.endPoint exampleSpline\n    --> Point2d.fromCoordinates ( 5, 1 )\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> Point2d.Point2d"},{"name":"firstDerivative","comment":" Get the first derivative of a spline at a given parameter value.\n\n    QuadraticSpline2d.derivative exampleSpline\n        ParameterValue.zero\n    --> Vector2d.fromComponents ( 4, 6 )\n\n    QuadraticSpline2d.derivative exampleSpline\n        ParameterValue.half\n    --> Vector2d.fromComponents ( 4, 0 )\n\n    QuadraticSpline2d.derivative exampleSpline\n        ParameterValue.one\n    --> Vector2d.fromComponents ( 4, -6 )\n\nNote that the derivative interpolates linearly from end to end.\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> Curve.ParameterValue.ParameterValue -> Vector2d.Vector2d"},{"name":"firstDerivativesAt","comment":" Evaluate the first derivative of a spline at a range of parameter values:\n\n    exampleSpline\n        |> QuadraticSpline2d.firstDerivativesAt\n            (ParameterValue.steps 2)\n    --> [ Vector2d.fromComponents ( 4, 6 )\n    --> , Vector2d.fromComponents ( 4, 0 )\n    --> , Vector2d.fromComponents ( 4, -6 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> QuadraticSpline2d.QuadraticSpline2d -> List.List Vector2d.Vector2d"},{"name":"fromArcLengthParameterized","comment":" Get the original `QuadraticSpline2d` from which an `ArcLengthParameterized`\nvalue was constructed.\n","type":"QuadraticSpline2d.ArcLengthParameterized -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"fromNondegenerate","comment":" Convert a nondegenerate spline back to a general `QuadraticSpline2d`.\n\n    QuadraticSpline2d.fromNondegenerate\n        nondegenerateExampleSpline\n    --> exampleSpline\n\n","type":"QuadraticSpline2d.Nondegenerate -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"mirrorAcross","comment":" Mirror a spline across an axis.\n\n    QuadraticSpline2d.mirrorAcross Axis2d.x exampleSpline\n    --> QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 1, -1 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 3, -4 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 5, -1 )\n    -->     }\n\n","type":"Axis2d.Axis2d -> QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"nondegenerate","comment":" Attempt to construct a nondegenerate spline from a general\n`QuadraticSpline2d`. If the spline is in fact degenerate (consists of a single\npoint), returns an `Err` with that point.\n\n    QuadraticSpline2d.nondegenerate exampleSpline\n    --> Ok nondegenerateExampleSpline\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> Result.Result Point2d.Point2d QuadraticSpline2d.Nondegenerate"},{"name":"placeIn","comment":" Take a spline considered to be defined in local coordinates relative to a\ngiven reference frame, and return that spline expressed in global coordinates.\n\n    localFrame =\n        Frame2d.atCoordinates ( 1, 2 )\n\n    QuadraticSpline2d.placeIn localFrame exampleSpline\n    --> QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 2, 3 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 4, 6 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 6, 3 )\n    -->     }\n\n","type":"Frame2d.Frame2d -> QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"pointAlong","comment":" Try to get the point along a spline at a given arc length. For example, to\nget the point a quarter of the way along `exampleSpline`:\n\n    QuadraticSpline2d.pointAlong parameterizedSpline\n        (arcLength / 4)\n    --> Just (Point2d.fromCoordinates ( 1.8350, 1.9911 ))\n\nNote that this is not the same as evaulating at a parameter value of 1/4:\n\n    QuadraticSpline2d.pointOn exampleSpline 0.25\n    --> Point2d.fromCoordinates ( 2, 2.125 )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline, returns `Nothing`.\n\n","type":"QuadraticSpline2d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Point2d.Point2d"},{"name":"pointOn","comment":" Get the point along a spline at a given parameter value:\n\n    QuadraticSpline2d.pointOn exampleSpline 0\n    --> Point2d.fromCoordinates ( 1, 1 )\n\n    QuadraticSpline2d.pointOn exampleSpline 0.5\n    --> Point2d.fromCoordinates ( 3, 2.5 )\n\n    QuadraticSpline2d.pointOn exampleSpline 1\n    --> Point2d.fromCoordinates ( 5, 1 )\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> Curve.ParameterValue.ParameterValue -> Point2d.Point2d"},{"name":"pointsAt","comment":" Get points along a spline at a given set of parameter values:\n\n    exampleSpline\n        |> QuadraticSpline2d.pointsAt\n            (ParameterValue.steps 2)\n    --> [ Point2d.fromCoordinates ( 1, 1 )\n    --> , Point2d.fromCoordinates ( 3, 2.5 )\n    --> , Point2d.fromCoordinates ( 5, 1 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> QuadraticSpline2d.QuadraticSpline2d -> List.List Point2d.Point2d"},{"name":"relativeTo","comment":" Take a spline defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atCoordinates ( 1, 2 )\n\n    QuadraticSpline2d.relativeTo localFrame exampleSpline\n    --> QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 0, -1 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 2, 2 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 4, -1 )\n    -->     }\n\n","type":"Frame2d.Frame2d -> QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"reverse","comment":" Reverse a spline so that the start point becomes the end point, and vice\nversa.\n\n    QuadraticSpline2d.reverse exampleSpline\n    --> QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 5, 1 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 3, 4 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 1, 1 )\n    -->     }\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"rotateAround","comment":" Rotate a spline counterclockwise around a given center point by a given\nangle (in radians).\n\n    examplePolyline\n        |> QuadraticSpline2d.rotateAround Point2d.origin\n            (degrees 90)\n    --> QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( -1, 1 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( -4, 3 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( -1, 5 )\n    -->     }\n\n","type":"Point2d.Point2d -> Basics.Float -> QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"sample","comment":" Get both the point and tangent direction of a nondegenerate spline at a\ngiven parameter value:\n\n    QuadraticSpline2d.sample nondegenerateExampleSpline\n        ParameterValue.half\n    --> ( Point2d.fromCoordinates ( 3, 2.5 )\n    --> , Direction2d.x\n    --> )\n\n","type":"QuadraticSpline2d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"sampleAlong","comment":" Try to get the point and tangent direction along a spline at a given arc\nlength. To get the point and tangent direction a quarter of the way along\n`exampleSpline`:\n\n    QuadraticSpline2d.sampleAlong parameterizedSpline\n        (0.25 * arcLength)\n    --> Just\n    -->     ( Point2d.fromCoordinates ( 1.8350, 1.9911 )\n    -->     , Direction2d.fromAngle (degrees 41.145)\n    -->     )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline (or if the spline is degenerate), returns `Nothing`.\n\n","type":"QuadraticSpline2d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"samplesAt","comment":" Get points and tangent directions of a nondegenerate spline at a given set\nof parameter values:\n\n    nondegenerateExampleSpline\n        |> QuadraticSpline2d.samplesAt\n            (ParameterValue.steps 2)\n    --> [ ( Point2d.fromCoordinates ( 1, 1 )\n    -->   , Direction2d.fromAngle (degrees 56.31)\n    -->   )\n    --> , ( Point2d.fromCoordinates ( 3, 2.5 )\n    -->   , Direction2d.x\n    -->   )\n    --> , ( Point2d.fromCoordinates ( 5, 1 )\n    -->   , Direction2d.fromAngle (degrees -56.31)\n    -->   )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> QuadraticSpline2d.Nondegenerate -> List.List ( Point2d.Point2d, Direction2d.Direction2d )"},{"name":"scaleAbout","comment":" Scale a spline about the given center point by the given scale.\n\n    examplePolyline\n        |> QuadraticSpline2d.scaleAbout Point2d.origin 2\n    --> QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 2, 2 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 6, 8 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 10, 2 )\n    -->     }\n\n","type":"Point2d.Point2d -> Basics.Float -> QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"secondDerivative","comment":" Get the second derivative of a spline (for a quadratic spline, this is a\nconstant).\n","type":"QuadraticSpline2d.QuadraticSpline2d -> Vector2d.Vector2d"},{"name":"splitAt","comment":" Split a spline at a particular parameter value, resulting in two smaller\nsplines.\n\n    parameterValue =\n        ParameterValue.clamped 0.75\n\n    QuadraticSpline2d.splitAt parameterValue exampleSpline\n    --> ( QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 1, 1 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 2.5, 3.25 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 4, 2.125 )\n    -->     }\n    --> , QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 4, 2.125 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 4.5, 1.75 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 5, 1 )\n    -->     }\n    --> )\n\n","type":"Curve.ParameterValue.ParameterValue -> QuadraticSpline2d.QuadraticSpline2d -> ( QuadraticSpline2d.QuadraticSpline2d, QuadraticSpline2d.QuadraticSpline2d )"},{"name":"startDerivative","comment":" Get the start derivative of a spline. This is equal to twice the vector from\nthe spline's first control point to its second.\n\n    QuadraticSpline2d.startDerivative exampleSpline\n    --> Vector2d.fromComponents ( 4, 6 )\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> Vector2d.Vector2d"},{"name":"startPoint","comment":" Get the start point of a spline.\n\n    QuadraticSpline2d.startPoint exampleSpline\n    --> Point2d.fromCoordinates ( 1, 1 )\n\n","type":"QuadraticSpline2d.QuadraticSpline2d -> Point2d.Point2d"},{"name":"tangentDirection","comment":" Get the tangent direction to a nondegenerate spline at a given parameter\nvalue:\n\n    QuadraticSpline2d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.zero\n    --> Direction2d.fromAngle (degrees 56.31)\n\n    QuadraticSpline2d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.half\n    --> Direction2d.x\n\n    QuadraticSpline2d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.one\n    --> Direction2d.fromAngle (degrees -56.31)\n\n","type":"QuadraticSpline2d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> Direction2d.Direction2d"},{"name":"tangentDirectionAlong","comment":" Try to get the tangent direction along a spline at a given arc length. To\nget the tangent direction a quarter of the way along `exampleSpline`:\n\n    QuadraticSpline2d.tangentDirectionAlong\n        parameterizedSpline\n        (arcLength / 4)\n    --> Just (Direction2d.fromAngle (degrees 41.145))\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline (or if the derivative of the spline happens to be exactly zero at the\ngiven arc length), returns `Nothing`.\n\n","type":"QuadraticSpline2d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Direction2d.Direction2d"},{"name":"tangentDirectionsAt","comment":" Get tangent directions to a nondegenerate spline at a given set of parameter\nvalues:\n\n    nondegenerateExampleSpline\n        |> QuadraticSpline2d.tangentDirectionsAt\n            (ParameterValue.steps 2)\n    --> [ Direction2d.fromAngle (degrees 56.31)\n    --> , Direction2d.x\n    --> , Direction2d.fromAngle (degrees -56.31)\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> QuadraticSpline2d.Nondegenerate -> List.List Direction2d.Direction2d"},{"name":"translateBy","comment":" Translate a spline by a given displacement.\n\n    displacement =\n        Vector2d.fromComponents ( 2, 3 )\n\n    exampleSpline\n        |> QuadraticSpline2d.translateBy displacement\n    --> QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 3, 4 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 5, 7 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 7, 4 )\n    -->     )\n\n","type":"Vector2d.Vector2d -> QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"translateIn","comment":" Translate a spline in a given direction by a given distance;\n\n    QuadraticSpline2d.translateIn direction distance\n\nis equivalent to\n\n    QuadraticSpline2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"with","comment":" Construct a spline from its start point, control point and end point:\n\n    exampleSpline =\n        QuadraticSpline2d.with\n            { startPoint =\n                Point2d.fromCoordinates ( 1, 1 )\n            , controlPoint =\n                Point2d.fromCoordinates ( 3, 4 )\n            , endPoint =\n                Point2d.fromCoordinates ( 5, 1 )\n            }\n\n","type":"{ startPoint : Point2d.Point2d, controlPoint : Point2d.Point2d, endPoint : Point2d.Point2d } -> QuadraticSpline2d.QuadraticSpline2d"}],"binops":[]},{"name":"QuadraticSpline3d","comment":" A `QuadraticSpline3d` is a quadratic [Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve)\nin 3D defined by a start point, control point and end point. This module\ncontains functionality for\n\n  - Evaluating points and derivatives along a spline\n  - Scaling, rotating, translating or mirroring a spline\n  - Converting a spline between local and global coordinates in different\n    reference frames\n\n@docs QuadraticSpline3d\n\n\n# Constructors\n\n@docs with, on\n\n\n# Properties\n\n@docs startPoint, endPoint, controlPoint, startDerivative, endDerivative, boundingBox\n\n\n# Evaluation\n\n@docs pointOn, pointsAt\n@docs Nondegenerate, nondegenerate, fromNondegenerate\n@docs tangentDirection, tangentDirectionsAt, sample, samplesAt\n\n\n# Transformations\n\n@docs reverse, scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n\n# Sketch planes\n\n@docs projectInto\n\n\n# Subdivision\n\n@docs bisect, splitAt\n\n\n# Arc length parameterization\n\n@docs ArcLengthParameterized, arcLengthParameterized, arcLength, pointAlong, tangentDirectionAlong, sampleAlong\n\n\n## Low level\n\nAn `ArcLengthParameterized` value is a combination of an\n[`ArcLengthParameterization`](Geometry-ArcLengthParameterization) and an\nunderlying `QuadraticSpline3d`. If you need to do something fancy, you can\nextract these two values separately.\n\n@docs arcLengthParameterization, fromArcLengthParameterized\n\n\n# Differentiation\n\nYou are unlikely to need to use these functions directly, but they are useful if\nyou are writing low-level geometric algorithms.\n\n@docs firstDerivative, firstDerivativesAt, secondDerivative\n\n","unions":[{"name":"ArcLengthParameterized","comment":" A spline that has been parameterized by arc length.\n","args":[],"cases":[]},{"name":"Nondegenerate","comment":" If a curve has zero length (consists of just a single point), then we say\nthat it is 'degenerate'. Some operations such as computing tangent directions\nare not defined on degenerate curves.\n\nA `Nondegenerate` value represents a spline that is definitely not degenerate.\nIt is used as input to functions such as `QuadraticSpline3d.tangentDirection`\nand can be constructed using `QuadraticSpline3d.nondegenerate`.\n\n","args":[],"cases":[]}],"aliases":[{"name":"QuadraticSpline3d","comment":" ","args":[],"type":"Geometry.Types.QuadraticSpline3d"}],"values":[{"name":"arcLength","comment":" Find the total arc length of a spline.\n\n    QuadraticSpline3d.arcLength parameterizedSpline\n    --> 3.8175\n\nIn this example, the result will be accurate to within `1.0e-4` since that was\nthe tolerance used when constructing `parameterizedSpline`.\n\n","type":"QuadraticSpline3d.ArcLengthParameterized -> Basics.Float"},{"name":"arcLengthParameterization","comment":" ","type":"QuadraticSpline3d.ArcLengthParameterized -> Curve.ArcLengthParameterization.ArcLengthParameterization"},{"name":"arcLengthParameterized","comment":" Build an arc length parameterization of the given spline, with a given\naccuracy. Generally speaking, all operations on the resulting\n`ArcLengthParameterized` value will be accurate to within the specified maximum\nerror.\n\n    parameterizedSpline =\n        exampleSpline\n            |> QuadraticSpline3d.arcLengthParameterized\n                { maxError = 1.0e-4 }\n\n","type":"{ maxError : Basics.Float } -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.ArcLengthParameterized"},{"name":"bisect","comment":" Split a spline into two roughly equal halves.\n\n    QuadraticSpline3d.bisect exampleSpline\n    --> ( QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, 1 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 2, 2.5 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 2.5 )\n    -->     }\n    --> , QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 3, 2.5 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 4, 2.5 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 3 )\n    -->     }\n    --> )\n\nEquivalent to `QuadraticSpline3d.splitAt ParameterValue.half`.\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> ( QuadraticSpline3d.QuadraticSpline3d, QuadraticSpline3d.QuadraticSpline3d )"},{"name":"boundingBox","comment":" Compute a bounding box for a given spline. It is not guaranteed that the\nresult will be the _smallest_ possible bounding box, since for efficiency the\nbounding box is computed from the spline's control points (which cover a larger\nvolume than the spline itself).\n\n    QuadraticSpline3d.boundingBox exampleSpline\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 3\n    -->     , minY = 1\n    -->     , maxY = 3\n    -->     , minZ = 1\n    -->     , maxZ = 3\n    -->     }\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> BoundingBox3d.BoundingBox3d"},{"name":"controlPoint","comment":" Get the control point of a spline.\n\n    QuadraticSpline3d.controlPoint exampleSpline\n    --> Point3d.fromCoordinates ( 3, 2, 1 )\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> Point3d.Point3d"},{"name":"endDerivative","comment":" Get the end derivative of a spline. This is equal to twice the vector from\nthe spline's second control point to its third.\n\n    QuadraticSpline3d.endDerivative exampleSpline\n    --> Vector3d.fromComponents ( 0, 2, 4 )\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> Vector3d.Vector3d"},{"name":"endPoint","comment":" Get the end point of a spline. This is equal to the spline's last control\npoint.\n\n    QuadraticSpline3d.endPoint exampleSpline\n    --> Point3d.fromCoordinates ( 3, 3, 3 )\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> Point3d.Point3d"},{"name":"firstDerivative","comment":" Get the first derivative of a spline at a given parameter value:\n\n    QuadraticSpline3d.derivative exampleSpline\n        ParameterValue.zero\n    --> Vector3d.fromComponents ( 4, 2, 0 )\n\n    QuadraticSpline3d.derivative exampleSpline\n        ParameterValue.half\n    --> Vector3d.fromComponents ( 2, 2, 2 )\n\n    QuadraticSpline3d.derivative exampleSpline\n        ParameterValue.one\n    --> Vector3d.fromComponents ( 0, 2, 4 )\n\nNote that the derivative interpolates linearly from end to end.\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> Curve.ParameterValue.ParameterValue -> Vector3d.Vector3d"},{"name":"firstDerivativesAt","comment":" Evaluate the first derivative of a spline at a range of parameter values:\n\n    exampleSpline\n        |> QuadraticSpline3d.firstDerivativesAt\n            (ParameterValue.steps 2)\n    --> [ Vector3d.fromComponents ( 4, 2, 0 )\n    --> , Vector3d.fromComponents ( 2, 2, 2 )\n    --> , Vector3d.fromComponents ( 0, 2, 4 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> QuadraticSpline3d.QuadraticSpline3d -> List.List Vector3d.Vector3d"},{"name":"fromArcLengthParameterized","comment":" Get the original `QuadraticSpline3d` from which an `ArcLengthParameterized`\nvalue was constructed.\n","type":"QuadraticSpline3d.ArcLengthParameterized -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"fromNondegenerate","comment":" Convert a nondegenerate spline back to a general `QuadraticSpline3d`.\n\n    QuadraticSpline3d.fromNondegenerate\n        nondegenerateExampleSpline\n    --> exampleSpline\n\n","type":"QuadraticSpline3d.Nondegenerate -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"mirrorAcross","comment":" Mirror a spline across a plane.\n\n    QuadraticSpline3d.mirrorAcross Plane3d.xy exampleSpline\n    --> QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, -1 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 3, 2, -1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, -3 )\n    -->     }\n\n","type":"Plane3d.Plane3d -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"nondegenerate","comment":" Attempt to construct a nondegenerate spline from a general\n`QuadraticSpline3d`. If the spline is in fact degenerate (consists of a single\npoint), returns an `Err` with that point.\n\n    QuadraticSpline3d.nondegenerate exampleSpline\n    --> Ok nondegenerateExampleSpline\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> Result.Result Point3d.Point3d QuadraticSpline3d.Nondegenerate"},{"name":"on","comment":" Construct a 3D spline lying _on_ a sketch plane by providing a 2D spline\nspecified in XY coordinates _within_ the sketch plane.\n\n    QuadraticSpline3d.on SketchPlane3d.xz <|\n        QuadraticSpline2d.with\n            { startPoint =\n                Point2d.fromCoordinates ( 1, 1 )\n            , controlPoint =\n                Point2d.fromCoordinates ( 3, 4 )\n            , endPoint =\n                Point2d.fromCoordinates ( 5, 1 )\n            }\n    --> QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 0, 1 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 3, 0, 4 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 5, 0, 1 )\n    -->     }\n\n","type":"SketchPlane3d.SketchPlane3d -> QuadraticSpline2d.QuadraticSpline2d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"placeIn","comment":" Take a spline considered to be defined in local coordinates relative to a\ngiven reference frame, and return that spline expressed in global coordinates.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    QuadraticSpline3d.placeIn localFrame exampleSpline\n    --> QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 2, 3, 4 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 4, 4, 4 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 4, 5, 6 )\n    -->     }\n\n","type":"Frame3d.Frame3d -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"pointAlong","comment":" Try to get the point along a spline at a given arc length. For example, to\nget the point a quarter of the way along `exampleSpline`:\n\n    QuadraticSpline3d.pointAlong parameterizedSpline\n        (arcLength / 4)\n    --> Just <|\n    -->     Point3d.fromCoordinates\n    -->         ( 1.8227, 1.4655, 1.1083 )\n\nNote that this is not the same as evaulating at a parameter value of 1/4:\n\n    QuadraticSpline3d.pointOn exampleSpline 0.25\n    --> Point3d.fromCoordinates ( 1.875, 1.5, 1.125 )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline, returns `Nothing`.\n\n","type":"QuadraticSpline3d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Point3d.Point3d"},{"name":"pointOn","comment":" Get the point along a spline at a given parameter value:\n\n    QuadraticSpline3d.pointOn exampleSpline 0\n    --> Point3d.fromCoordinates ( 1, 1, 1 )\n\n    QuadraticSpline3d.pointOn exampleSpline 0.5\n    --> Point3d.fromCoordinates ( 2.5, 2, 1.5 )\n\n    QuadraticSpline3d.pointOn exampleSpline 1\n    --> Point3d.fromCoordinates ( 3, 3, 3 )\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> Curve.ParameterValue.ParameterValue -> Point3d.Point3d"},{"name":"pointsAt","comment":" Get points along a spline at a given set of parameter values:\n\n    exampleSpline\n        |> QuadraticSpline3d.pointsAt\n            (ParameterValue.steps 2)\n    --> [ Point3d.fromCoordinates ( 1, 1, 1 )\n    --> , Point3d.fromCoordinates ( 2.5, 2, 1.5 )\n    --> , Point3d.fromCoordinates ( 3, 3, 3 )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> QuadraticSpline3d.QuadraticSpline3d -> List.List Point3d.Point3d"},{"name":"projectInto","comment":" Project a spline into a given sketch plane. Conceptually, finds the\n[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof the spline onto the plane and then expresses the projected spline in 2D\nsketch coordinates.\n\n    exampleSpline\n        |> QuadraticSpline3d.projectInto SketchPlane3d.yz\n    --> QuadraticSpline2d.with\n    -->     { startPoint =\n    -->         Point2d.fromCoordinates ( 1, 1 )\n    -->     , controlPoint =\n    -->         Point2d.fromCoordinates ( 2, 1 )\n    -->     , endPoint =\n    -->         Point2d.fromCoordinates ( 3, 3 )\n    -->     }\n\n","type":"SketchPlane3d.SketchPlane3d -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline2d.QuadraticSpline2d"},{"name":"projectOnto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof a spline onto a plane.\n\n    QuadraticSpline3d.projectOnto Plane3d.xy exampleSpline\n    --> QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, 0 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 3, 2, 0 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 0 )\n    -->     }\n\n","type":"Plane3d.Plane3d -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"relativeTo","comment":" Take a spline defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 1, 2, 3 ))\n\n    QuadraticSpline3d.relativeTo localFrame exampleSpline\n    --> QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 0, -1, -2 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 2, 0, -2 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 2, 1, 0 )\n    -->     }\n\n","type":"Frame3d.Frame3d -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"reverse","comment":" Reverse a spline so that the start point becomes the end point, and vice\nversa.\n\n    QuadraticSpline3d.reverse exampleSpline\n    --> QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 3 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 3, 2, 1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, 1 )\n    -->     }\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"rotateAround","comment":" Rotate a spline counterclockwise around a given axis by a given angle (in\nradians).\n\n    exampleSpline\n        |> QuadraticSpline3d.rotateAround Axis3d.z\n            (degrees 90)\n    --> QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( -1, 1, 1 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( -2, 3, 1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( -3, 3, 3 )\n    -->     }\n\n","type":"Axis3d.Axis3d -> Basics.Float -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"sample","comment":" Get both the point and tangent direction of a nondegenerate spline at a\ngiven parameter value:\n\n    QuadraticSpline3d.sample nondegenerateExampleSpline\n        ParameterValue.half\n    --> ( Point3d.fromCoordinates ( 2.5, 2, 1.5 )\n    --> , Direction3d.fromAzimuthAndElevation\n    -->     (degrees 45)\n    -->     (degrees 35.26)\n    --> )\n\n","type":"QuadraticSpline3d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> ( Point3d.Point3d, Direction3d.Direction3d )"},{"name":"sampleAlong","comment":" Try to get the point and tangent direction along a spline at a given arc\nlength. To get the point and tangent direction a quarter of the way along\n`exampleSpline`:\n\n    QuadraticSpline3d.sampleAlong parameterizedSpline\n        (0.25 * arcLength)\n    --> Just\n    -->     ( Point3d.fromCoordinates\n    -->         ( 1.8227, 1.4655, 1.1083 )\n    -->     , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 33.09)\n    -->         (degrees 14.26)\n    -->     )\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline (or if the spline is degenerate), `Nothing` is returned.\n\n","type":"QuadraticSpline3d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe ( Point3d.Point3d, Direction3d.Direction3d )"},{"name":"samplesAt","comment":" Get points and tangent directions of a nondegenerate spline at a given set\nof parameter values:\n\n    nondegenerateExampleSpline\n        |> QuadraticSpline3d.samplesAt\n            (ParameterValue.steps 2)\n    --> [ ( Point3d.fromCoordinates ( 1, 1, 1 )\n    -->   , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 26.57)\n    -->         (degrees 0)\n    -->   )\n    --> , ( Point3d.fromCoordinates ( 2.5, 2, 1.5 )\n    -->   , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 45)\n    -->         (degrees 35.26)\n    -->   )\n    --> , ( Point3d.fromCoordinates ( 3, 3, 3 )\n    -->   , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 90)\n    -->         (degrees 63.43)\n    -->   )\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> QuadraticSpline3d.Nondegenerate -> List.List ( Point3d.Point3d, Direction3d.Direction3d )"},{"name":"scaleAbout","comment":" Scale a spline about the given center point by the given scale.\n\n    exampleSpline\n        |> QuadraticSpline3d.scaleAbout Point3d.origin 2\n    --> QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 2, 2, 2 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 6, 4, 2 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 6, 6, 6 )\n    -->     }\n\n","type":"Point3d.Point3d -> Basics.Float -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"secondDerivative","comment":" Get the second derivative of a spline (for a quadratic spline, this is a\nconstant).\n","type":"QuadraticSpline3d.QuadraticSpline3d -> Vector3d.Vector3d"},{"name":"splitAt","comment":" Split a spline at a particular parameter value, resulting in two smaller\nsplines.\n\n    parameterValue =\n        ParameterValue.clamped 0.75\n\n    QuadraticSpline3d.splitAt parameterValue exampleSpline\n    --> ( QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 1, 1, 1 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 2, 1.5, 1 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 2.5, 2, 1.5 )\n    -->     }\n    --> , QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 2.5, 2, 1.5 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 3, 2.5, 2 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 3, 3, 3 )\n    -->     }\n    --> )\n\n","type":"Curve.ParameterValue.ParameterValue -> QuadraticSpline3d.QuadraticSpline3d -> ( QuadraticSpline3d.QuadraticSpline3d, QuadraticSpline3d.QuadraticSpline3d )"},{"name":"startDerivative","comment":" Get the start derivative of a spline. This is equal to twice the vector from\nthe spline's first control point to its second.\n\n    QuadraticSpline3d.startDerivative exampleSpline\n    --> Vector3d.fromComponents ( 4, 2, 0 )\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> Vector3d.Vector3d"},{"name":"startPoint","comment":" Get the start point of a spline.\n\n    QuadraticSpline3d.startPoint exampleSpline\n    --> Point3d.fromCoordinates ( 1, 1, 1 )\n\n","type":"QuadraticSpline3d.QuadraticSpline3d -> Point3d.Point3d"},{"name":"tangentDirection","comment":" Get the tangent direction to a nondegenerate spline at a given parameter\nvalue:\n\n    QuadraticSpline3d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.zero\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 26.57)\n    -->     (degrees 0)\n\n    QuadraticSpline3d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.half\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 45)\n    -->     (degrees 35.26)\n\n    QuadraticSpline3d.tangentDirection\n        nondegenerateExampleSpline\n        ParameterValue.one\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 90)\n    -->     (degrees 63.43)\n\n","type":"QuadraticSpline3d.Nondegenerate -> Curve.ParameterValue.ParameterValue -> Direction3d.Direction3d"},{"name":"tangentDirectionAlong","comment":" Try to get the tangent direction along a spline at a given arc length. To\nget the tangent direction a quarter of the way along `exampleSpline`:\n\n    QuadraticSpline3d.tangentDirectionAlong\n        parameterizedSpline\n        (arcLength / 4)\n    --> Just <|\n    -->     Direction3d.fromAzimuthAndElevation\n    -->         (degrees 33.09)\n    -->         (degrees 14.26)\n\nIf the given arc length is less than zero or greater than the arc length of the\nspline (or if the spline is degenerate), returns `Nothing`.\n\n","type":"QuadraticSpline3d.ArcLengthParameterized -> Basics.Float -> Maybe.Maybe Direction3d.Direction3d"},{"name":"tangentDirectionsAt","comment":" Get tangent directions to a nondegenerate spline at a given set of parameter\nvalues:\n\n    nondegenerateExampleSpline\n        |> QuadraticSpline3d.tangentDirectionsAt\n            (ParameterValue.steps 2)\n    --> [ Direction3d.fromAzimuthAndElevation\n    -->     (degrees 26.57)\n    -->     (degrees 0)\n    --> , Direction3d.fromAzimuthAndElevation\n    -->     (degrees 45)\n    -->     (degrees 35.26)\n    --> , Direction3d.fromAzimuthAndElevation\n    -->     (degrees 90)\n    -->     (degrees 63.43)\n    --> ]\n\n","type":"List.List Curve.ParameterValue.ParameterValue -> QuadraticSpline3d.Nondegenerate -> List.List Direction3d.Direction3d"},{"name":"translateBy","comment":" Translate a spline by a given displacement.\n\n    displacement =\n        Vector3d.fromComponents ( 2, 3, 1 )\n\n    exampleSpline\n        |> QuadraticSpline3d.translateBy displacement\n    --> QuadraticSpline3d.with\n    -->     { startPoint =\n    -->         Point3d.fromCoordinates ( 3, 4, 2 )\n    -->     , controlPoint =\n    -->         Point3d.fromCoordinates ( 5, 5, 2 )\n    -->     , endPoint =\n    -->         Point3d.fromCoordinates ( 5, 6, 4 )\n    -->     }\n\n","type":"Vector3d.Vector3d -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"translateIn","comment":" Translate an arc in a given direction by a given distance;\n\n    QuadraticSpline3d.translateIn direction distance\n\nis equivalent to\n\n    QuadraticSpline3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> QuadraticSpline3d.QuadraticSpline3d -> QuadraticSpline3d.QuadraticSpline3d"},{"name":"with","comment":" Construct a spline from its start point, control point and end point:\n\n    exampleSpline =\n        QuadraticSpline3d.with\n            { startPoint =\n                Point3d.fromCoordinates ( 1, 1, 1 )\n            , controlPoint =\n                Point3d.fromCoordinates ( 3, 2, 1 )\n            , endPoint =\n                Point3d.fromCoordinates ( 3, 3, 3 )\n            }\n\n","type":"{ startPoint : Point3d.Point3d, controlPoint : Point3d.Point3d, endPoint : Point3d.Point3d } -> QuadraticSpline3d.QuadraticSpline3d"}],"binops":[]},{"name":"Rectangle2d","comment":" A `Rectangle2d` represents a rectangle in 2D space. This module contains\nrectangle-related functionality such as:\n\n  - Constructing rectangles in various ways\n  - Extracting rectangle vertices and edges\n  - Scaling, rotating, translating and mirroring rectangles\n  - Converting rectangles between different coordinate systems\n\nUnlike bounding boxes, rectangles are _not_ constrained to be axis-aligned -\nthey can have arbitrary orientation and so can be rotated, mirrored etc.\n\n@docs Rectangle2d\n\n\n# Construction\n\n@docs from, centeredOn, fromExtrema, fromExtremaIn\n\n\n# Properties\n\n@docs dimensions, axes, xAxis, yAxis, centerPoint, area\n@docs vertices, bottomLeftVertex, bottomRightVertex, topLeftVertex, topRightVertex\n@docs edges, leftEdge, bottomEdge, rightEdge, topEdge\n@docs boundingBox\n\n\n# Querying\n\n@docs contains\n\n\n# Conversion\n\n@docs toPolygon\n\n\n# Transformation\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Rectangle2d","comment":" ","args":[],"type":"Geometry.Types.Rectangle2d"}],"values":[{"name":"area","comment":" Get the area of a rectangle:\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    Rectangle2d.area rectangle\n    --> 6\n\n","type":"Rectangle2d.Rectangle2d -> Basics.Float"},{"name":"axes","comment":" Get the central axes of a rectangle as a `Frame2d`:\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    Rectangle2d.axes rectangle\n    --> Frame2d.atCoordinates ( 3.5, 2 )\n\nThe origin point of the frame will be the center point of the rectangle.\n\n","type":"Rectangle2d.Rectangle2d -> Frame2d.Frame2d"},{"name":"bottomEdge","comment":" Get the bottom edge of a rectangle;\n\n    Rectangle2d.bottomEdge rectangle\n\nis equivalent to\n\n    (Rectangle2d.edges rectangle).bottom\n\nbut is more efficient.\n\n","type":"Rectangle2d.Rectangle2d -> LineSegment2d.LineSegment2d"},{"name":"bottomLeftVertex","comment":" Get the bottom left vertex of a rectangle;\n\n    Rectangle2d.bottomLeftVertex rectangle\n\nis equivalent to\n\n    (Rectangle2d.vertices rectangle).bottomLeft\n\nbut is more efficient.\n\n","type":"Rectangle2d.Rectangle2d -> Point2d.Point2d"},{"name":"bottomRightVertex","comment":" Get the bottom right vertex of a rectangle;\n\n    Rectangle2d.bottomRightVertex rectangle\n\nis equivalent to\n\n    (Rectangle2d.vertices rectangle).bottomRight\n\nbut is more efficient.\n\n","type":"Rectangle2d.Rectangle2d -> Point2d.Point2d"},{"name":"boundingBox","comment":" Get the minimal bounding box containing a given rectangle. This have\nexactly the same shape and size as the rectangle itself if the rectangle is\naxis-aligned, but will be larger than the rectangle if the rectangle is at an\nangle.\n\n    square =\n        Rectangle2d.fromExtrema\n            { minX = 0\n            , maxX = 1\n            , minY = 0\n            , maxY = 1\n            }\n\n    diamond =\n        square\n            |> Rectangle2d.rotateAround Point2d.origin\n                (degrees 45)\n\n    Rectangle2d.boundingBox diamond\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = -0.7071\n    -->     , maxX = 0.7071\n    -->     , minY = 0\n    -->     , maxY = 1.4142\n    -->     }\n\n","type":"Rectangle2d.Rectangle2d -> BoundingBox2d.BoundingBox2d"},{"name":"centerPoint","comment":" Get the center point of a rectangle.\n","type":"Rectangle2d.Rectangle2d -> Point2d.Point2d"},{"name":"centeredOn","comment":" Construct a rectangle centered on the given axes (frame), with the given\noverall X/Y dimensions (width/height).\n\n    frame =\n        Frame2d.atCoordinates ( 3, 2 )\n\n    rectangle =\n        Rectangle2d.centeredOn frame ( 4, 3 )\n\n    Rectangle2d.vertices rectangle\n    --> { bottomLeft = Point2d.fromCoordinates ( 1, 0.5 )\n    --> , bottomRight = Point2d.fromCoordinates ( 5, 0.5 )\n    --> , topLeft = Point2d.fromCoordinates ( 1, 3.5 )\n    --> , topRight = Point2d.fromCoordinates ( 5, 3.5 )\n    --> }\n\n","type":"Frame2d.Frame2d -> ( Basics.Float, Basics.Float ) -> Rectangle2d.Rectangle2d"},{"name":"contains","comment":" Check if a rectangle contains a given point:\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    p1 =\n        Point2d.fromCoordinates ( 3, 2 )\n\n    p2 =\n        Point2d.fromCoordinates ( 3, 4 )\n\n    rectangle |> Rectangle2d.contains p1\n    --> True\n\n    rectangle |> Rectangle2d.contains p2\n    --> False\n\n","type":"Point2d.Point2d -> Rectangle2d.Rectangle2d -> Basics.Bool"},{"name":"dimensions","comment":" Get the overall dimensions (width and height) of a rectangle:\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    Rectangle2d.dimensions rectangle\n    --> ( 3, 2 )\n\n","type":"Rectangle2d.Rectangle2d -> ( Basics.Float, Basics.Float )"},{"name":"edges","comment":" Get the edges of a rectangle as a record. Note that 'bottom', 'top',\n'left' and 'right' are with respect to the rectangle's axes, so the may not\ncorrespond to global up/down or left/right if the rectangle has been rotated or\nmirrored. The orientation of each edge is chosen so that it will be in a\ncounterclockwise direction (unless the rectangle has been mirrored):\n\n  - The `bottom` edge is from the bottom left to bottom right vertex\n  - The `right` edge is from the bottom right to top right vertex\n  - The `top` edge is from the top right to top left vertex\n  - The `left` edge is from the top left to bottom left vertex\n\n(Note that this ordering will lead to each edge being in a clockwise direction\nif the rectangle _has_ been mirrored.)\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    Rectangle2d.edges rectangle\n    --> { bottom =\n    -->     LineSegment2d.fromEndpoints\n    -->         ( Point2d.fromCoordinates ( 2, 1 )\n    -->         , Point2d.fromCoordinates ( 5, 1 )\n    -->         )\n    --> , right =\n    -->     LineSegment2d.fromEndpoints\n    -->         ( Point2d.fromCoordinates ( 5, 1 )\n    -->         , Point2d.fromCoordinates ( 5, 3 )\n    -->         )\n    --> , top =\n    -->     LineSegment2d.fromEndpoints\n    -->         ( Point2d.fromCoordinates ( 5, 3 )\n    -->         , Point2d.fromCoordinates ( 2, 3 )\n    -->         )\n    --> , left =\n    -->     LineSegment2d.fromEndpoints\n    -->         ( Point2d.fromCoordinates ( 2, 3 )\n    -->         , Point2d.fromCoordinates ( 2, 1 )\n    -->         )\n    --> }\n\n","type":"Rectangle2d.Rectangle2d -> { bottom : LineSegment2d.LineSegment2d, right : LineSegment2d.LineSegment2d, top : LineSegment2d.LineSegment2d, left : LineSegment2d.LineSegment2d }"},{"name":"from","comment":" Construct an axis-aligned rectangle stretching from one point to another.\nThe order of the points does not matter, and they can represent either the\nlower left and upper right vertices or the upper left and lower right.\n\n    p1 =\n        Point2d.fromCoordinates ( 5, 2 )\n\n    p2 =\n        Point2d.fromCoordinates ( 1, 4 )\n\n    Rectangle2d.from p1 p2\n    --> Rectangle2d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 5\n    -->     , minY = 2\n    -->     , maxY = 4\n    -->     }\n\n","type":"Point2d.Point2d -> Point2d.Point2d -> Rectangle2d.Rectangle2d"},{"name":"fromExtrema","comment":" Construct an axis-aligned rectangle by specifying its minimum and maximum\nX and Y coordinates. If the min and max are given in the wrong order, they will\nbe swapped.\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    Rectangle2d.vertices rectangle\n    --> { bottomLeft = Point2d.fromCoordinates ( 2, 1 )\n    --> , bottomRight = Point2d.fromCoordinates ( 5, 1 )\n    --> , topLeft = Point2d.fromCoordinates ( 2, 3 )\n    --> , topRight = Point2d.fromCoordinates ( 5, 3 )\n    --> }\n\n","type":"{ minX : Basics.Float, maxX : Basics.Float, minY : Basics.Float, maxY : Basics.Float } -> Rectangle2d.Rectangle2d"},{"name":"fromExtremaIn","comment":" Construct a rectangle by supplying its maximum and minimum X and Y values\nwithin a particular frame:\n\n    frame =\n        Frame2d.atCoordinates ( 5, 4 )\n\n    Rectangle2d.fromExtremaIn frame\n        { minX = -1\n        , minY = -1\n        , maxX = 3\n        , maxY = 2\n        }\n    --> Rectangle2d.fromExtrema\n    -->     { minX = 4\n    -->     , minY = 3\n    -->     , maxX = 8\n    -->     , maxY = 6\n    -->     }\n\nNote that for simplicity we used a non-rotated frame in the above example - if\nwe had used a rotated frame, the result could not have been expressed using\n`Rectangle2d.fromExtrema` since it would no longer have been axis-aligned.\n\n","type":"Frame2d.Frame2d -> { minX : Basics.Float, maxX : Basics.Float, minY : Basics.Float, maxY : Basics.Float } -> Rectangle2d.Rectangle2d"},{"name":"leftEdge","comment":" Get the left edge of a rectangle;\n\n    Rectangle2d.leftEdge rectangle\n\nis equivalent to\n\n    (Rectangle2d.edges rectangle).left\n\nbut is more efficient.\n\n","type":"Rectangle2d.Rectangle2d -> LineSegment2d.LineSegment2d"},{"name":"mirrorAcross","comment":" Mirror a rectangle across a given axis.\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    Rectangle2d.mirrorAcross Axis2d.x rectangle\n    --> Rectangle2d.fromExtrema\n    -->     { minX = 2\n    -->     , maxX = 5\n    -->     , minY = -3\n    -->     , maxY = -1\n    -->     }\n\nNote that this will flip the handedness of the rectangle's axes, and therefore\nthe order/direction of results from `Rectangle2d.vertices` and\n`Rectangle2d.edges` will change.\n\n","type":"Axis2d.Axis2d -> Rectangle2d.Rectangle2d -> Rectangle2d.Rectangle2d"},{"name":"placeIn","comment":" Take a rectangle considered to be defined in local coordinates relative to a\ngiven reference frame, and return that rectangle expressed in global\ncoordinates.\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    localFrame =\n        Frame2d.atCoordinates ( 1, 2 )\n\n    Rectangle2d.placeIn localFrame rectangle\n    --> Rectangle2d.fromExtrema\n    -->     { minX = 3\n    -->     , maxX = 6\n    -->     , minY = 3\n    -->     , maxY = 5\n    -->     }\n\n","type":"Frame2d.Frame2d -> Rectangle2d.Rectangle2d -> Rectangle2d.Rectangle2d"},{"name":"relativeTo","comment":" Take a rectangle defined in global coordinates, and return it expressed\nin local coordinates relative to a given reference frame.\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    localFrame =\n        Frame2d.atCoordinates ( 1, 2 )\n\n    Rectangle2d.relativeTo localFrame rectangle\n    --> Rectangle2d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 4\n    -->     , minY = -1\n    -->     , maxY = 1\n    -->     }\n\n","type":"Frame2d.Frame2d -> Rectangle2d.Rectangle2d -> Rectangle2d.Rectangle2d"},{"name":"rightEdge","comment":" Get the right edge of a rectangle;\n\n    Rectangle2d.rightEdge rectangle\n\nis equivalent to\n\n    (Rectangle2d.edges rectangle).right\n\nbut is more efficient.\n\n","type":"Rectangle2d.Rectangle2d -> LineSegment2d.LineSegment2d"},{"name":"rotateAround","comment":" Rotate a rectangle around a given point by a given angle (in radians).\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 0\n            , maxX = 1\n            , minY = 0\n            , maxY = 1\n            }\n\n    rotated =\n        rectangle\n            |> Rectangle2d.rotateAround Point2d.origin\n                (degrees 45)\n\n    Rectangle2d.centerPoint rotated\n    --> Point2d.fromCoordinates ( 0, 0.7071 )\n\n    Rectangle2d.xDirection rotated\n    --> Direction2d.fromAngle (degrees 45)\n\n    Rectangle2d.vertices rotated\n    --> { bottomLeft =\n    -->     Point2d.origin\n    --> , bottomRight =\n    -->     Point2d.fromCoordinates ( 0.7071, 0.7071 )\n    --> , topRight =\n    -->     Point2d.fromCoordinates ( 0, 1.4142 )\n    --> , topLeft =\n    -->     Point2d.fromCoordinates ( -0.7071, 0.7071 )\n    --> }\n\n","type":"Point2d.Point2d -> Basics.Float -> Rectangle2d.Rectangle2d -> Rectangle2d.Rectangle2d"},{"name":"scaleAbout","comment":" Scale a rectangle about a given point by a given scale.\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    rectangle\n        |> Rectangle2d.scaleAbout Point2d.origin 2\n    --> Rectangle2d.fromExtrema\n    -->     { minX = 4\n    -->     , maxX = 10\n    -->     , minY = 2\n    -->     , maxY = 6\n    -->     }\n\nNote that scaling by a negative value will flip the handedness of the\nrectangle's axes, and therefore the order/direction of results from\n`Rectangle2d.vertices` and `Rectangle2d.edges` will change.\n\n","type":"Point2d.Point2d -> Basics.Float -> Rectangle2d.Rectangle2d -> Rectangle2d.Rectangle2d"},{"name":"toPolygon","comment":" Convert a rectangle to a [`Polygon2d`](Polygon2d#Polygon2d).\n","type":"Rectangle2d.Rectangle2d -> Polygon2d.Polygon2d"},{"name":"topEdge","comment":" Get the top edge of a rectangle;\n\n    Rectangle2d.topEdge rectangle\n\nis equivalent to\n\n    (Rectangle2d.edges rectangle).top\n\nbut is more efficient.\n\n","type":"Rectangle2d.Rectangle2d -> LineSegment2d.LineSegment2d"},{"name":"topLeftVertex","comment":" Get the top left vertex of a rectangle;\n\n    Rectangle2d.topLeftVertex rectangle\n\nis equivalent to\n\n    (Rectangle2d.vertices rectangle).topLeft\n\nbut is more efficient.\n\n","type":"Rectangle2d.Rectangle2d -> Point2d.Point2d"},{"name":"topRightVertex","comment":" Get the top right vertex of a rectangle;\n\n    Rectangle2d.topRightVertex rectangle\n\nis equivalent to\n\n    (Rectangle2d.vertices rectangle).topRight\n\nbut is more efficient.\n\n","type":"Rectangle2d.Rectangle2d -> Point2d.Point2d"},{"name":"translateBy","comment":" Translate a rectangle by a given displacement.\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    displacement =\n        Vector2d.fromComponents ( 2, -3 )\n\n    Rectangle2d.translateBy displacement rectangle\n    --> Rectangle2d.fromExtrema\n    -->     { minX = 4\n    -->     , maxX = 7\n    -->     , minY = -2\n    -->     , maxY = 0\n    -->     }\n\n","type":"Vector2d.Vector2d -> Rectangle2d.Rectangle2d -> Rectangle2d.Rectangle2d"},{"name":"translateIn","comment":" Translate a rectangle in a given direction by a given distance;\n\n    Rectangle2d.translateIn direction distance\n\nis equivalent to\n\n    Rectangle2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Rectangle2d.Rectangle2d -> Rectangle2d.Rectangle2d"},{"name":"vertices","comment":" Get the vertices of a rectangle as a record. Note that 'bottom', 'top',\n'left' and 'right' are with respect to the rectangle's axes, so the may not\ncorrespond to global up/down or left/right if the rectangle has been rotated or\nmirrored.\n\n    rectangle =\n        Rectangle2d.fromExtrema\n            { minX = 2\n            , maxX = 5\n            , minY = 1\n            , maxY = 3\n            }\n\n    Rectangle2d.vertices rectangle\n    --> { bottomLeft = Point2d.fromCoordinates ( 2, 1 )\n    --> , bottomRight = Point2d.fromCoordinates ( 5, 1 )\n    --> , topLeft = Point2d.fromCoordinates ( 2, 3 )\n    --> , topRight = Point2d.fromCoordinates ( 5, 3 )\n    --> }\n\n","type":"Rectangle2d.Rectangle2d -> { bottomLeft : Point2d.Point2d, bottomRight : Point2d.Point2d, topRight : Point2d.Point2d, topLeft : Point2d.Point2d }"},{"name":"xAxis","comment":" Get the X axis of a rectangle;\n\n    Rectangle2d.xAxis rectangle\n\nis equivalent to\n\n    Frame2d.xAxis (Rectangle2d.axes rectangle)\n\n","type":"Rectangle2d.Rectangle2d -> Axis2d.Axis2d"},{"name":"yAxis","comment":" Get the Y axis of a rectangle;\n\n    Rectangle2d.yAxis rectangle\n\nis equivalent to\n\n    Frame2d.yAxis (Rectangle2d.axes rectangle)\n\n","type":"Rectangle2d.Rectangle2d -> Axis2d.Axis2d"}],"binops":[]},{"name":"SketchPlane3d","comment":" A `SketchPlane3d` represents a 2D planar coordinate system in 3D space, and\nis defined by its origin point and X and Y directions (which are always\nperpendicular to each other). Sketch planes are the primary tool for converting\nback and forth between 2D and 3D coordinates:\n\n  - 3D geometry such as points, directions and line segments can be projected\n    _into_ a sketch plane, which effectively projects the geometry _onto_ the\n    sketch plane and then expresses the projected geometry _in_ 2D coordinates.\n  - 2D geometry can be place _onto_ a sketch plane to result in 3D geometry. For\n    example, a 2D point placed onto a sketch plane will result in a 3D point\n    _on_ that sketch plane that has the given 2D coordinate _in_ the sketch\n    plane.\n\nThis allows you to create algorithms that project from 3D into 2D, perform some\ncalculations in 2D, then convert the result back to 3D.\n\nMany 3D data types have `projectInto` functions that return the corresponding 2D\ndata type, and `on` functions for converting back to 3D. For example,\n[`Triangle3d.projectInto`](Triangle3d#projectInto) returns a `Triangle2d` and\n[`Triangle3d.on`](Triangle3d#on) returns a `Triangle3d`. These pairs of\nfunctions are almost, but not quite, inverses of each other:\n\n    triangle2d\n        |> Triangle3d.on sketchPlane\n        |> Triangle3d.projectInto sketchPlane\n\nwill just return the original `triangle2d` value (within roundoff error), while\n\n    triangle3d\n        |> Triangle3d.projectInto sketchPlane\n        |> Triangle3d.on sketchPlane\n\nis equivalent to\n\n    triangle3d\n        |> Triangle3d.projectOnto\n            (SketchPlane3d.toPlane sketchPlane)\n\n@docs SketchPlane3d\n\n\n# Constants\n\nThese predefined sketch planes all have the global origin point as their origin\npoint, and use the two indicated global axes as their X and Y axes. For example,\n\n    SketchPlane3d.originPoint SketchPlane3d.yz\n    --> Point3d.origin\n\n    SketchPlane3d.xDirection SketchPlane3d.yz\n    --> Direction3d.y\n\n    SketchPlane3d.yDirection SketchPlane3d.yz\n    --> Direction3d.z\n\n@docs xy, yx, yz, zy, zx, xz\n\n\n# Constructors\n\nSketch planes can also be constructed from `Frame3d` values using\n`Frame3d.xySketchPlane` etc.\n\n@docs withNormalDirection, on, throughPoints, fromPlane, unsafe\n\n\n# Conversions\n\n@docs toPlane\n\n\n# Properties\n\n@docs originPoint, xDirection, yDirection, normalDirection, xAxis, yAxis, normalAxis\n\n\n# Transformations\n\n@docs offsetBy, reverseX, reverseY, moveTo, rotateAround, rotateAroundOwn, translateBy, translateIn, translateAlongOwn, mirrorAcross\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"SketchPlane3d","comment":" ","args":[],"type":"Geometry.Types.SketchPlane3d"}],"values":[{"name":"fromPlane","comment":" Construct a SketchPlane3d from the given plane;\n\n    SketchPlane3d.fromPlane plane\n\nis equivalent to\n\n    SketchPlane3d.withNormalDirection\n        (Plane3d.normalDirection plane)\n        (Plane3d.originPoint plane)\n\nNote that because the X and Y directions of the resulting sketch plane are\nchosen arbitrarily, conversions may not work exactly as you expect. For example,\nin the current implementation,\n\n    sketchPlane =\n        SketchPlane3d.fromPlane Plane3d.xy\n\nis not equal to `SketchPlane3d.xy` (although the two sketch planes have the same\norigin point and are coplanar):\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point3d.origin\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.negativeY\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.positiveX\n\n","type":"Plane3d.Plane3d -> SketchPlane3d.SketchPlane3d"},{"name":"mirrorAcross","comment":" Mirror a sketch plane across a plane.\n\n    sketchPlane =\n        SketchPlane3d.yz\n            |> SketchPlane3d.moveTo\n                (Point2d.fromCoordinates ( 2, 1, 3 ))\n\n    mirroredSketchPlane =\n        SketchPlane3d.mirrorAcross Plane3d.xy sketchPlane\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point2d.fromCoordinates ( 2, 1, -3 )\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.y\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.negativeZ\n\n","type":"Plane3d.Plane3d -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"moveTo","comment":" Set the origin point of the given sketch plane to the given point, leaving\nits X and Y directions unchanged.\n\n    newOrigin =\n        Point3d.fromCoordinates ( 2, 1, 3 )\n\n    sketchPlane =\n        SketchPlane3d.moveTo newOrigin SketchPlane3d.yz\n\n    SketchPlane3d.originPoint sketchPlane\n    --> newOrigin\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.y\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.z\n\n","type":"Point3d.Point3d -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"normalAxis","comment":" Get the normal axis to a sketch plane (the axis formed from the sketch\nplane's origin point and normal direction).\n\n    SketchPlane3d.normalAxis SketchPlane3d.xy\n    --> Axis3d.z\n\n    SketchPlane3d.normalAxis SketchPlane3d.xz\n    --> Axis3d.reverse Axis3d.y\n\n","type":"SketchPlane3d.SketchPlane3d -> Axis3d.Axis3d"},{"name":"normalDirection","comment":" Get the normal direction to a sketch plane. This is equal to the cross\nproduct of the sketch plane's X and Y directions.\n\n    SketchPlane3d.normalDirection SketchPlane3d.xy\n    --> Direction3d.z\n\n    SketchPlane3d.normalDirection SketchPlane3d.xz\n    --> Direction3d.negativeY\n\n","type":"SketchPlane3d.SketchPlane3d -> Direction3d.Direction3d"},{"name":"offsetBy","comment":" Shift a sketch plane in its own normal direction by the given (signed)\ndistance.\n\n    SketchPlane3d.offsetBy -2.0 SketchPlane3d.xy\n        |> SketchPlane3d.originPoint\n    --> Point3d.fromCoordinates ( 0, 0, -2 )\n\n    SketchPlane3d.offsetBy 1.0 SketchPlane3d.zx\n        |> SketchPlane3d.originPoint\n    --> Point3d.fromCoordinates ( 0, 1, 0 )\n\n","type":"Basics.Float -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"on","comment":" Construct one sketch plane lying on another sketch plane, but with a\ndifferent origin point and X/Y directions. To do this, a `Frame2d` must be\nprovided that specifies the origin point and X/Y directions of the new sketch\nplane, in 2D coordinates within the existing sketch plane. Whew!\n\n    frame2d =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 2, 3 ))\n            |> Frame2d.rotateBy (degrees -30)\n\n    sketchPlane =\n        SketchPlane3d.on SketchPlane3d.yz frame2d\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point3d.fromCoordinates ( 0, 2, 3 )\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 90)\n    -->     (degrees -30)\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 90)\n    -->     (degrees 60)\n\n","type":"SketchPlane3d.SketchPlane3d -> Frame2d.Frame2d -> SketchPlane3d.SketchPlane3d"},{"name":"originPoint","comment":" Get the origin point of a sketch plane.\n\n    SketchPlane3d.originPoint SketchPlane3d.xy\n    --> Point3d.origin\n\n","type":"SketchPlane3d.SketchPlane3d -> Point3d.Point3d"},{"name":"placeIn","comment":" Take a sketch plane defined in local coordinates relative to a given\nreference frame, and return that sketch plane expressed in global coordinates.\n","type":"Geometry.Types.Frame3d -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"relativeTo","comment":" Take a sketch plane defined in global coordinates, and return it expressed\nin local coordinates relative to a given reference frame.\n","type":"Geometry.Types.Frame3d -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"reverseX","comment":" Reverse the X direction of a sketch plane, leaving its Y direction and\norigin point unchanged.\n\n    sketchPlane =\n        SketchPlane3d.reverseX SketchPlane3d.yz\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point3d.origin\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.negativeY\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.z\n\n","type":"SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"reverseY","comment":" Reverse the Y direction of a sketch plane, leaving its X direction and\norigin point unchanged.\n\n    sketchPlane =\n        SketchPlane3d.reverseY SketchPlane3d.yz\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point3d.origin\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.y\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.negativeZ\n\n","type":"SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"rotateAround","comment":" Rotate a sketch plane around an axis by a given angle (in radians). The\nsketch plane's origin point and X and Y directions will all be rotated around\nthe given axis.\n\n    SketchPlane3d.xy\n        |> SketchPlane3d.rotateAround Axis3d.x (degrees 90)\n    --> SketchPlane3d.xz\n\n","type":"Axis3d.Axis3d -> Basics.Float -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"rotateAroundOwn","comment":" Rotate a sketch plane around one of its own axes by a given angle (in\nradians).\n\nThe first argument is a function that returns the axis to rotate around, given\nthe current sketch plane. The majority of the time this will be either\n`SketchPlane3d.xAxis` or `SketchPlane3d.yAxis`.\n\nThis function is convenient when constructing sketch planes via a series of\ntransformations. For example,\n\n    sketchPlane =\n        SketchPlane3d.xy\n            |> SketchPlane3d.translateBy\n                (Vector3d.fromComponents ( 1, 0, 0 ))\n            |> SketchPlane3d.rotateAroundOwn\n                SketchPlane3d.yAxis\n                (degrees -45)\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point3d.fromCoordinates ( 1, 0, 0 )\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 0)\n    -->     (degrees 45)\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.y\n\nNote that since the rotation was around the sketch plane's own Y axis (which\npasses through the sketch plane's origin point) instead of the global Y axis,\nthe origin point itself was not affected by the rotation.\n\n","type":"(SketchPlane3d.SketchPlane3d -> Axis3d.Axis3d) -> Basics.Float -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"throughPoints","comment":" Attempt to construct a sketch plane that passes through the three given\npoints. Returns a sketch plane where:\n\n  - The origin point is the first given point\n  - The X direction is equal to the direction from the first given point to the\n    second\n  - The Y direction is chosen such that the third given point lies on the sketch\n    plane and has a positive Y coordinate within the sketch plane (that is, it\n    is on the positive Y side of the sketch plane's X axis)\n\nIf the three given points are collinear, returns `Nothing`.\n\n    SketchPlane3d.throughPoints\n        (Point3d.fromCoordinates ( 2, 0, 0 ))\n        (Point3d.fromCoordinates ( 3, 0, 0 ))\n        (Point3d.fromCoordinates ( 4, 1, 1 ))\n    --> Just sketchPlane\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point3d.fromCoordinates ( 2, 0, 0 )\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.x\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 90)\n    -->     (degrees 45)\n\n    SketchPlane3d.throughPoints\n        (Point3d.fromCoordinates ( 2, 0, 0 ))\n        (Point3d.fromCoordinates ( 3, 0, 0 ))\n        (Point3d.fromCoordinates ( 4, 0, 0 ))\n    --> Nothing\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Point3d.Point3d -> Maybe.Maybe SketchPlane3d.SketchPlane3d"},{"name":"toPlane","comment":" Convert a `SketchPlane3d` to a `Plane3d` with the same origin point and\nnormal direction.\n\n    SketchPlane3d.toPlane SketchPlane3d.xy\n    --> Plane3d.xy\n\n    SketchPlane3d.toPlane SketchPlane3d.yx\n    --> Plane3d.reverseNormal Plane3d.xy\n\n","type":"SketchPlane3d.SketchPlane3d -> Plane3d.Plane3d"},{"name":"translateAlongOwn","comment":" Translate a sketch plane along one of its own axes by a given distance.\n\nThe first argument is a function that returns the axis to translate along, given\nthe current sketch plane. The majority of the time this will be either\n`SketchPlane3d.xAxis` or `SketchPlane3d.yAxis`.\n\nThis function is convenient when constructing frames via a series of\ntransformations. For example,\n\n    sketchPlane =\n        SketchPlane3d.xy\n            |> SketchPlane3d.rotateAround\n                Axis3d.x\n                (degrees 45)\n            |> SketchPlane3d.translateAlongOwn\n                SketchPlane3d.yAxis\n                2\n\nmeans 'take the global XY sketch plane, rotate it around the global X axis by\n45 degrees, then translate the result 2 units along its own (rotated) Y axis',\nresulting in\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point3d.fromCoordinates ( 0, 1.4142, 1.4142 )\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.x\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 90)\n    -->     (degrees 45)\n\n","type":"(SketchPlane3d.SketchPlane3d -> Axis3d.Axis3d) -> Basics.Float -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"translateBy","comment":" Translate a sketch plane by a given displacement.\n\n    displacement =\n        Vector3d.fromComponents ( 2, 1, 3 )\n\n    sketchPlane =\n        SketchPlane3d.xy\n            |> SketchPlane3d.translateBy displacement\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point3d.fromCoordinates ( 2, 1, 3 )\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.x\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.y\n\n","type":"Vector3d.Vector3d -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"translateIn","comment":" Translate a sketch plane in a given direction by a given distance;\n\n    SketchPlane3d.translateIn direction distance\n\nis equivalent to\n\n    SketchPlane3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> SketchPlane3d.SketchPlane3d -> SketchPlane3d.SketchPlane3d"},{"name":"unsafe","comment":" Construct a sketch plane directly from its origin point and X and Y\ndirections:\n\n    sketchPlane =\n        SketchPlane3d.unsafe\n            { originPoint =\n                Point3d.fromCoordinates ( 2, 1, 3 )\n            , xDirection = Direction3d.positiveY\n            , yDirection = Direction3d.negativeZ\n            }\n\nIf you construct a `SketchPlane3d` this way, **you must ensure that the X and Y\nbasis directions are perpendicular to each other**.\n\n","type":"{ originPoint : Point3d.Point3d, xDirection : Direction3d.Direction3d, yDirection : Direction3d.Direction3d } -> SketchPlane3d.SketchPlane3d"},{"name":"withNormalDirection","comment":" Construct a sketch plane with the given normal direction, having the given\norigin point. The X and Y basis directions of the sketch plane will:\n\n  - be perpendicular to each other,\n  - both be perpendicular to the given normal direction, and\n  - have a cross product equal to the given normal direction.\n\nThis is useful when constructing 'scratch' sketch planes where the specific X/Y\ndirections are unimportant.\n\n    sketchPlane =\n        SketchPlane3d.withNormalDirection\n            (Direction3d.fromAzimuthAndElevation\n                (degrees 0)\n                (degrees 60)\n            )\n            Point3d.origin\n\n    SketchPlane3d.originPoint sketchPlane\n    --> Point3d.origin\n\n    SketchPlane3d.xDirection sketchPlane\n    --> Direction3d.fromAzimuthAndElevation\n    -->     (degrees 0)\n    -->     (degrees -30)\n\n    SketchPlane3d.yDirection sketchPlane\n    --> Direction3d.y\n\n","type":"Direction3d.Direction3d -> Point3d.Point3d -> SketchPlane3d.SketchPlane3d"},{"name":"xAxis","comment":" Get the X axis of a sketch plane. A 2D X coordinate within the sketch plane\ncorresponds to a distance along this axis in 3D.\n\n    SketchPlane3d.xAxis SketchPlane3d.zx\n    --> Axis3d.z\n\n","type":"SketchPlane3d.SketchPlane3d -> Axis3d.Axis3d"},{"name":"xDirection","comment":" Get the X direction of a sketch plane (the direction of the sketch plane's\nX axis).\n\n    SketchPlane3d.xDirection SketchPlane3d.zx\n    --> Direction3d.z\n\n","type":"SketchPlane3d.SketchPlane3d -> Direction3d.Direction3d"},{"name":"xy","comment":" A sketch plane formed from the global X and Y axes.\n","type":"SketchPlane3d.SketchPlane3d"},{"name":"xz","comment":" A sketch plane formed from the global X and Z axes.\n","type":"SketchPlane3d.SketchPlane3d"},{"name":"yAxis","comment":" Get the Y axis of a sketch plane. A 2D Y coordinate within the sketch plane\ncorresponds to a distance along this axis in 3D.\n\n    SketchPlane3d.yAxis SketchPlane3d.zx\n    --> Axis3d.x\n\n","type":"SketchPlane3d.SketchPlane3d -> Axis3d.Axis3d"},{"name":"yDirection","comment":" Get the Y direction of a sketch plane (the direction of the sketch plane's\nY axis).\n\n    SketchPlane3d.yDirection SketchPlane3d.zx\n    --> Direction3d.x\n\n","type":"SketchPlane3d.SketchPlane3d -> Direction3d.Direction3d"},{"name":"yx","comment":" A sketch plane formed from the global Y and X axes.\n","type":"SketchPlane3d.SketchPlane3d"},{"name":"yz","comment":" A sketch plane formed from the global Y and Z axes.\n","type":"SketchPlane3d.SketchPlane3d"},{"name":"zx","comment":" A sketch plane formed from the global Z and X axes.\n","type":"SketchPlane3d.SketchPlane3d"},{"name":"zy","comment":" A sketch plane formed from the global Z and Y axes.\n","type":"SketchPlane3d.SketchPlane3d"}],"binops":[]},{"name":"Sphere3d","comment":" A `Sphere3d` is defined by its center point and radius. This module contains\nfunctionality for:\n\n  - Constructing spheres through points\n  - Scaling, rotating and translating spheres\n  - Extracting sphere properties like center point and volume\n\n@docs Sphere3d\n\n\n# Constants\n\n@docs unit\n\n\n# Constructors\n\n@docs withRadius, throughPoints\n\n\n# Properties\n\n@docs centerPoint, radius, diameter, volume, surfaceArea, circumference, boundingBox\n\n\n# Queries\n\n@docs contains\n\n\n# Transformations\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto, projectInto\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Sphere3d","comment":" ","args":[],"type":"Geometry.Types.Sphere3d"}],"values":[{"name":"boundingBox","comment":" Get the minimal bounding box containing a given sphere.\n\n    Sphere3d.boundingBox exampleSphere\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = -2\n    -->     , maxX = 4\n    -->     , minY = -1\n    -->     , maxY = 5\n    -->     , minZ = -2\n    -->     , maxZ = 4\n    -->     }\n\n","type":"Sphere3d.Sphere3d -> BoundingBox3d.BoundingBox3d"},{"name":"centerPoint","comment":" Get the center point of a sphere.\n\n    Sphere3d.centerPoint exampleSphere\n    --> Point3d.fromCoordinates ( 1, 2, 1 )\n\n","type":"Sphere3d.Sphere3d -> Point3d.Point3d"},{"name":"circumference","comment":" Get the circumference of a sphere (the circumference of a [great circle](https://en.wikipedia.org/wiki/Great_circle)\nof the sphere).\n\n    Sphere3d.circumference exampleSphere\n    --> 18.8496\n\n","type":"Sphere3d.Sphere3d -> Basics.Float"},{"name":"contains","comment":" Check if a sphere contains a given point.\n\n    Sphere3d.contains\n        (Point3d.fromCoordinates ( 4, 2, 1 ))\n        exampleSphere\n    --> True\n\n    Sphere3d.contains\n        (Point3d.fromCoordinates ( 4.00001, 2, 1 ))\n        exampleSphere\n    --> False\n\n","type":"Point3d.Point3d -> Sphere3d.Sphere3d -> Basics.Bool"},{"name":"diameter","comment":" Get the diameter of a sphere.\n\n    Sphere3d.diameter exampleSphere\n    --> 6\n\n","type":"Sphere3d.Sphere3d -> Basics.Float"},{"name":"mirrorAcross","comment":" Mirror a sphere across a given plane.\n\n    Sphere3d.mirrorAcross Plane3d.xy exampleSphere\n    --> Sphere3d.withRadius 3\n    -->     (Point3d.fromCoordinates ( 1, 2, -1 ))\n\n","type":"Plane3d.Plane3d -> Sphere3d.Sphere3d -> Sphere3d.Sphere3d"},{"name":"placeIn","comment":" Take a sphere considered to be defined in local coordinates relative to a\ngiven reference frame, and return that sphere expressed in global coordinates.\n\n    exampleSphere\n        |> Sphere3d.placeIn\n            (Frame3d.atPoint\n                (Point3d.fromCoordinates ( 1, 2, 3 ))\n            )\n    --> Sphere3d.withRadius 3\n    -->     (Point3d.fromCoordinates ( 2, 4, 4 ))\n\n","type":"Frame3d.Frame3d -> Sphere3d.Sphere3d -> Sphere3d.Sphere3d"},{"name":"projectInto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof a sphere into a sketch plane.\n\n    Sphere3d.projectInto SketchPlane3d.xy exampleSphere\n    --> Circle2d.withRadius 3\n    -->     (Point2d.fromCoordinates ( 1, 2 ))\n\n","type":"SketchPlane3d.SketchPlane3d -> Sphere3d.Sphere3d -> Circle2d.Circle2d"},{"name":"projectOnto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof a sphere onto a plane.\n\n    Sphere3d.projectOnto Plane3d.xy exampleSphere\n    --> Circle3d.withRadius 3\n    -->     Direction3d.z\n    -->     (Point3d.fromCoordinates ( 1, 2, 0 ))\n\n","type":"Plane3d.Plane3d -> Sphere3d.Sphere3d -> Circle3d.Circle3d"},{"name":"radius","comment":" Get the radius of a sphere.\n\n    Sphere3d.radius exampleSphere\n    --> 3\n\n","type":"Sphere3d.Sphere3d -> Basics.Float"},{"name":"relativeTo","comment":" Take a sphere defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    exampleSphere\n        |> Sphere3d.relativeTo\n            (Frame3d.atPoint\n                (Point3d.fromCoordinates ( 1, 2, 3 ))\n            )\n    --> Sphere3d.withRadius 3\n    -->     (Point3d.fromCoordinates ( 0, 0, -2 ))\n\n","type":"Frame3d.Frame3d -> Sphere3d.Sphere3d -> Sphere3d.Sphere3d"},{"name":"rotateAround","comment":" Rotate a sphere around a given axis by a given angle (in radians).\n\n    exampleSphere\n        |> Sphere3d.rotateAround Axis3d.y (degrees 90)\n    --> Sphere3d.withRadius 3\n    -->     (Point3d.fromCoordinates ( 1, 2, -1 ))\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Sphere3d.Sphere3d -> Sphere3d.Sphere3d"},{"name":"scaleAbout","comment":" Scale a sphere around a given point by a given scale.\n\n    Sphere3d.scaleAbout Point3d.origin 3 exampleSphere\n    --> Sphere3d.withRadius 9\n    -->     (Point3d.fromCoordinates ( 3, 6, 3 ))\n\n","type":"Point3d.Point3d -> Basics.Float -> Sphere3d.Sphere3d -> Sphere3d.Sphere3d"},{"name":"surfaceArea","comment":" Get the surface area of a sphere.\n\n    Sphere3d.surfaceArea exampleSphere\n    --> 113.0973\n\n","type":"Sphere3d.Sphere3d -> Basics.Float"},{"name":"throughPoints","comment":" Attempt to construct a sphere that passes through the four given points.\nReturns `Nothing` if four given points are coplanar.\n\n    Sphere3d.throughPoints\n        (Point3d.fromCoordinates ( 1, 0, 0 ))\n        (Point3d.fromCoordinates ( -1, 0, 0 ))\n        (Point3d.fromCoordinates ( 0, 1, 0 ))\n        (Point3d.fromCoordinates ( 0, 0, 0.5 ))\n    --> Just\n    -->     (Sphere3d.withRadius 1.25\n    -->         (Point3d.fromCoordinates ( 0, 0, -0.75 ))\n    -->     )\n\n    Sphere3d.throughPoints\n        (Point3d.fromCoordinates ( 1, 0, 0 ))\n        (Point3d.fromCoordinates ( -1, 0, 0 ))\n        (Point3d.fromCoordinates ( 0, 1, 0 ))\n        (Point3d.fromCoordinates ( 0, -1, 0 ))\n    --> Nothing\n\n","type":"Point3d.Point3d -> Point3d.Point3d -> Point3d.Point3d -> Point3d.Point3d -> Maybe.Maybe Sphere3d.Sphere3d"},{"name":"translateBy","comment":" Translate a sphere by a given displacement.\n\n    exampleSphere\n        |> Sphere3d.translateBy\n            (Vector3d.fromComponents ( 2, 1, 3 ))\n    --> Sphere3d.withRadius 3\n    -->     (Point3d.fromCoordinates ( 3, 3, 4 ))\n\n","type":"Vector3d.Vector3d -> Sphere3d.Sphere3d -> Sphere3d.Sphere3d"},{"name":"translateIn","comment":" Translate a sphere in a given direction by a given distance;\n\n    Sphere3d.translateIn direction distance\n\nis equivalent to\n\n    Sphere3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> Sphere3d.Sphere3d -> Sphere3d.Sphere3d"},{"name":"unit","comment":" The unit sphere, centered on the origin with a radius of 1.\n\n    Sphere3d.unit\n    --> Sphere3d.withRadius 1 Point3d.origin\n\n","type":"Sphere3d.Sphere3d"},{"name":"volume","comment":" Get the volume of a sphere.\n\n    Sphere3d.volume exampleSphere\n    --> 113.0973\n\n","type":"Sphere3d.Sphere3d -> Basics.Float"},{"name":"withRadius","comment":" Construct a sphere from its radius and center point:\n\n    exampleSphere =\n        Sphere3d.withRadius 3\n            (Point3d.fromCoordinates ( 1, 2, 1 ))\n\nIf you pass a negative radius, the absolute value will be used.\n\n","type":"Basics.Float -> Point3d.Point3d -> Sphere3d.Sphere3d"}],"binops":[]},{"name":"Triangle2d","comment":" A `Triangle2d` represents a triangle in 2D space, and is defined by its\nthree vertices. This module contains triangle-related functionality such as:\n\n  - Finding the area and centroid of triangles\n  - Scaling, rotating, translating and mirroring triangles\n  - Converting triangles between different coordinate systems\n\n@docs Triangle2d\n\n\n# Constructors\n\n@docs fromVertices\n\n\n# Properties\n\n@docs vertices, edges, centroid, area, counterclockwiseArea, clockwiseArea, boundingBox, circumcircle\n\n\n# Queries\n\n@docs contains\n\n\n# Transformations\n\nTransforming a triangle is equivalent to transforming its vertices.\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, mapVertices\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Triangle2d","comment":" ","args":[],"type":"Geometry.Types.Triangle2d"}],"values":[{"name":"area","comment":" Get the area of a triangle. The result will always be positive regardless of\nwhether the triangle's vertices are in clockwise or counterclockwise order.\n\n    Triangle2d.area exampleTriangle\n    --> 1.0\n\n","type":"Triangle2d.Triangle2d -> Basics.Float"},{"name":"boundingBox","comment":" Get the minimal bounding box containing a given triangle.\n\n    Triangle2d.boundingBox exampleTriangle\n    --> BoundingBox2d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 2\n    -->     , minY = 1\n    -->     , maxY = 3\n    -->     }\n\n","type":"Triangle2d.Triangle2d -> BoundingBox2d.BoundingBox2d"},{"name":"centroid","comment":" Get the centroid (center of mass) of a triangle.\n\n    Triangle2d.centroid exampleTriangle\n    --> Point2d.fromCoordinates ( 1.3333, 1.6667 )\n\n","type":"Triangle2d.Triangle2d -> Point2d.Point2d"},{"name":"circumcircle","comment":" Attempt to find the circumcircle of a triangle, a circle that passes through\neach of the triangle's vertices;\n\n    Triangle2d.circumcircle triangle\n\nis equivalent to\n\n    ( p1, p2, p3 ) =\n        Triangle2d.vertices triangle\n\n    Circle2d.throughPoints p1 p2 p3\n\nIf the triangle is degenerate (its three vertices are collinear), returns\n`Nothing`.\n\n","type":"Triangle2d.Triangle2d -> Maybe.Maybe Circle2d.Circle2d"},{"name":"clockwiseArea","comment":" Get the signed area of a triangle, returning a positive value if the\ntriangle's vertices are in clockwise order and a negative value otherwise.\n\n    Triangle2d.clockwiseArea exampleTriangle\n    --> -1.0\n\n","type":"Triangle2d.Triangle2d -> Basics.Float"},{"name":"contains","comment":" Check whether a given point is inside a given triangle.\n\n    interiorPoint =\n        Point2d.fromCoordinates ( 1.5, 1.5 )\n\n    Triangle2d.contains interiorPoint exampleTriangle\n    --> True\n\n    Triangle2d.contains Point2d.origin exampleTriangle\n    --> False\n\nIt does not matter whether the triangle's vertices are in clockwise or\ncounterclockwise order.\n\n","type":"Point2d.Point2d -> Triangle2d.Triangle2d -> Basics.Bool"},{"name":"counterclockwiseArea","comment":" Get the signed area of a triangle, returning a positive value if the\ntriangle's vertices are in counterclockwise order and a negative value\notherwise.\n\n    Triangle2d.counterclockwiseArea exampleTriangle\n    --> 1.0\n\n","type":"Triangle2d.Triangle2d -> Basics.Float"},{"name":"edges","comment":" Get the edges of a triangle: from the first vertex to the second, from the\nsecond to the third, and from the third back to the first.\n\n\n    ( e1, e2, e3 ) =\n        Triangle2d.edges exampleTriangle\n\n\n    --> e1 =\n    -->     LineSegment2d.fromEndpoints\n    -->         ( Point2d.fromCoordinates ( 1, 1 )\n    -->         , Point2d.fromCoordinates ( 2, 1 )\n    -->         )\n    -->\n    --> e2 =\n    -->     LineSegment2d.fromEndpoints\n    -->         ( Point2d.fromCoordinates ( 2, 1 )\n    -->         , Point2d.fromCoordinates ( 1, 3 )\n    -->         )\n    -->\n    --> e3 =\n    -->     LineSegment2d.fromEndpoints\n    -->         ( Point2d.fromCoordinates ( 1, 3 )\n    -->         , Point2d.fromCoordinates ( 1, 1 )\n    -->         )\n\n","type":"Triangle2d.Triangle2d -> ( LineSegment2d.LineSegment2d, LineSegment2d.LineSegment2d, LineSegment2d.LineSegment2d )"},{"name":"fromVertices","comment":" Construct a triangle from its three vertices:\n\n    exampleTriangle =\n        Triangle2d.fromVertices\n            ( Point2d.fromCoordinates ( 1, 1 )\n            , Point2d.fromCoordinates ( 2, 1 )\n            , Point2d.fromCoordinates ( 1, 3 )\n            )\n\n","type":"( Point2d.Point2d, Point2d.Point2d, Point2d.Point2d ) -> Triangle2d.Triangle2d"},{"name":"mapVertices","comment":" Transform each vertex of a triangle by a given function and create a new\ntriangle from the resulting points. Most other transformation functions can be\ndefined in terms of `mapVertices`; for example,\n\n    Triangle2d.mirrorAcross axis\n\nis equivalent to\n\n    Triangle2d.mapVertices (Point2d.mirrorAcross axis)\n\n","type":"(Point2d.Point2d -> Point2d.Point2d) -> Triangle2d.Triangle2d -> Triangle2d.Triangle2d"},{"name":"mirrorAcross","comment":" Mirror a triangle across a given axis.\n\n    Triangle2d.mirrorAcross Axis2d.y exampleTriangle\n    --> Triangle2d.fromVertices\n    -->     ( Point2d.fromCoordinates ( -1, 1 )\n    -->     , Point2d.fromCoordinates ( -2, 1 )\n    -->     , Point2d.fromCoordinates ( -1, 3 )\n    -->     )\n\nNote that mirroring a triangle will result in its 'winding direction' being\nflipped - if the triangle's vertices were in counterclockwise order before\nmirroring, they will be in clockwise order afterwards and vice versa.\n\n","type":"Axis2d.Axis2d -> Triangle2d.Triangle2d -> Triangle2d.Triangle2d"},{"name":"placeIn","comment":" Take a triangle considered to be defined in local coordinates relative to a\ngiven reference frame, and return that triangle expressed in global coordinates.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Triangle2d.placeIn localFrame exampleTriangle\n    --> Triangle2d.fromVertices\n    -->     ( Point2d.fromCoordinates ( 2, 3 )\n    -->     , Point2d.fromCoordinates ( 3, 3 )\n    -->     , Point2d.fromCoordinates ( 2, 5 )\n    -->     )\n\n","type":"Frame2d.Frame2d -> Triangle2d.Triangle2d -> Triangle2d.Triangle2d"},{"name":"relativeTo","comment":" Take a triangle defined in global coordinates, and return it expressed\nin local coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame2d.atPoint (Point2d.fromCoordinates ( 1, 2 ))\n\n    Triangle2d.relativeTo localFrame exampleTriangle\n    --> Triangle2d.fromVertices\n    -->     ( Point2d.fromCoordinates ( 0, -1 )\n    -->     , Point2d.fromCoordinates ( 1, -1 )\n    -->     , Point2d.fromCoordinates ( 0, 1 )\n    -->     )\n\n","type":"Frame2d.Frame2d -> Triangle2d.Triangle2d -> Triangle2d.Triangle2d"},{"name":"rotateAround","comment":" Rotate a triangle around a given point by a given angle (in radians).\n\n    exampleTriangle\n        |> Triangle2d.rotateAround Point2d.origin\n            (degrees 90)\n    --> Triangle2d.fromVertices\n    -->     ( Point2d.fromCoordinates ( -1, 1 )\n    -->     , Point2d.fromCoordinates ( -1, 2 )\n    -->     , Point2d.fromCoordinates ( -3, 1 )\n    -->     )\n\n","type":"Point2d.Point2d -> Basics.Float -> Triangle2d.Triangle2d -> Triangle2d.Triangle2d"},{"name":"scaleAbout","comment":" Scale a triangle about a given point by a given scale.\n\n    Triangle2d.scaleAbout Point2d.origin 2 exampleTriangle\n    --> Triangle2d.fromVertices\n    -->     ( Point2d.fromCoordinates ( 2, 2 )\n    -->     , Point2d.fromCoordinates ( 4, 2 )\n    -->     , Point2d.fromCoordinates ( 2, 6 )\n    -->     )\n\nNote that scaling by a negative value will result in the 'winding direction' of\nthe triangle being flipped - if the triangle's vertices were in counterclockwise\norder before the negative scaling, they will be in clockwise order afterwards\nand vice versa.\n\n","type":"Point2d.Point2d -> Basics.Float -> Triangle2d.Triangle2d -> Triangle2d.Triangle2d"},{"name":"translateBy","comment":" Translate a triangle by a given displacement.\n\n    displacement =\n        Vector2d.fromComponents ( 2, -3 )\n\n    Triangle2d.translateBy displacement exampleTriangle\n    --> Triangle2d.fromVertices\n    -->     ( Point2d.fromCoordinates ( 3, -2 )\n    -->     , Point2d.fromCoordinates ( 4, -2 )\n    -->     , Point2d.fromCoordinates ( 3, 0 )\n    -->     )\n\n","type":"Vector2d.Vector2d -> Triangle2d.Triangle2d -> Triangle2d.Triangle2d"},{"name":"translateIn","comment":" Translate a triangle in a given direction by a given distance;\n\n    Triangle2d.translateIn direction distance\n\nis equivalent to\n\n    Triangle2d.translateBy\n        (Vector2d.withLength distance direction)\n\n","type":"Direction2d.Direction2d -> Basics.Float -> Triangle2d.Triangle2d -> Triangle2d.Triangle2d"},{"name":"vertices","comment":" Get the vertices of a triangle.\n\n\n    ( p1, p2, p3 ) =\n        Triangle2d.vertices exampleTriangle\n\n\n    --> p1 = Point2d.fromCoordinates ( 1, 1 )\n    --> p2 = Point2d.fromCoordinates ( 2, 1 )\n    --> p3 = Point2d.fromCoordinates ( 1, 3 )\n\n","type":"Triangle2d.Triangle2d -> ( Point2d.Point2d, Point2d.Point2d, Point2d.Point2d )"}],"binops":[]},{"name":"Triangle3d","comment":" A `Triangle3d` represents a triangle in 3D space, and is defined by its\nthree vertices. This module contains triangle-related functionality such as:\n\n  - Finding the area and centroid of triangles\n  - Scaling, rotating, translating, mirroring and projecting triangles\n  - Converting triangles between different coordinate systems\n\n@docs Triangle3d\n\n\n# Constructors\n\n@docs fromVertices, on\n\n\n# Properties\n\n@docs vertices, edges, centroid, area, normalDirection, boundingBox, circumcircle\n\n\n# Transformations\n\nTransforming a triangle is equivalent to transforming its vertices.\n\n@docs scaleAbout, rotateAround, translateBy, translateIn, mirrorAcross, projectOnto, mapVertices\n\n\n# Coordinate conversions\n\n@docs relativeTo, placeIn, projectInto\n\n","unions":[],"aliases":[{"name":"Triangle3d","comment":" ","args":[],"type":"Geometry.Types.Triangle3d"}],"values":[{"name":"area","comment":" Get the area of a triangle. This value is always positive.\n\n    Triangle3d.area exampleTriangle\n    --> 1.5811\n\n","type":"Triangle3d.Triangle3d -> Basics.Float"},{"name":"boundingBox","comment":" Get the minimal bounding box containing a given triangle.\n\n    Triangle3d.boundingBox exampleTriangle\n    --> BoundingBox3d.fromExtrema\n    -->     { minX = 1\n    -->     , maxX = 2\n    -->     , minY = 0\n    -->     , maxY = 1\n    -->     , minZ = 0\n    -->     , maxZ = 3\n    -->     }\n\n","type":"Triangle3d.Triangle3d -> BoundingBox3d.BoundingBox3d"},{"name":"centroid","comment":" Get the centroid (center of mass) of a triangle.\n\n    Triangle3d.centroid exampleTriangle\n    --> Point3d.fromCoordinates ( 1.6667, 0.6667, 1 )\n\n","type":"Triangle3d.Triangle3d -> Point3d.Point3d"},{"name":"circumcircle","comment":" Attempt to find the circumcircle of a triangle, a circle that passes through\neach of the triangle's vertices;\n\n    Triangle3d.circumcircle triangle\n\nis equivalent to\n\n    ( p1, p2, p3 ) =\n        Triangle3d.vertices triangle\n\n    Circle3d.throughPoints p1 p2 p3\n\nIf the triangle is degenerate (its three vertices are collinear), returns\n`Nothing`.\n\n","type":"Triangle3d.Triangle3d -> Maybe.Maybe Circle3d.Circle3d"},{"name":"edges","comment":" Get the edges of a triangle: from the first vertex to the second, from the\nsecond to the third, and from the third back to the first.\n\n\n    ( e1, e2, e3 ) =\n        Triangle3d.edges exampleTriangle\n\n\n    --> e1 =\n    -->     LineSegment3d.fromEndpoints\n    -->         ( Point3d.fromCoordinates ( 1, 0, 0 )\n    -->         , Point3d.fromCoordinates ( 2, 0, 0 )\n    -->         )\n    -->\n    --> e2 =\n    -->     LineSegment3d.fromEndpoints\n    -->         ( Point3d.fromCoordinates ( 2, 0, 0 )\n    -->         , Point3d.fromCoordinates ( 2, 1, 3 )\n    -->         )\n    -->\n    --> e3 =\n    -->     LineSegment3d.fromEndpoints\n    -->         ( Point3d.fromCoordinates ( 2, 1, 3 )\n    -->         , Point3d.fromCoordinates ( 1, 0, 0 )\n    -->         )\n\n","type":"Triangle3d.Triangle3d -> ( LineSegment3d.LineSegment3d, LineSegment3d.LineSegment3d, LineSegment3d.LineSegment3d )"},{"name":"fromVertices","comment":" Construct a triangle from its three vertices:\n\n    exampleTriangle =\n        Triangle3d.fromVertices\n            ( Point3d.fromCoordinates ( 1, 0, 0 )\n            , Point3d.fromCoordinates ( 2, 0, 0 )\n            , Point3d.fromCoordinates ( 2, 1, 3 )\n            )\n\n","type":"( Point3d.Point3d, Point3d.Point3d, Point3d.Point3d ) -> Triangle3d.Triangle3d"},{"name":"mapVertices","comment":" Transform each vertex of a triangle by a given function and create a new\ntriangle from the resulting points. Most other transformation functions can be\ndefined in terms of `mapVertices`; for example,\n\n    Triangle3d.projectOnto plane\n\nis equivalent to\n\n    Triangle3d.mapVertices (Point3d.projectOnto plane)\n\n","type":"(Point3d.Point3d -> Point3d.Point3d) -> Triangle3d.Triangle3d -> Triangle3d.Triangle3d"},{"name":"mirrorAcross","comment":" Mirror a triangle across a given plane.\n\n    Triangle3d.mirrorAcross Plane3d.yz exampleTriangle\n    --> Triangle3d.fromVertices\n    -->     ( Point3d.fromCoordinates ( -1, 0, 0 )\n    -->     ( Point3d.fromCoordinates ( -2, 0, 0 )\n    -->     ( Point3d.fromCoordinates ( -2, 1, 3 )\n    -->     )\n\n","type":"Plane3d.Plane3d -> Triangle3d.Triangle3d -> Triangle3d.Triangle3d"},{"name":"normalDirection","comment":" Attempt to find the normal direction to a triangle. The resulting direction\nwill be oriented such that the triangle vertices are in counterclockwise order\naround it according to the right-hand rule. If the triangle is degenerate (its\nthree vertices are collinear), returns `Nothing`.\n\n    Triangle3d.normalDirection exampleTriangle\n    --> Just\n    -->     (Direction3d.fromAzimuthAndElevation\n    -->         (degrees -90)\n    -->         (degrees 18.43)\n    -->     )\n\n","type":"Triangle3d.Triangle3d -> Maybe.Maybe Direction3d.Direction3d"},{"name":"on","comment":" Construct a 3D triangle lying _on_ a sketch plane by providing a 2D triangle\nspecified in XY coordinates _within_ the sketch plane.\n\n    Triangle3d.on SketchPlane3d.xz <|\n        Triangle2d.fromVertices\n            ( Point2d.fromCoordinates ( 1, 1 )\n            , Point2d.fromCoordinates ( 2, 1 )\n            , Point2d.fromCoordinates ( 1, 3 )\n            )\n    --> Triangle3d.fromVertices\n    -->     ( Point3d.fromCoordinates ( 1, 0, 1 )\n    -->     , Point3d.fromCoordinates ( 2, 0, 1 )\n    -->     , Point3d.fromCoordinates ( 1, 0, 3 )\n    -->     )\n\n","type":"SketchPlane3d.SketchPlane3d -> Triangle2d.Triangle2d -> Triangle3d.Triangle3d"},{"name":"placeIn","comment":" Take a triangle considered to be defined in local coordinates relative to a\ngiven reference frame, and return that triangle expressed in global coordinates.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 2, 1, 3 ))\n\n    Triangle3d.placeIn localFrame exampleTriangle\n    --> Triangle3d.fromVertices\n    -->     ( Point3d.fromCoordinates ( 3, 1, 3 )\n    -->     , Point3d.fromCoordinates ( 4, 1, 3 )\n    -->     , Point3d.fromCoordinates ( 4, 2, 6 )\n    -->     )\n\n","type":"Frame3d.Frame3d -> Triangle3d.Triangle3d -> Triangle3d.Triangle3d"},{"name":"projectInto","comment":" Project a triangle into a given sketch plane. Conceptually, this finds the\n[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof the triangle onto the plane and then expresses the projected triangle in 2D\nsketch coordinates.\n\n    Triangle3d.projectInto SketchPlane3d.xy exampleTriangle\n    --> Triangle2d.fromVertices\n    -->     ( Point2d.fromCoordinates ( 1, 0 )\n    -->     , Point2d.fromCoordinates ( 2, 0 )\n    -->     , Point2d.fromCoordinates ( 2, 1 )\n    -->     )\n\n    Triangle3d.projectInto SketchPlane3d.zx exampleTriangle\n    --> Triangle2d.fromVertices\n    -->     ( Point2d.fromCoordinates ( 0, 1 )\n    -->     , Point2d.fromCoordinates ( 0, 2 )\n    -->     , Point2d.fromCoordinates ( 3, 2 )\n    -->     )\n\n","type":"SketchPlane3d.SketchPlane3d -> Triangle3d.Triangle3d -> Triangle2d.Triangle2d"},{"name":"projectOnto","comment":" Find the [orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof a triangle onto a plane.\n\n    Triangle3d.projectOnto Plane3d.xy exampleTriangle\n    --> Triangle3d.fromVertices\n    -->     ( Point3d.fromCoordinates ( 1, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 2, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 2, 1, 0 )\n    -->     )\n\n    Triangle3d.projectOnto Plane3d.xz exampleTriangle\n    --> Triangle3d.fromVertices\n    -->     ( Point3d.fromCoordinates ( 1, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 2, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 2, 0, 3 )\n    -->     )\n\n","type":"Plane3d.Plane3d -> Triangle3d.Triangle3d -> Triangle3d.Triangle3d"},{"name":"relativeTo","comment":" Take a triangle defined in global coordinates, and return it expressed\nin local coordinates relative to a given reference frame.\n\n    localFrame =\n        Frame3d.atPoint\n            (Point3d.fromCoordinates ( 2, 1, 3 ))\n\n    Triangle3d.relativeTo localFrame exampleTriangle\n    --> Triangle3d.fromVertices\n    -->     ( Point3d.fromCoordinates ( -1, -1, -3 )\n    -->     , Point3d.fromCoordinates ( 0, -1, -3 )\n    -->     , Point3d.fromCoordinates ( 0, 0, 0 )\n    -->     )\n\n","type":"Frame3d.Frame3d -> Triangle3d.Triangle3d -> Triangle3d.Triangle3d"},{"name":"rotateAround","comment":" Rotate a triangle around a given axis by a given angle (in radians).\n\n    exampleTriangle\n        |> Triangle3d.rotateAround Axis3d.z (degrees 90)\n    --> Triangle3d.fromVertices\n    -->     ( Point3d.fromCoordinates ( 0, 1, 0 )\n    -->     , Point3d.fromCoordinates ( 0, 2, 0 )\n    -->     , Point3d.fromCoordinates ( -1, 2, 3 )\n    -->     )\n\n","type":"Axis3d.Axis3d -> Basics.Float -> Triangle3d.Triangle3d -> Triangle3d.Triangle3d"},{"name":"scaleAbout","comment":" Scale a triangle about a given point by a given scale.\n\n    Triangle3d.scaleAbout Point3d.origin 2 exampleTriangle\n    --> Triangle3d.fromVertices\n    -->     ( Point3d.fromCoordinates ( 2, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 4, 0, 0 )\n    -->     , Point3d.fromCoordinates ( 4, 2, 6 )\n    -->     )\n\n","type":"Point3d.Point3d -> Basics.Float -> Triangle3d.Triangle3d -> Triangle3d.Triangle3d"},{"name":"translateBy","comment":" Translate a triangle by a given displacement.\n\n    displacement =\n        Vector3d.fromComponents ( 2, -1, 3 )\n\n    Triangle3d.translateBy displacement exampleTriangle\n    --> Triangle3d.fromVertices\n    -->     ( Point3d.fromCoordinates ( 3, -1, 3 )\n    -->     , Point3d.fromCoordinates ( 4, -1, 3 )\n    -->     , Point3d.fromCoordinates ( 4, 0, 6 )\n    -->     )\n\n","type":"Vector3d.Vector3d -> Triangle3d.Triangle3d -> Triangle3d.Triangle3d"},{"name":"translateIn","comment":" Translate a triangle in a given direction by a given distance;\n\n    Triangle3d.translateIn direction distance\n\nis equivalent to\n\n    Triangle3d.translateBy\n        (Vector3d.withLength distance direction)\n\n","type":"Direction3d.Direction3d -> Basics.Float -> Triangle3d.Triangle3d -> Triangle3d.Triangle3d"},{"name":"vertices","comment":" Get the vertices of a triangle.\n\n\n    ( p1, p2, p3 ) =\n        Triangle3d.vertices exampleTriangle\n\n\n    --> p1 = Point3d.fromCoordinates ( 1, 0, 0 )\n    --> p2 = Point3d.fromCoordinates ( 2, 0, 0 )\n    --> p3 = Point3d.fromCoordinates ( 2, 1, 3 )\n\n","type":"Triangle3d.Triangle3d -> ( Point3d.Point3d, Point3d.Point3d, Point3d.Point3d )"}],"binops":[]},{"name":"Vector2d","comment":" A `Vector2d` represents a quantity such as a displacement or velocity in 2D,\nand is defined by its X and Y components. This module contains a variety of\nvector-related functionality, such as\n\n  - Adding or subtracting vectors\n  - Finding the lengths of vectors\n  - Rotating vectors\n  - Converting vectors between different coordinate systems\n\nNote that unlike in many other geometry packages where vectors are used as a\ngeneral-purpose data type, `elm-geometry` has separate data types for vectors,\ndirections and points. In most code it is actually more common to use `Point2d`\nand `Direction2d` than `Vector2d`, and much code can avoid working directly with\n`Vector2d` values at all!\n\n@docs Vector2d\n\n\n# Constants\n\n@docs zero\n\nAlthough there are no predefined constants for the vectors with components\n(1,&nbsp;0) and (0,&nbsp;1), in most cases you will actually want their\n`Direction2d` versions [`Direction2d.x`](Direction2d#x) and [`Direction2d.y`](Direction2d#y).\n\n\n# Constructors\n\n@docs fromComponents, fromPolarComponents, from, withLength, perpendicularTo, interpolateFrom\n\n\n# Properties\n\n@docs components, xComponent, yComponent, polarComponents, length, squaredLength, direction, lengthAndDirection\n\n\n# Comparison\n\n@docs equalWithin\n\n\n# Measurement\n\n@docs componentIn\n\n\n# Arithmetic\n\n@docs sum, difference, dotProduct, crossProduct\n\n\n# Transformations\n\nNote that for `mirrorAcross` and `projectOnto`, only the direction of the axis\naffects the result, since vectors are position-independent. Think of\nmirroring/projecting a vector across/onto an axis as moving the vector so its\ntail is on the axis, then mirroring/projecting its tip across/onto the axis.\n\n@docs reverse, normalize, scaleBy, rotateBy, rotateClockwise, rotateCounterclockwise, mirrorAcross, projectionIn, projectOnto\n\n\n# Coordinate conversions\n\nLike other transformations, coordinate conversions of vectors depend only on the\norientations of the relevant frames, not the positions of their origin points.\n\nFor the examples, assume the following frame has been defined:\n\n    rotatedFrame =\n        Frame2d.atOrigin |> Frame2d.rotateBy (degrees 30)\n\n@docs relativeTo, placeIn\n\n","unions":[],"aliases":[{"name":"Vector2d","comment":" ","args":[],"type":"Geometry.Types.Vector2d"}],"values":[{"name":"componentIn","comment":" Find the component of a vector in an arbitrary direction, for example\n\n    forwardSpeed =\n        Vector2d.componentIn forwardDirection velocity\n\nThis is more general and flexible than using `xComponent` or `yComponent`, both\nof which can be expressed in terms of `componentIn`; for example,\n\n    Vector2d.xComponent vector\n\nis equivalent to\n\n    Vector2d.componentIn Direction2d.x vector\n\n","type":"Geometry.Types.Direction2d -> Vector2d.Vector2d -> Basics.Float"},{"name":"components","comment":" Extract the components of a vector.\n\n    Vector2d.components (Vector2d.fromComponents ( 2, 3 ))\n    --> ( 2, 3 )\n\nThis combined with Elm's built-in tuple destructuring provides a convenient way\nto extract both the X and Y components of a vector in one line of code:\n\n    ( x, y ) =\n        Vector2d.components vector\n\n","type":"Vector2d.Vector2d -> ( Basics.Float, Basics.Float )"},{"name":"crossProduct","comment":" Find the scalar 'cross product' of two vectors in 2D. This is defined as\n\n    crossProduct firstVector secondVector =\n        let\n            ( x1, y1 ) =\n                components firstVector\n\n            ( x2, y2 ) =\n                components secondVector\n        in\n        x1 * y2 - y1 * x2\n\nand is useful in many of the same ways as the 3D cross product:\n\n  - Its length is equal to the product of the lengths of the two given vectors\n    and the sine of the angle between them, so it can be used as a metric to\n    determine if two vectors are nearly parallel.\n  - The sign of the result indicates the direction of rotation from the first\n    vector to the second (positive indicates a counterclockwise rotation and\n    negative indicates a clockwise rotation), similar to how the direction of\n    the 3D cross product indicates the direction of rotation.\n\nSome examples:\n\n    firstVector =\n        Vector2d.fromComponents ( 2, 0 )\n\n    secondVector =\n        Vector2d.fromComponents ( 0, 3 )\n\n    Vector2d.crossProduct firstVector secondVector\n    --> 6\n\n    Vector2d.crossProduct secondVector firstVector\n    --> -6\n\n    Vector2d.crossProduct firstVector firstVector\n    --> 0\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d -> Basics.Float"},{"name":"difference","comment":" Find the difference between two vectors (the first vector minus the second).\n\n    firstVector =\n        Vector2d.fromComponents ( 5, 6 )\n\n    secondVector =\n        Vector2d.fromComponents ( 1, 3 )\n\n    Vector2d.difference firstVector secondVector\n    --> Vector2d.fromComponents ( 4, 3 )\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"direction","comment":" Attempt to find the direction of a vector. In the case of a zero vector,\nreturn `Nothing`.\n\n    Vector2d.direction (Vector2d.fromComponents ( 3, 3 ))\n    --> Just (Direction2d.fromAngle (degrees 45))\n\n    Vector2d.direction Vector2d.zero\n    --> Nothing\n\n","type":"Vector2d.Vector2d -> Maybe.Maybe Geometry.Types.Direction2d"},{"name":"dotProduct","comment":" Find the dot product of two vectors.\n\n    firstVector =\n        Vector2d.fromComponents ( 1, 2 )\n\n    secondVector =\n        Vector2d.fromComponents ( 3, 4 )\n\n    Vector2d.dotProduct firstVector secondVector\n    --> 11\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d -> Basics.Float"},{"name":"equalWithin","comment":" Compare two vectors within a tolerance. Returns true if the difference\nbetween the two given vectors has magnitude less than the given tolerance.\n\n    firstVector =\n        Vector2d.fromComponents ( 1, 2 )\n\n    secondVector =\n        Vector2d.fromComponents ( 0.9999, 2.0002 )\n\n    Vector2d.equalWithin 1e-3 firstVector secondVector\n    --> True\n\n    Vector2d.equalWithin 1e-6 firstVector secondVector\n    --> False\n\n","type":"Basics.Float -> Vector2d.Vector2d -> Vector2d.Vector2d -> Basics.Bool"},{"name":"from","comment":" Construct a vector from the first given point to the second.\n\n    startPoint =\n        Point2d.fromCoordinates ( 1, 1 )\n\n    endPoint =\n        Point2d.fromCoordinates ( 4, 5 )\n\n    Vector2d.from startPoint endPoint\n    --> Vector2d.fromComponents ( 3, 4 )\n\n","type":"Geometry.Types.Point2d -> Geometry.Types.Point2d -> Vector2d.Vector2d"},{"name":"fromComponents","comment":" Construct a vector from its X and Y components.\n\n    vector =\n        Vector2d.fromComponents ( 2, 3 )\n\n","type":"( Basics.Float, Basics.Float ) -> Vector2d.Vector2d"},{"name":"fromPolarComponents","comment":" Construct a vector from a length and angle. The angle is measured\ncounterclockwise from the positive X direction.\n\n    Vector2d.fromPolarComponents ( 2, degrees 135 )\n    -->Vector2d.fromComponents ( -1.4142, 1.4142 )\n\n","type":"( Basics.Float, Basics.Float ) -> Vector2d.Vector2d"},{"name":"interpolateFrom","comment":" Construct a vector by interpolating from the first given vector to the\nsecond, based on a parameter that ranges from zero to one.\n\n    startVector =\n        Vector2d.zero\n\n    endVector =\n        Vector2d.fromComponents ( 8, 12 )\n\n    Vector2d.interpolateFrom startVector endVector 0.25\n    --> Vector2d.fromComponents ( 2, 3 )\n\nPartial application may be useful:\n\n    interpolatedVector : Float -> Vector2d\n    interpolatedVector =\n        Vector2d.interpolateFrom startVector endVector\n\n    List.map interpolatedVector [ 0, 0.5, 1 ]\n    --> [ Vector2d.fromComponents ( 0, 0 )\n    --> , Vector2d.fromComponents ( 4, 6 )\n    --> , Vector2d.fromComponents ( 8, 12 )\n    --> ]\n\nYou can pass values less than zero or greater than one to extrapolate:\n\n    interpolatedVector -0.5\n    --> Vector2d.fromComponents ( -4, -6 )\n\n    interpolatedVector 1.25\n    --> Vector2d.fromComponents ( 10, 15 )\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d -> Basics.Float -> Vector2d.Vector2d"},{"name":"length","comment":" Get the length (magnitude) of a vector.\n\n    Vector2d.length (Vector2d.fromComponents ( 3, 4 ))\n    --> 5\n\n","type":"Vector2d.Vector2d -> Basics.Float"},{"name":"lengthAndDirection","comment":" Attempt to find the length and direction of a vector. In the case of a zero\nvector, returns `Nothing`.\n\n    vector =\n        Vector2d.fromComponents ( 1, 1 )\n\n    Vector2d.lengthAndDirection vector\n    --> Just\n    -->     ( 1.4142\n    -->     , Direction2d.fromAngle (degrees 45)\n    -->     )\n\n    Vector2d.lengthAndDirection Vector2d.zero\n    --> Nothing\n\n","type":"Vector2d.Vector2d -> Maybe.Maybe ( Basics.Float, Geometry.Types.Direction2d )"},{"name":"mirrorAcross","comment":" Mirror a vector across a given axis.\n\n    vector =\n        Vector2d.fromComponents ( 2, 3 )\n\n    Vector2d.mirrorAcross Axis2d.y vector\n    --> Vector2d.fromComponents ( -2, 3 )\n\nThe position of the axis doesn't matter, only its orientation:\n\n    horizontalAxis =\n        Axis2d.withDirection Direction2d.x\n            (Point2d.fromCoordinates ( 100, 200 ))\n\n    Vector2d.mirrorAcross horizontalAxis vector\n    --> Vector2d.fromComponents ( 2, -3 )\n\n","type":"Geometry.Types.Axis2d -> Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"normalize","comment":" Normalize a vector to have a length of one. Zero vectors are left as-is.\n\n    vector =\n        Vector2d.fromComponents ( 3, 4 )\n\n    Vector2d.normalize vector\n    --> Vector2d.fromComponents ( 0.6, 0.8 )\n\n    Vector2d.normalize Vector2d.zero\n    --> Vector2d.zero\n\n**Warning**: `Vector2d.direction` is safer since it forces you to explicitly\nconsider the case where the given vector is zero. `Vector2d.normalize` is\nprimarily useful for cases like generating WebGL meshes, where defaulting to a\nzero vector for degenerate cases is acceptable, and the overhead of something\nlike\n\n    Vector2d.direction vector\n        |> Maybe.map Direction2d.toVector\n        |> Maybe.withDefault Vector2d.zero\n\n(which is functionally equivalent to `Vector2d.normalize vector`) is too high.\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"perpendicularTo","comment":" Construct a vector perpendicular to the given vector, by rotating the given\nvector 90 degrees counterclockwise. The constructed vector will have the same\nlength as the given vector. Alias for `Vector2d.rotateCounterclockwise`.\n\n    Vector2d.perpendicularTo\n        (Vector2d.fromComponents ( 1, 0 ))\n    --> Vector2d.fromComponents ( 0, 1 )\n\n    Vector2d.perpendicularTo\n        (Vector2d.fromComponents ( 0, 2 ))\n    --> Vector2d.fromComponents ( -2, 0 )\n\n    Vector2d.perpendicularTo\n        (Vector2d.fromComponents ( 3, 1 ))\n    --> Vector2d.fromComponents ( -1, 3 )\n\n    Vector2d.perpendicularTo Vector2d.zero\n    --> Vector2d.zero\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"placeIn","comment":" Take a vector defined in local coordinates relative to a given reference\nframe, and return that vector expressed in global coordinates.\n\n    Vector2d.fromComponents ( 2, 0 )\n        |> Vector2d.placeIn rotatedFrame\n    --> Vector2d.fromComponents ( 1.732, 1 )\n\n","type":"Geometry.Types.Frame2d -> Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"polarComponents","comment":" Get the polar components (length, polar angle) of a vector.\n\n    Vector2d.polarComponents\n        (Vector2d.fromComponents ( 1, 1 ))\n    --> ( 1.4142, degrees 45 )\n\n","type":"Vector2d.Vector2d -> ( Basics.Float, Basics.Float )"},{"name":"projectOnto","comment":" Project a vector onto an axis.\n\n    Vector2d.projectOnto Axis2d.y\n        (Vector2d.fromComponents ( 3, 4 ))\n    --> Vector2d.fromComponents ( 0, 4 )\n\n    Vector2d.projectOnto Axis2d.x\n        (Vector2d.fromComponents ( -1, 2 ))\n    --> Vector2d.fromComponents ( -1, 0 )\n\nThis is equivalent to finding the projection in the axis' direction.\n\n","type":"Geometry.Types.Axis2d -> Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"projectionIn","comment":" Find the projection of a vector in a particular direction. Conceptually,\nthis means splitting the original vector into a portion parallel to the given\ndirection and a portion perpendicular to it, then returning the parallel\nportion.\n\n    vector =\n        Vector2d.fromComponents ( 2, 3 )\n\n    Vector2d.projectionIn Direction2d.x vector\n    --> Vector2d.fromComponents ( 2, 0 )\n\n    Vector2d.projectionIn Direction2d.y vector\n    --> Vector2d.fromComponents ( 0, 3 )\n\n","type":"Geometry.Types.Direction2d -> Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"relativeTo","comment":" Take a vector defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    Vector2d.fromComponents ( 2, 0 )\n        |> Vector2d.relativeTo rotatedFrame\n    --> Vector2d.fromComponents ( 1.732, -1 )\n\n","type":"Geometry.Types.Frame2d -> Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"reverse","comment":" Reverse the direction of a vector, negating its components.\n\n    Vector2d.reverse (Vector2d.fromComponents ( -1, 2 ))\n    --> Vector2d.fromComponents ( 1, -2 )\n\n(This could have been called `negate`, but `reverse` is more consistent with\nthe naming used in other modules.)\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"rotateBy","comment":" Rotate a vector counterclockwise by a given angle (in radians).\n\n    Vector2d.fromComponents ( 1, 1 )\n        |> Vector2d.rotateBy (degrees 45)\n    --> Vector2d.fromComponents ( 0, 1.4142 )\n\n    Vector2d.fromComponents ( 1, 0 )\n        |> Vector2d.rotateBy pi\n    --> Vector2d.fromComponents ( -1, 0 )\n\n","type":"Basics.Float -> Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"rotateClockwise","comment":" Rotate the given vector 90 degrees clockwise;\n\n    Vector2d.rotateClockwise vector\n\nis equivalent to\n\n    Vector2d.rotateBy (degrees -90) vector\n\nbut is more efficient.\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"rotateCounterclockwise","comment":" Rotate the given vector 90 degrees counterclockwise;\n\n    Vector2d.rotateCounterclockwise vector\n\nis equivalent to\n\n    Vector2d.rotateBy (degrees 90) vector\n\nbut is more efficient.\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"scaleBy","comment":" Scale the length of a vector by a given scale.\n\n    Vector2d.scaleBy 3 (Vector2d.fromComponents ( 1, 2 ))\n    --> Vector2d.fromComponents ( 3, 6 )\n\n(This could have been called `multiply` or `times`, but `scaleBy` was chosen as\na more geometrically meaningful name and to be consistent with the `scaleAbout`\nname used in other modules.)\n\n","type":"Basics.Float -> Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"squaredLength","comment":" Get the squared length of a vector. `squaredLength` is slightly faster than\n`length`, so for example\n\n    Vector2d.squaredLength vector > tolerance * tolerance\n\nis equivalent to but slightly more efficient than\n\n    Vector2d.length vector > tolerance\n\nsince the latter requires a square root under the hood. In many cases, however,\nthe speed difference will be negligible and using `length` is much more\nreadable!\n\n","type":"Vector2d.Vector2d -> Basics.Float"},{"name":"sum","comment":" Find the sum of two vectors.\n\n    firstVector =\n        Vector2d.fromComponents ( 1, 2 )\n\n    secondVector =\n        Vector2d.fromComponents ( 3, 4 )\n\n    Vector2d.sum firstVector secondVector\n    --> Vector2d.fromComponents ( 4, 6 )\n\n","type":"Vector2d.Vector2d -> Vector2d.Vector2d -> Vector2d.Vector2d"},{"name":"withLength","comment":" Construct a vector with the given length in the given direction.\n\n    Vector2d.withLength 5 Direction2d.y\n    --> Vector2d.fromComponents ( 0, 5 )\n\n","type":"Basics.Float -> Geometry.Types.Direction2d -> Vector2d.Vector2d"},{"name":"xComponent","comment":" Get the X component of a vector.\n\n    Vector2d.xComponent (Vector2d.fromComponents ( 2, 3 ))\n    --> 2\n\n","type":"Vector2d.Vector2d -> Basics.Float"},{"name":"yComponent","comment":" Get the Y component of a vector.\n\n    Vector2d.yComponent (Vector2d.fromComponents ( 2, 3 ))\n    --> 3\n\n","type":"Vector2d.Vector2d -> Basics.Float"},{"name":"zero","comment":" The zero vector.\n\n    Vector2d.zero\n    --> Vector2d.fromComponents ( 0, 0 )\n\n","type":"Vector2d.Vector2d"}],"binops":[]},{"name":"Vector3d","comment":" A `Vector3d` represents a quantity such as a displacement or velocity in 3D,\nand is defined by its X, Y and Z components. This module contains a variety of\nvector-related functionality, such as\n\n  - Adding or subtracting vectors\n  - Finding the lengths of vectors\n  - Rotating vectors\n  - Converting vectors between different coordinate systems\n\nNote that unlike in many other geometry packages where vectors are used as a\ngeneral-purpose data type, `elm-geometry` has separate data types for vectors,\ndirections and points. In most code it is actually more common to use `Point3d`\nand `Direction3d` than `Vector3d`, and much code can avoid working directly with\n`Vector3d` values at all!\n\n@docs Vector3d\n\n\n# Predefined vectors\n\n@docs zero\n\nAlthough there are no predefined constants for the vectors with components\n(1,&nbsp;0,&nbsp;0), (0,&nbsp;1,&nbsp;0) and (0,&nbsp;0,&nbsp;1), in most cases\nyou will actually want their `Direction3d` versions [`Direction3d.x`](Direction3d#x),\n[`Direction3d.y`](Direction3d#y) and [`Direction3d.z`](Direction3d#z).\n\n\n# Constructors\n\n@docs fromComponents, from, withLength, on, perpendicularTo, interpolateFrom\n\n\n# Components\n\n@docs components, xComponent, yComponent, zComponent, length, squaredLength, direction, lengthAndDirection\n\n\n# Comparison\n\n@docs equalWithin\n\n\n# Measurement\n\n@docs componentIn\n\n\n# Arithmetic\n\n@docs sum, difference, dotProduct, crossProduct\n\n\n# Transformations\n\nNote that for all transformations, only the orientation of the given axis or\nplane is relevant, since vectors are position-independent. Think of transforming\na vector as placing its tail on the relevant axis or plane and then transforming\nits tip.\n\n@docs reverse, normalize, scaleBy, rotateAround, mirrorAcross, projectionIn, projectOnto\n\n\n# Coordinate conversions\n\nLike other transformations, coordinate transformations of vectors depend only on\nthe orientations of the relevant frames/sketch planes, not their positions.\n\nFor the examples, assume the following definition of a local coordinate frame,\none that is rotated 30 degrees counterclockwise around the Z axis from the\nglobal XYZ frame:\n\n    rotatedFrame =\n        Frame3d.atOrigin |> Frame3d.rotateAround Axis3d.z (degrees 30)\n\n@docs relativeTo, placeIn, projectInto\n\n","unions":[],"aliases":[{"name":"Vector3d","comment":" ","args":[],"type":"Geometry.Types.Vector3d"}],"values":[{"name":"componentIn","comment":" Find the component of a vector in an arbitrary direction, for example\n\n    verticalSpeed =\n        Vector3d.componentIn upDirection velocity\n\nThis is more general and flexible than using `xComponent`, `yComponent` or\n`zComponent`, all of which can be expressed in terms of `componentIn`; for\nexample,\n\n    Vector3d.zComponent vector\n\nis equivalent to\n\n    Vector3d.componentIn Direction3d.z vector\n\n","type":"Geometry.Types.Direction3d -> Vector3d.Vector3d -> Basics.Float"},{"name":"components","comment":" Extract the components of a vector.\n\n    Vector3d.fromComponents ( 2, 3, 4 )\n        |> Vector3d.components\n    --> ( 2, 3, 4 )\n\nThis combined with Elm's built-in tuple destructuring provides a convenient way\nto extract the X, Y and Z components of a vector in one line of code:\n\n    ( x, y, z ) =\n        Vector3d.components vector\n\n","type":"Vector3d.Vector3d -> ( Basics.Float, Basics.Float, Basics.Float )"},{"name":"crossProduct","comment":" Find the cross product of two vectors.\n\n    firstVector =\n        Vector3d.fromComponents ( 2, 0, 0 )\n\n    secondVector =\n        Vector3d.fromComponents ( 0, 3, 0 )\n\n    Vector3d.crossProduct firstVector secondVector\n    --> Vector3d.fromComponents ( 0, 0, 6 )\n\n","type":"Vector3d.Vector3d -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"difference","comment":" Find the difference between two vectors (the first vector minus the second).\n\n    firstVector =\n        Vector3d.fromComponents ( 5, 6, 7 )\n\n    secondVector =\n        Vector3d.fromComponents ( 1, 1, 1 )\n\n    Vector3d.difference firstVector secondVector\n    --> Vector3d.fromComponents ( 4, 5, 6 )\n\n","type":"Vector3d.Vector3d -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"direction","comment":" Attempt to find the direction of a vector. In the case of a zero vector,\nreturns `Nothing`.\n\n    Vector3d.fromComponents ( 3, 0, 3 )\n        |> Vector3d.direction\n    --> Just\n    -->     (Direction3d.fromAzimuthAndElevation\n    -->         (degrees 0)\n    -->         (degrees 45)\n    -->     )\n\n    Vector3d.direction Vector3d.zero\n    --> Nothing\n\n","type":"Vector3d.Vector3d -> Maybe.Maybe Geometry.Types.Direction3d"},{"name":"dotProduct","comment":" Find the dot product of two vectors.\n\n    firstVector =\n        Vector3d.fromComponents ( 1, 0, 2 )\n\n    secondVector =\n        Vector3d.fromComponents ( 3, 4, 5 )\n\n    Vector3d.dotProduct firstVector secondVector\n    --> 13\n\n","type":"Vector3d.Vector3d -> Vector3d.Vector3d -> Basics.Float"},{"name":"equalWithin","comment":" Compare two vectors within a tolerance. Returns true if the difference\nbetween the two given vectors has magnitude less than the given tolerance.\n\n    firstVector =\n        Vector3d.fromComponents ( 2, 1, 3 )\n\n    secondVector =\n        Vector3d.fromComponents ( 2.0002, 0.9999, 3.0001 )\n\n    Vector3d.equalWithin 1e-3 firstVector secondVector\n    --> True\n\n    Vector3d.equalWithin 1e-6 firstVector secondVector\n    --> False\n\n","type":"Basics.Float -> Vector3d.Vector3d -> Vector3d.Vector3d -> Basics.Bool"},{"name":"from","comment":" Construct a vector from the first given point to the second.\n\n    startPoint =\n        Point3d.fromCoordinates ( 1, 1, 1 )\n\n    endPoint =\n        Point3d.fromCoordinates ( 4, 5, 6 )\n\n    Vector3d.from startPoint endPoint\n    --> Vector3d.fromComponents ( 3, 4, 5 )\n\n","type":"Geometry.Types.Point3d -> Geometry.Types.Point3d -> Vector3d.Vector3d"},{"name":"fromComponents","comment":" Construct a vector from its X, Y and Z components.\n\n    vector =\n        Vector3d.fromComponents ( 2, 1, 3 )\n\n","type":"( Basics.Float, Basics.Float, Basics.Float ) -> Vector3d.Vector3d"},{"name":"interpolateFrom","comment":" Construct a vector by interpolating from the first given vector to the\nsecond, based on a parameter that ranges from zero to one.\n\n    startVector =\n        Vector3d.fromComponents ( 1, 2, 4 )\n\n    endVector =\n        Vector3d.fromComponents ( 1, 3, 8 )\n\n    Vector3d.interpolateFrom startVector endVector 0.25\n    --> Vector3d.fromComponents ( 1, 2.25, 5 )\n\nPartial application may be useful:\n\n    interpolatedVector : Float -> Vector3d\n    interpolatedVector =\n        Vector3d.interpolateFrom startVector endVector\n\n    List.map interpolatedVector [ 0, 0.5, 1 ]\n    --> [ Vector3d.fromComponents ( 1, 2, 4 )\n    --> , Vector3d.fromComponents ( 1, 2, 6 )\n    --> , Vector3d.fromComponents ( 1, 2, 8 )\n    --> ]\n\nYou can pass values less than zero or greater than one to extrapolate:\n\n    interpolatedVector -0.5\n    --> Vector3d.fromComponents ( 1, 2, 2 )\n\n    interpolatedVector 1.25\n    --> Vector3d.fromComponents ( 1, 2, 9 )\n\n","type":"Vector3d.Vector3d -> Vector3d.Vector3d -> Basics.Float -> Vector3d.Vector3d"},{"name":"length","comment":" Get the length (magnitude) of a vector.\n\n    Vector3d.length (Vector3d.fromComponents ( 2, 1, 2 ))\n    --> 3\n\n","type":"Vector3d.Vector3d -> Basics.Float"},{"name":"lengthAndDirection","comment":" Attempt to find the length and direction of a vector. In the case of a zero\nvector, returns `Nothing`.\n\n    vector =\n        Vector3d.fromComponents ( 3, 0, 3 )\n\n    Vector3d.lengthAndDirection vector\n    --> Just\n    -->     ( 4.2426\n    -->     , Direction3d.fromAzimuthAndElevation\n    -->         (degrees 0)\n    -->         (degrees 45)\n    -->     )\n\n    Vector3d.lengthAndDirection Vector3d.zero\n    --> Nothing\n\n","type":"Vector3d.Vector3d -> Maybe.Maybe ( Basics.Float, Geometry.Types.Direction3d )"},{"name":"mirrorAcross","comment":" Mirror a vector across a plane.\n\n    vector =\n        Vector3d.fromComponents ( 1, 2, 3 )\n\n    Vector3d.mirrorAcross Plane3d.xy vector\n    --> Vector3d.fromComponents ( 1, 2, -3 )\n\n    Vector3d.mirrorAcross Plane3d.yz vector\n    --> Vector3d.fromComponents ( -1, 2, 3 )\n\n","type":"Geometry.Types.Plane3d -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"normalize","comment":" Normalize a vector to have a length of one. Zero vectors are left as-is.\n\n    vector =\n        Vector3d.fromComponents ( 3, 0, 4 )\n\n    Vector3d.normalize vector\n    --> Vector3d.fromComponents ( 0.6, 0, 0.8 )\n\n    Vector3d.normalize Vector3d.zero\n    --> Vector3d.zero\n\n**Warning**: `Vector3d.direction` is safer since it forces you to explicitly\nconsider the case where the given vector is zero. `Vector3d.normalize` is\nprimarily useful for cases like generating WebGL meshes, where defaulting to a\nzero vector for degenerate cases is acceptable, and the overhead of something\nlike\n\n    Vector3d.direction vector\n        |> Maybe.map Direction3d.toVector\n        |> Maybe.withDefault Vector3d.zero\n\n(which is functionally equivalent to `Vector3d.normalize vector`) is too high.\n\n","type":"Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"on","comment":" Construct a 3D vector lying _on_ a sketch plane by providing a 2D vector\nspecified in XY coordinates _within_ the sketch plane.\n\n    vector2d =\n        Vector2d.fromComponents ( 2, 3 )\n\n    Vector3d.on SketchPlane3d.xy vector2d\n    --> Vector3d.fromComponents ( 2, 3, 0 )\n\n    Vector3d.on SketchPlane3d.yz vector2d\n    --> Vector3d.fromComponents ( 0, 2, 3 )\n\n    Vector3d.on SketchPlane3d.zx vector2d\n    --> Vector3d.fromComponents ( 3, 0, 2 )\n\nA slightly more complex example:\n\n    tiltedSketchPlane =\n        SketchPlane3d.xy\n            |> SketchPlane3d.rotateAround Axis3d.x\n                (degrees 45)\n\n    Vector3d.on tiltedSketchPlane <|\n        Vector2d.fromComponents ( 1, 1 )\n    --> Vector3d.fromComponents ( 1, 0.7071, 0.7071 )\n\n","type":"Geometry.Types.SketchPlane3d -> Vector2d.Vector2d -> Vector3d.Vector3d"},{"name":"perpendicularTo","comment":" Construct an arbitrary vector perpendicular to the given vector. The exact\nlength and direction of the resulting vector are not specified, but it is\nguaranteed to be perpendicular to the given vector and non-zero (unless the\ngiven vector is itself zero).\n\n    Vector3d.perpendicularTo\n        (Vector3d.fromComponents ( 3, 0, 0 ))\n    --> Vector3d.fromComponents ( 0, 0, -3 )\n\n    Vector3d.perpendicularTo\n        (Vector3d.fromComponents ( 1, 2, 3 ))\n    --> Vector3d.fromComponents ( 0, -3, 2 )\n\n    Vector3d.perpendicularTo Vector3d.zero\n    --> Vector3d.zero\n\n","type":"Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"placeIn","comment":" Take a vector defined in local coordinates relative to a given reference\nframe, and return that vector expressed in global coordinates.\n\n    vector =\n        Vector3d.fromComponents ( 2, 0, 3 )\n\n    Vector3d.placeIn rotatedFrame vector\n    --> Vector3d.fromComponents ( 1.732, 1, 3 )\n\n","type":"Geometry.Types.Frame3d -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"projectInto","comment":" Project a vector into a given sketch plane. Conceptually, this finds the\n[orthographic projection](https://en.wikipedia.org/wiki/Orthographic_projection)\nof the vector onto the plane and then expresses the projected vector in 2D\nsketch coordinates.\n\n    vector =\n        Vector3d.fromComponents ( 2, 1, 3 )\n\n    Vector3d.projectInto SketchPlane3d.xy vector\n    --> Vector2d.fromComponents ( 2, 1 )\n\n    Vector3d.projectInto SketchPlane3d.yz vector\n    --> Vector2d.fromComponents ( 1, 3 )\n\n    Vector3d.projectInto SketchPlane3d.zx vector\n    --> Vector2d.fromComponents ( 3, 2 )\n\n","type":"Geometry.Types.SketchPlane3d -> Vector3d.Vector3d -> Vector2d.Vector2d"},{"name":"projectOnto","comment":" Project a vector [orthographically](https://en.wikipedia.org/wiki/Orthographic_projection)\nonto a plane. Conceptually, this means splitting the original vector into a\nportion parallel to the plane (perpendicular to the plane's normal direction)\nand a portion perpendicular to it (parallel to its normal direction), then\nreturning the parallel (in-plane) portion.\n\n    vector =\n        Vector3d.fromComponents ( 2, 1, 3 )\n\n    Vector3d.projectOnto Plane3d.xy vector\n    --> Vector3d.fromComponents ( 2, 1, 0 )\n\n    Vector3d.projectOnto Plane3d.xz vector\n    --> Vector3d.fromComponents ( 2, 0, 3 )\n\n","type":"Geometry.Types.Plane3d -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"projectionIn","comment":" Find the projection of a vector in a particular direction. Conceptually,\nthis means splitting the original vector into a portion parallel to the given\ndirection and a portion perpendicular to it, then returning the parallel\nportion.\n\n    vector =\n        Vector3d.fromComponents ( 1, 2, 3 )\n\n    Vector3d.projectionIn Direction3d.x vector\n    --> Vector3d.fromComponents ( 1, 0, 0 )\n\n    Vector3d.projectionIn Direction3d.z vector\n    --> Vector3d.fromComponents ( 0, 0, 3 )\n\n","type":"Geometry.Types.Direction3d -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"relativeTo","comment":" Take a vector defined in global coordinates, and return it expressed in\nlocal coordinates relative to a given reference frame.\n\n    vector =\n        Vector3d.fromComponents ( 2, 0, 3 )\n\n    Vector3d.relativeTo rotatedFrame vector\n    --> Vector3d.fromComponents ( 1.732, -1, 3 )\n\n","type":"Geometry.Types.Frame3d -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"reverse","comment":" Reverse the direction of a vector, negating its components.\n\n    Vector3d.reverse (Vector3d.fromComponents ( 1, -3, 2 ))\n    --> Vector3d.fromComponents ( -1, 3, -2 )\n\n(This could have been called `negate`, but `reverse` is more consistent with\nthe naming used in other modules.)\n\n","type":"Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"rotateAround","comment":" Rotate a vector around a given axis by a given angle (in radians).\n\n    vector =\n        Vector3d.fromComponents ( 2, 0, 1 )\n\n    Vector3d.rotateAround Axis3d.x (degrees 90) vector\n    --> Vector3d.fromComponents ( 2, -1, 0 )\n\n    Vector3d.rotateAround Axis3d.z (degrees 45) vector\n    --> Vector3d.fromComponents ( 1.4142, 1.4142, 1 )\n\n","type":"Geometry.Types.Axis3d -> Basics.Float -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"scaleBy","comment":" Scale the length of a vector by a given scale.\n\n    Vector3d.fromComponents ( 1, 2, 3 )\n        |> Vector3d.scaleBy 3\n    --> Vector3d.fromComponents ( 3, 6, 9 )\n\n(This could have been called `multiply` or `times`, but `scaleBy` was chosen as\na more geometrically meaningful name and to be consistent with the `scaleAbout`\nname used in other modules.)\n\n","type":"Basics.Float -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"squaredLength","comment":" Get the squared length of a vector. `squaredLength` is slightly faster than\n`length`, so for example\n\n    Vector3d.squaredLength vector > tolerance * tolerance\n\nis equivalent to but slightly more efficient than\n\n    Vector3d.length vector > tolerance\n\nsince the latter requires a square root under the hood. In many cases, however,\nthe speed difference will be negligible and using `length` is much more\nreadable!\n\n","type":"Vector3d.Vector3d -> Basics.Float"},{"name":"sum","comment":" Find the sum of two vectors.\n\n    firstVector =\n        Vector3d.fromComponents ( 1, 2, 3 )\n\n    secondVector =\n        Vector3d.fromComponents ( 4, 5, 6 )\n\n    Vector3d.sum firstVector secondVector\n    --> Vector3d.fromComponents ( 5, 7, 9 )\n\n","type":"Vector3d.Vector3d -> Vector3d.Vector3d -> Vector3d.Vector3d"},{"name":"withLength","comment":" Construct a vector with the given length in the given direction.\n\n    Vector3d.withLength 5 Direction3d.y\n    --> Vector3d.fromComponents ( 0, 5, 0 )\n\n","type":"Basics.Float -> Geometry.Types.Direction3d -> Vector3d.Vector3d"},{"name":"xComponent","comment":" Get the X component of a vector.\n\n    Vector3d.fromComponents ( 1, 2, 3 )\n        |> Vector3d.xComponent\n    --> 1\n\n","type":"Vector3d.Vector3d -> Basics.Float"},{"name":"yComponent","comment":" Get the Y component of a vector.\n\n    Vector3d.fromComponents ( 1, 2, 3 )\n        |> Vector3d.yComponent\n    --> 2\n\n","type":"Vector3d.Vector3d -> Basics.Float"},{"name":"zComponent","comment":" Get the Z component of a vector.\n\n    Vector3d.fromComponents ( 1, 2, 3 )\n        |> Vector3d.zComponent\n    --> 3\n\n","type":"Vector3d.Vector3d -> Basics.Float"},{"name":"zero","comment":" The zero vector.\n\n    Vector3d.zero\n    --> Vector3d.fromComponents ( 0, 0, 0 )\n\n","type":"Vector3d.Vector3d"}],"binops":[]},{"name":"VoronoiDiagram2d","comment":" For any given set of distinct (non-equal) points in 2D, there is a finite\nregion around each point such that anywhere in the region is closer to that\npoint than to any other point. These are the called the Voronoi regions of each\npoint, and the collection of the Voronoi regions for a set of points is called\nthe [Voronoi diagram](https://en.wikipedia.org/wiki/Voronoi_diagram) of those\npoints.\n\nAlthough some Voronoi regions will be infinite in size, if they are all clipped\nto a particular bounding box then they will all be finite, convex polygons. This\nmodule therefore provides functionality for:\n\n  - Building Voronoi diagrams from sets of points or arbitrary vertices (so\n    you can associate colors, IDs or other data with points)\n  - Adding new points/vertices to an existing Voronoi diagram\n  - Clipping a Voronoi diagram to a particular bounding box to get a list of\n    polygons with their associated points/vertices\n\nThe returned polygons can then be used in various interesting ways:\n\n  - Use to do interesting geographical analyses (for example, what are the areas\n    covered by different fire stations?)\n  - Use as an invisible hover target in SVG to highlight corresponding points:\n    highlighting a given point when the mouse is over its Voronoi polygon is one\n    way to highlight the point nearest the mouse\n\nThe current implementation is somewhat inefficient, but there are plans to speed\nit up in the future (without requiring any changes to the API).\n\n@docs VoronoiDiagram2d, Error\n\n\n# Construction\n\nConstructing a Voronoi diagram from points/vertices is currently an O(n^2)\noperation but should be O(n log n) in the future.\n\n@docs empty\n\n@docs fromPoints, fromVerticesBy\n\n\n# Modification\n\nInserting a point into a Voronoi diagram is currently an O(n) operation but\nshould be O(log n) in the future.\n\n@docs insertPoint, insertVertexBy\n\n\n# Properties\n\n@docs vertices, polygons\n\n\n# Conversion\n\nA Voronoi diagram of a set or vertices is [the dual](https://en.wikipedia.org/wiki/Delaunay_triangulation#Relationship_with_the_Voronoi_diagram)\nof the Delaunay triangulation of those vertices. As a result, it is possible to\nconvert back and forth between the two.\n\n@docs fromDelaunayTriangulation, toDelaunayTriangulation\n\n","unions":[{"name":"Error","comment":" An error type indicating that the two given vertices have the same position.\n","args":["vertex"],"cases":[["CoincidentVertices",["vertex","vertex"]]]},{"name":"VoronoiDiagram2d","comment":" A 2D Voronoi diagram of a set of vertices.\n","args":["vertex"],"cases":[]}],"aliases":[],"values":[{"name":"empty","comment":" An empty Voronoi diagram with no vertices or faces.\n","type":"VoronoiDiagram2d.VoronoiDiagram2d vertex"},{"name":"fromDelaunayTriangulation","comment":" Construct a Voronoi diagram from a Delaunay triangulation. Complexity should\nbe O(n) in the vast majority of cases but may be O(n log n) in pathological\ncases.\n","type":"DelaunayTriangulation2d.DelaunayTriangulation2d vertex -> VoronoiDiagram2d.VoronoiDiagram2d vertex"},{"name":"fromPoints","comment":" Construct a Voronoi diagram from an array of points. The points must all be\ndistinct; if any two points are equal, you will get an `Err CoincidentVertices`.\n","type":"Array.Array Point2d.Point2d -> Result.Result (VoronoiDiagram2d.Error Point2d.Point2d) (VoronoiDiagram2d.VoronoiDiagram2d Point2d.Point2d)"},{"name":"fromVerticesBy","comment":" Construct a Voronoi diagram from an array of vertices of arbitrary type, by\nsupplying a function that returns the position of each vertex as a `Point2d`.\nFor example, if you had\n\n    types alias Vertex =\n        { position = Point2d\n        , color = String\n        }\n\nand\n\n    vertices : Array Vertex\n    vertices =\n        ...\n\nthen you would use\n\n    VoronoiDiagram2d.fromVerticesBy .position vertices\n\nThe vertices must all be distinct; if any two have the same position, you will\nget an `Err CoincidentVertices`.\n\n","type":"(vertex -> Point2d.Point2d) -> Array.Array vertex -> Result.Result (VoronoiDiagram2d.Error vertex) (VoronoiDiagram2d.VoronoiDiagram2d vertex)"},{"name":"insertPoint","comment":" Add a new point into an existing Voronoi diagram. It must not be equal to\nany existing point; if it is, you will get an `Err CoincidentVertices`.\n","type":"Point2d.Point2d -> VoronoiDiagram2d.VoronoiDiagram2d Point2d.Point2d -> Result.Result (VoronoiDiagram2d.Error Point2d.Point2d) (VoronoiDiagram2d.VoronoiDiagram2d Point2d.Point2d)"},{"name":"insertVertexBy","comment":" Add a new vertex into an existing Voronoi diagram, by supplying a function\nto get the position of the vertex. The vertex must not have the same position as\nany existing vertex; if it is, you will get an `Err CoincidentVertices`.\n","type":"(vertex -> Point2d.Point2d) -> vertex -> VoronoiDiagram2d.VoronoiDiagram2d vertex -> Result.Result (VoronoiDiagram2d.Error vertex) (VoronoiDiagram2d.VoronoiDiagram2d vertex)"},{"name":"polygons","comment":" Convert a Voronoi diagram to a list of polygons, by clipping each (possibly\ninfinite/unbounded) Voronoi region to the given bounding box. Each item in the\nreturned list will be an input vertex with its corresponding (clipped) Voronoi\nregion.\n\nIf the bounding box contains all vertices, then there will be an entry in the\nlist for every vertex. However, if some vertices fall outside the given\nbounding box, then it is possible that their Voronoi region is also entirely\noutside the bounding box, in which case they will have no entry in the\nreturned list.\n\nComplexity should be O(n) in the vast majority of cases but may be O(n log n)\nin pathological cases (such as 1000 points on a circle surrounding a single\ncenter point, in which case the Voronoi region for the center point will be\na polygon with 1000 edges).\n\n","type":"BoundingBox2d.BoundingBox2d -> VoronoiDiagram2d.VoronoiDiagram2d vertex -> List.List ( vertex, Polygon2d.Polygon2d )"},{"name":"toDelaunayTriangulation","comment":" Convert a Voronoi diagram to a Delaunay triangulation. This is a simple\naccessor, so complexity is O(1).\n","type":"VoronoiDiagram2d.VoronoiDiagram2d vertex -> DelaunayTriangulation2d.DelaunayTriangulation2d vertex"},{"name":"vertices","comment":" Get the vertices of a Voronoi diagram. If the diagram was constructed by\ncalling `fromPoints` or `fromVerticesBy`, then the returned vertex array will\nsimply be the array that was passed in. If any vertices were added using\n`insertPoint` or `insertVertexBy`, then they will be appended to the end of the\narray. This is a simple accessor, so complexity is O(1).\n","type":"VoronoiDiagram2d.VoronoiDiagram2d vertex -> Array.Array vertex"}],"binops":[]}]