Bot releases are visible (Hide)
Despite the major version bump, this is really just a clean-up release with three main changes.
Direction3d
instead of an Axis3d
Previously, Vector3d.rotateAround
and Direction3d.rotateAround
took an Axis3d
as an argument even though the origin point of the axis wasn't used, only the axis direction. This was to be consistent with all other 3D rotateAround
functions, but can be confusing and in some cases could force you to create an axis with a dummy origin point, which seems messy. These two functions now accept a Direction3d
instead, so you may need to change some code from (e.g.)
Direction3d.rotateAround someAxis someDirection
to
Direction3d.rotateAround (Axis3d.direction someAxis) someDirection
Thanks @MartinSStewart for bringing this up!
ArcLengthParameterization
to ArcLength
I originally used the longer name for this module since it's the only module in elm-geometry
that doesn't have a 2d
or 3d
suffix, and I wanted to add something to make the name less likely to conflict with modules in other packages. However, several years later the Elm package repository still doesn't have any other packages that mention arc length, so it looks like the simpler name is probably OK.
No functionality has been changed, but all the names have:
3.x | 4.0 |
---|---|
ArcLengthParameterization.ArcLengthParameterization |
ArcLength.Parameterization |
ArcLengthParameterization.build |
ArcLength.parameterization |
ArcLengthParameterization.totalArcLength |
ArcLength.total |
ArcLengthParameterization.arcLengthToParameterValue |
ArcLength.toParameterValue |
ArcLengthParameterization.parameterValueToArcLength |
ArcLength.fromParameterValue |
I personally now like using the Parameterization
type qualified; instead of
import ArcLengthParameterization exposing (ArcLengthParameterization)
import Length exposing (Meters)
type alias Model =
{ parameterization : ArcLengthParameterization Meters
, -- other stuff
}
I now tend to write
import ArcLength
import Length exposing (Meters)
type alias Model =
{ parameterization : ArcLength.Parameterization Meters
, -- other stuff
}
This one is subtle and shouldn't actually be a breaking change for any code, since the only change is making some type signatures more permissive (all existing code should still type-check just fine, and the behaviour is unchanged). The short version is that a few vector-related functions were requiring units types to match when they didn't actually need to, and those type signatures have now been relaxed to be more permissive (and more correct!).
For example, in elm-geometry
3.x, the Vector3d.mirrorAcross
function had the following signature:
Plane3d units coordinates -> Vector3d units coordinates -> Vector3d units coordinates
The units
type parameter here will most commonly be Meters
, meaning that:
Length
(a.k.a. Quantity Float Meters
) values; that is, the coordinates are measured in meters, centimeters, feet, inches etc.Length
values; that is, the vector is a displacement (a vector between two points).However, it's not actually necessary for those two units types to match! Since mirroring a vector across a plane doesn't involve the plane's origin point (just the plane's normal direction, which is unitless) it's not actually necessary that the units of the vector match the units of the plane's origin point. For example, it's totally valid (and sometimes useful) to mirror a velocity vector (with units of MetersPerSecond
) across a plane with units of Meters
. As a result, Vector3d.mirrorAcross
now has the signature
Plane3d planeUnits coordinates -> Vector3d units coordinates -> Vector3d units coordinates
That is, the plane and vector are still enforced to be defined in the same coordinate system, and the units of the mirrored vector are enforced to be the same as the original vector, but the units of the plane and vector are allowed be different.
Of course, the units don't have to be different, so any existing code that (for example) mirrors a Vector3d Meters WorldCoordinates
across a Plane3d Meters WorldCoordinates
will still compile and run exactly the same as before. The Elm compiler considers this change a breaking one, but all it actually does is allow certain kinds of code that weren't allowed previously.
It's not just transformation functions like mirrorAcross
that have been updated - several vector construction functions have had similar changes. For example, it is now possible to do things like construct a velocity vector with units of MetersPerSecond
by providing its components within a sketch plane with units of Meters
:
-- elm-geometry 3.x
Vector3d.xyOn :
SketchPlane3d units coordinates3d { defines : coordinates2d }
-> Quantity Float units
-> Quantity Float units
-> Vector3d units coordinates3d
-- elm-geometry 4.0
Vector3d.xyOn :
SketchPlane3d sketchPlaneUnits coordinates3d { defines : coordinates2d }
-> Quantity Float units
-> Quantity Float units
-> Vector3d units coordinates3d
(Note how the vector units are now allowed to be different from the sketch plane units.)
Full list of functions with updated signatures:
Vector2d
xyIn
rThetaIn
relativeTo
placeIn
projectOnto
(Note that Vector2d.mirrorAcross
was the one function that actually had the correct type signature already, so didn't need to be updated.)
Vector3d
xyzIn
on
xyOn
rThetaOn
relativeTo
placeIn
rotateAround
mirrorAcross
projectOnto
projectInto
Published by ianmackenzie about 1 year ago
This release adds Spline2d
and Spline3d
modules, which are generalizations of the existing QuadraticSpline2d
/CubicSpline2d
and QuadraticSpline3d
/CubicSpline3d
modules.
In general you should prefer to use the existing modules (they're much more efficient), but the new ones are useful if you need support for fancy higher-degree splines (quartic, quintic etc.) or if you're doing something like making a graphics editor where users can choose how many points to use to define a spline curve (two for a straight line, three for a quadratic spline, four for a cubic spline, etc.).
Published by ianmackenzie over 1 year ago
This (long-delayed!) release adds several small new functions:
Polygon2d.regular
for constructing regular polygons (triangles, squares, pentagons, hexagons etc.) (thanks @gampleman in #148)Axis2d.intersectionPoint
for finding the intersection point between two 2D axesAxis3d.intersectionWithTriangle
, and Axis3d.intersectionWithRectangle
(thanks @w0rm in #146)BoundingBox2d.interpolate
and BoundingBox3d.interpolate
for interpolating within bounding boxesLineSegment2d.axis
and LineSegment3d.axis
for getting the axis that a given line segment lies onVector2d
and Vector3d
by Float
or Quantity Float Unitless
values (functionally the same thing, but different in the eyes of the type system): multiplyBy
, divideBy
, timesUnitless
and overUnitless
for both Vector2d
and Vector3d
RationalQuadraticSpline3d.approximate
and RationalCubicSpline3d.approximate
for generating polyline approximations to rational splines in 3D (useful for 3D rendering)Adding the rational spline approximate
functions (the last bullet point above) also required adding a bunch of lower-level functionality that is less likely to be useful outside of elm-geometry
internals:
VectorBoundingBox2d
and VectorBoundingBox3d
types/modules, equivalent to BoundingBox2d
and BoundingBox3d
but for bounds on vectors instead of pointsPublished by ianmackenzie about 3 years ago
This release fixes a typo in the implementation of Vector3d.perpendicularTo
which would cause it would give an incorrect (non-perpendicular) result in some cases. Please update!
Published by ianmackenzie almost 4 years ago
This release extends the work on spline functionality from the last release and adds support for rational quadratic and cubic splines in the RationalQuadraticSpline2d
, RationalQuadraticSpline3d
, RationalCubicSpline2d
and RationalCubicSpline3d
modules. This means it is now possible to create quadratic or cubic NURBS curves in 2D or 3D using elm-geometry
! For example, to create a NURBS curve representing a perfect circle (consisting of four rational quadratic spline segments), you could write
splineSegments =
RationalQuadraticSpline2d.bSplineSegments
[ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4 ]
[ ( Point2d.pixels 300 0, 1 )
, ( Point2d.pixels 300 300, 1 / sqrt 2 )
, ( Point2d.pixels 0 300, 1 )
, ( Point2d.pixels -300 300, 1 / sqrt 2 )
, ( Point2d.pixels -300 0, 1 )
, ( Point2d.pixels -300 -300, 1 / sqrt 2 )
, ( Point2d.pixels 0 -300, 1 )
, ( Point2d.pixels 300 -300, 1 / sqrt 2 )
, ( Point2d.pixels 300 0, 1 )
]
See Wikipedia for some explanation, but note that:
elm-geometry
uses a different knot convention that avoids the 'dummy' first and last knots, so note that the first and last knots are only repeated twice here instead of three times.This release also adds an Ellipsoid3d
type and module for representing ellipsoids. Thanks to @g-belmonte for contributing this in #135! (Eventually elm-3d-scene
will get support for rendering ellipsoids.)
Published by ianmackenzie almost 4 years ago
This is a small release that primarily brings some basic B-spline functionality to the QuadraticSpline2d
, QuadraticSpline3d
, CubicSpline2d
and CubicSpline3d
modules, for example:
-- Construct a B-spline and get its individual cubic spline segments
CubicSpline2d.bSplineSegments :
List Float -- knot values
-> List (Point2d units coordinates) -- control points
-> List (CubicSpline2d units coordinates) -- resulting curve segments
-- Find the knot intervals corresponding to those curve segments
CubicSpline2d.bSplineIntervals : List Float -> List (Interval Float)
In addition, Circle3d
now has a toArc
function for converting a 360 degree arc (with unspecified start/end point).
Published by ianmackenzie almost 4 years ago
This release is the result of a steady accumulation of contributions over the last several months - not a very cohesive story to tell here, but lots of useful new features!
This release adds new Ellipse3d
and EllipticalArc3d
modules, which are fairly straightforward 3D versions of Ellipse2d
and EllipticalArc2d
having many of the same operations.
A few modules now have basic functions for generating random values in 2D and 3D. You can generate random points within bounding boxes and rectangles:
BoundingBox2d.randomPoint : BoundingBox2d units coordinates -> Generator (Point2d units coordinates)
BoundingBox3d.randomPoint : BoundingBox3d units coordinates -> Generator (Point3d units coordinates)
Rectangle2d.randomPoint : Rectangle2d units coordinates -> Generator (Point2d units coordinates)
Rectangle3d.randomPoint : Rectangle3d units coordinates -> Generator (Point3d units coordinates)
You can also generate random 2D and 3D directions:
Direction2d.random : Generator (Direction2d coordinates)
Direction3d.random : Generator (Direction3d coordinates)
Future releases will likely add more random generators such as 'point within circle' , 'point within triangle' etc.
This release brings some more flexibility in how to approximate curves (arcs, splines) etc. by things like polylines. The Arc2d
, Arc3d
, QuadraticSpline2d
, QuadraticSpline3d
, CubicSpline2d
, CubicSpline3d
and EllipticalArc2d
modules now all have new approximate
, segments
and numApproximationSegments
functions, for example:
Arc2d.approximate : Quantity Float units -> Arc2d units coordinates -> Polyline2d units coordinates
Arc2d.segments : Int -> Arc2d units coordinates -> Polyline2d units coordinates
Arc2d.numApproximationSegments : Quantity Float units -> Arc2d units coordinates -> Int
approximate
function replaces toPolyline
, which is now deprecated since there are now multiple ways to convert a curve to a polyline. Like toPolyline
, approximate
takes a tolerance and returns a polyline that approximates the arc to within that tolerance.segments
function is a simpler version of approximate
that takes as an argument the number of segments to use.numApproximationSegments
is a lower-level function that tells you how many segments would be needed for a polyline to approximate the given arc to within the given accuracy. You can then use this to determine how many times to call functions like pointOn
or sample
.The existing Polygon2d.triangulate
turns a Polygon2d
into a triangular mesh by adding edges between existing polygon vertices. Sometimes, however, you want some extra control over the resulting triangulation - for example, you might want to ensure that all triangles are smaller than some given size. There is now a Polygon2d.triangulateWith
function and some functions for setting up some 'rules' for the triangulation:
Polygon2d.triangulateWith :
TriangulationRule units coordinates
-> Polygon2d units coordinates
-> TriangularMesh (Point2d units coordinates)
Polygon2d.maxEdgeLength : Quantity Float units -> TriangulationRule units coordinates
Polygon2d.maxTriangleDimensions : Quantity Float units -> Quantity Float units -> TriangulationRule units coordinates
Vectors now have a new scaleTo
function thanks to @g-belmonte in #137:
Vector2d.scaleTo : Quantity Float units2 -> Vector2d units1 coordinates -> Vector2d units2 coordinates
Vector3d.scaleTo : Quantity Float units2 -> Vector3d units1 coordinates -> Vector3d units2 coordinates
These functions will return a vector in the same direction as the original, but scaled to the given length (or left as zero if they are zero to begin with). Note that this is capable of changing the units of the vector if you want!
The Arc2d
, Arc3d
, Ellipse2d
and EllipticalArc2d
modules now all have boundingBox
functions. The BoundingBox2d
and BoundingBox3d
modules themselves now also have new functionality to convert between bounding boxes and X/Y/Z intervals, for example
BoundingBox2d.xy : Interval Float units -> Interval Float units -> BoundingBox2d units coordinates
BoundingBox2d.fromIntervals : ( Interval Float units, Interval Float units ) -> BoundingBox2d units coordinates
BoundingBox2d.intervals : BoundingBox2d units coordinates -> ( Interval Float units, Interval Float units )
BoundingBox2d.xInterval : BoundingBox2d units coordinates -> Interval Float units
BoundingBox2d.yInterval : BoundingBox2d units coordinates -> Interval Float units
and similar for BoundingBox3d
.
The Vector2d
and Vector3d
modules got several new functions for constructing speed, acceleration and force vectors from their X/Y/Z components. For example, the Vector2d
module now has several functions such as:
Vector2d.metersPerSecond : Float -> Float -> Vector2d MetersPerSecond coordinates
Vector2d.feetPerSecondSquared : Float -> Float -> Vector2d MetersPerSecondSquared coordinates
Vector2d.kilonewtons : Float -> Float -> Vector2d Newtons coordinates
Thanks to @g-belmonte in #139 for adding these!
Other new functions in this release:
Arc3d.projectOnto : Plane3d units coordinates -> Arc3d units coordinates -> EllipticalArc3d units coordinates
-- Reverse the orientation (axial direction) of a circle
Circle3d.flip : Circle3d units coordinates -> Circle3d units coordinates
-- Alias for Plane3d.reverseNormal, for consistency with Circle3d.flip
Plane3d.flip : Plane3d units coordinates -> Plane3d units coordinates
-- Find the minimum/maximum distances of ellipses and elliptical arcs along arbitrary axes
Ellipse2d.signedDistanceAlong : Axis2d units coordinates -> Ellipse2d units coordinates -> Interval Float units
EllipticalArc2d.signedDistanceAlong : Axis2d units coordinates -> EllipticalArc2d units coordinates -> Interval Float units
Published by ianmackenzie over 4 years ago
This release brings a few useful new functions and some performance improvements. First, there's Axis3d.intersectionWithSphere
, contributed by @SuzzzWood in #128:
Axis3d.intersectionWithSphere :
Sphere3d units coordinates
-> Axis3d units coordinates
-> Maybe ( Point3d units coordinates, Point3d units coordinates )
Second, a handful of functions for measuring intervals of distances of line segments relative to axes and planes in 2D and 3D, contributed by @w0rm in #123:
LineSegment2d.signedDistanceAlong :
Axis2d units coordinates
-> LineSegment2d units coordinates
-> Interval Float units
LineSegment2d.signedDistanceFrom :
Axis2d units coordinates
-> LineSegment2d units coordinates
-> Interval Float units
LineSegment3d.signedDistanceAlong :
Axis3d units coordinates
-> LineSegment3d units coordinates
-> Interval Float units
LineSegment3d.signedDistanceFrom :
Plane3d units coordinates
-> LineSegment3d units coordinates
-> Interval Float units
Finally, the performance of arc length parameterization has been improved (particularly for 2D/3D cubic and quadratic splines). Please open an issue or reach out to @ianmackenzie on the Elm Slack if you are encountering any other performance issues with elm-geometry
!
Published by ianmackenzie over 4 years ago
This release brings a new Cone3d
module for representing/manipulating 3D cones, contributed by @w0rm in #131. (See also Andrey's corresponding PR to add support for rendering cones in elm-3d-scene
!)
Published by ianmackenzie over 4 years ago
This is a fairly small release that brings a few new bounding box related functions, all suggested by @MartinSStewart in #129 and #130:
BoundingBox2d.withDimensions :
( Quantity Float units, Quantity Float units )
-> Point2d units coordinates
-> BoundingBox2d units coordinates
BoundingBox3d.withDimensions :
( Quantity Float units, Quantity Float units, Quantity Float units )
-> Point3d units coordinates
-> BoundingBox3d units coordinates
Rectangle2d.fromBoundingBox :
BoundingBox2d units coordinates
-> Rectangle2d units coordinates
Block3d.fromBoundingBox :
BoundingBox3d units coordinates
-> Block3d units coordinates
Published by ianmackenzie over 4 years ago
This release of elm-geometry
adds a new Rectangle3d
module and type. That's it, that's the release =)
Published by ianmackenzie over 4 years ago
elm-geometry
3.2 is out! This release brings a handful of small but useful new features requested (and in many cases contributed) by the community:
Arc2d.midpoint
, Arc3d.midpoint
and EllipticalArc2d.midpoint
for getting midpoints of circular and elliptical arcs (see #115, thanks @w0rm!)Polygon2d.centroid
for getting the centroid (center of mass) of a polygon (see #117, thanks @w0rm!)Axis2d.throughPoints
and Axis3d.throughPoints
for constructing axes that pass through two given points (thanks @MartinSStewart for the request)elm-geometry
(thanks @MartinSStewart for the request):
Point2d.coordinates
, Point2d.coordinatesIn
Point3d.coordinates
, Point3d.coordinatesIn
Vector2d.components
, Vector3d.components
Direction2d.components
, Direction3d.components
Vector2d.half
, Vector2d.twice
as convenient shortand for Vector2d.scaleBy
Vector2d.sum
to get the sum of a list of vectorsVector2d.product
and Vector2d.times
to multiply a vector by a scalar Quantity
(analogous to Quantity.times
)Vector2d.over
and Vector2d.over_
to divide a vector by a scalar Quantity
(analogous to Quantity.over
and Quantity.over_
)Vector3d
Published by ianmackenzie almost 5 years ago
This release adds a new Cylinder3d
type and corresponding module, for representing/manipulating/querying 3D cylinders.
Published by ianmackenzie almost 5 years ago
elm-geometry
3.0 is out! This release brings some small but breaking changes from the interim 2.0 release, and should hopefully now be stable for the foreseeable future.
Block3d
elm-geometry
now has a Block3d
type which is basically a 3D version of Rectangle2d
, useful for defining rectangular blocks in 3D. Unlike a BoundingBox3d
, a Block3d
does not have to be axis-aligned - it can be arbitrarily rotated, mirrored and otherwise transformed).
A few bounding box related functions have been moved around/renamed for clarity/discoverability, with the end result that they're actually a bit closer to where they used to be in elm-geometry
1.x. Specifically:
hull
functions have been renamed to aggregate
; for example BoundingBox2d.hull3
is now BoundingBox2d.aggregate3
.BoundingBox2d.hull2
and BoundingBox3d.hull2
functions have been renamed to union
(not strictly the correct term mathematically speaking, but convenient).hull
functions have been moved to the corresponding bounding box modules; for example Point3d.hull
is now BoundingBox3d.hull
(with the same signature).Point2d.hull2
and BoundingBox3d.hull2
have been moved/renamed to BoundingBox2d.from
and BoundingBox3d.from
(matching how things worked in 1.x).Basically, all functions that construct bounding boxes are now in bounding box modules. In addition, hullOfN
and aggregateOfN
functions have been added that basically act as combinations of hullOf
/hullN
and aggregateOf
/aggregateN
respectively.
See #107 for relevant discussion - thanks @MartinSStewart!
Arc.SweptAngle
has been renamed to simply SweptAngle
for simplicity (didn't seem like that was likely to cause too many module name conflicts).Axis3d.intersectionWithPlane
function to find the intersection of an axis and a plane in 3D.Circle2d
and Sphere3d
modules now have some convenient atPoint
and atOrigin
constructors.LineSegment2d
and LineSegment3d
modules now have fromPointAndVector
constructors as suggested in #110.Frame2d.atOrigin
and Frame3d.atOrigin
have been loosened slightly to match Frame2d.atPoint Point2d.origin
and Frame3d.atPoint Point3d.atOrigin
; this was a case where the initial design was a bit too strict about coordinate system tracking and prevented some perfectly valid code from compiling. Thanks @unsoundscapes for some useful feedback here!Rectangle2d.withAxes
has been renamed back to Rectangle2d.centeredOn
; I've gone back and forth on this one but I think centeredOn
is more descriptive and readable.I think all the changes in 3.0 have been discussed above, but I may have missed something! Here's what elm diff
reported for elm-geometry
3.0 relative to 2.0:
---- ADDED MODULES - MINOR ----
Block3d
SweptAngle
---- REMOVED MODULES - MAJOR ----
Arc.SweptAngle
---- Axis3d - MINOR ----
Added:
intersectionWithPlane :
Geometry.Types.Plane3d units coordinates
-> Axis3d.Axis3d units coordinates
-> Maybe.Maybe (Point3d.Point3d units coordinates)
---- BoundingBox2d - MAJOR ----
Added:
aggregate :
BoundingBox2d.BoundingBox2d units coordinates
-> List.List (BoundingBox2d.BoundingBox2d units coordinates)
-> BoundingBox2d.BoundingBox2d units coordinates
aggregate3 :
BoundingBox2d.BoundingBox2d units coordinates
-> BoundingBox2d.BoundingBox2d units coordinates
-> BoundingBox2d.BoundingBox2d units coordinates
-> BoundingBox2d.BoundingBox2d units coordinates
aggregateN :
List.List (BoundingBox2d.BoundingBox2d units coordinates)
-> Maybe.Maybe (BoundingBox2d.BoundingBox2d units coordinates)
aggregateOf :
(a -> BoundingBox2d.BoundingBox2d units coordinates)
-> a
-> List.List a
-> BoundingBox2d.BoundingBox2d units coordinates
aggregateOfN :
(a -> BoundingBox2d.BoundingBox2d units coordinates)
-> List.List a
-> Maybe.Maybe (BoundingBox2d.BoundingBox2d units coordinates)
from :
Point2d.Point2d units coordinates
-> Point2d.Point2d units coordinates
-> BoundingBox2d.BoundingBox2d units coordinates
hullOfN :
(a -> Point2d.Point2d units coordinates)
-> List.List a
-> Maybe.Maybe (BoundingBox2d.BoundingBox2d units coordinates)
union :
BoundingBox2d.BoundingBox2d units coordinates
-> BoundingBox2d.BoundingBox2d units coordinates
-> BoundingBox2d.BoundingBox2d units coordinates
Removed:
hull2 :
BoundingBox2d units coordinates
-> BoundingBox2d units coordinates
-> BoundingBox2d units coordinates
Changed:
- hull :
BoundingBox2d units coordinates
-> List (BoundingBox2d units coordinates)
-> BoundingBox2d units coordinates
+ hull :
Point2d.Point2d units coordinates
-> List.List (Point2d.Point2d units coordinates)
-> BoundingBox2d.BoundingBox2d units coordinates
- hull3 :
BoundingBox2d units coordinates
-> BoundingBox2d units coordinates
-> BoundingBox2d units coordinates
-> BoundingBox2d units coordinates
+ hull3 :
Point2d.Point2d units coordinates
-> Point2d.Point2d units coordinates
-> Point2d.Point2d units coordinates
-> BoundingBox2d.BoundingBox2d units coordinates
- hullN :
List (BoundingBox2d units coordinates)
-> Maybe (BoundingBox2d units coordinates)
+ hullN :
List.List (Point2d.Point2d units coordinates)
-> Maybe.Maybe (BoundingBox2d.BoundingBox2d units coordinates)
- hullOf :
(a -> BoundingBox2d units coordinates)
-> a
-> List a
-> BoundingBox2d units coordinates
+ hullOf :
(a -> Point2d.Point2d units coordinates)
-> a
-> List.List a
-> BoundingBox2d.BoundingBox2d units coordinates
---- BoundingBox3d - MAJOR ----
Added:
aggregate :
BoundingBox3d.BoundingBox3d units coordinates
-> List.List (BoundingBox3d.BoundingBox3d units coordinates)
-> BoundingBox3d.BoundingBox3d units coordinates
aggregate3 :
BoundingBox3d.BoundingBox3d units coordinates
-> BoundingBox3d.BoundingBox3d units coordinates
-> BoundingBox3d.BoundingBox3d units coordinates
-> BoundingBox3d.BoundingBox3d units coordinates
aggregateN :
List.List (BoundingBox3d.BoundingBox3d units coordinates)
-> Maybe.Maybe (BoundingBox3d.BoundingBox3d units coordinates)
aggregateOf :
(a -> BoundingBox3d.BoundingBox3d units coordinates)
-> a
-> List.List a
-> BoundingBox3d.BoundingBox3d units coordinates
aggregateOfN :
(a -> BoundingBox3d.BoundingBox3d units coordinates)
-> List.List a
-> Maybe.Maybe (BoundingBox3d.BoundingBox3d units coordinates)
from :
Point3d.Point3d units coordinates
-> Point3d.Point3d units coordinates
-> BoundingBox3d.BoundingBox3d units coordinates
hullOfN :
(a -> Point3d.Point3d units coordinates)
-> List.List a
-> Maybe.Maybe (BoundingBox3d.BoundingBox3d units coordinates)
union :
BoundingBox3d.BoundingBox3d units coordinates
-> BoundingBox3d.BoundingBox3d units coordinates
-> BoundingBox3d.BoundingBox3d units coordinates
Removed:
hull2 :
BoundingBox3d units coordinates
-> BoundingBox3d units coordinates
-> BoundingBox3d units coordinates
Changed:
- hull :
BoundingBox3d units coordinates
-> List (BoundingBox3d units coordinates)
-> BoundingBox3d units coordinates
+ hull :
Point3d.Point3d units coordinates
-> List.List (Point3d.Point3d units coordinates)
-> BoundingBox3d.BoundingBox3d units coordinates
- hull3 :
BoundingBox3d units coordinates
-> BoundingBox3d units coordinates
-> BoundingBox3d units coordinates
-> BoundingBox3d units coordinates
+ hull3 :
Point3d.Point3d units coordinates
-> Point3d.Point3d units coordinates
-> Point3d.Point3d units coordinates
-> BoundingBox3d.BoundingBox3d units coordinates
- hullN :
List (BoundingBox3d units coordinates)
-> Maybe (BoundingBox3d units coordinates)
+ hullN :
List.List (Point3d.Point3d units coordinates)
-> Maybe.Maybe (BoundingBox3d.BoundingBox3d units coordinates)
- hullOf :
(a -> BoundingBox3d units coordinates)
-> a
-> List a
-> BoundingBox3d units coordinates
+ hullOf :
(a -> Point3d.Point3d units coordinates)
-> a
-> List.List a
-> BoundingBox3d.BoundingBox3d units coordinates
---- Circle2d - MINOR ----
Added:
atOrigin :
Quantity.Quantity Basics.Float units
-> Circle2d.Circle2d units coordinates
atPoint :
Point2d.Point2d units coordinates
-> Quantity.Quantity Basics.Float units
-> Circle2d.Circle2d units coordinates
---- Frame2d - MAJOR ----
Changed:
- atOrigin : Frame2d units coordinates { defines : coordinates }
+ atOrigin : Frame2d.Frame2d units coordinates defines
---- Frame3d - MAJOR ----
Changed:
- atOrigin : Frame3d units coordinates { defines : coordinates }
+ atOrigin : Frame3d.Frame3d units coordinates defines
---- LineSegment2d - MINOR ----
Added:
fromPointAndVector :
Point2d.Point2d units coordinates
-> Vector2d.Vector2d units coordinates
-> LineSegment2d.LineSegment2d units coordinates
---- LineSegment3d - MINOR ----
Added:
fromPointAndVector :
Point3d.Point3d units coordinates
-> Vector3d.Vector3d units coordinates
-> LineSegment3d.LineSegment3d units coordinates
---- Point2d - MAJOR ----
Removed:
hull :
Point2d units coordinates
-> List (Point2d units coordinates)
-> BoundingBox2d units coordinates
hull2 :
Point2d units coordinates
-> Point2d units coordinates
-> BoundingBox2d units coordinates
hull3 :
Point2d units coordinates
-> Point2d units coordinates
-> Point2d units coordinates
-> BoundingBox2d units coordinates
hullN :
List (Point2d units coordinates)
-> Maybe (BoundingBox2d units coordinates)
hullOf :
(a -> Point2d units coordinates)
-> a
-> List a
-> BoundingBox2d units coordinates
---- Point3d - MAJOR ----
Removed:
hull :
Point3d units coordinates
-> List (Point3d units coordinates)
-> BoundingBox3d units coordinates
hull2 :
Point3d units coordinates
-> Point3d units coordinates
-> BoundingBox3d units coordinates
hull3 :
Point3d units coordinates
-> Point3d units coordinates
-> Point3d units coordinates
-> BoundingBox3d units coordinates
hullN :
List (Point3d units coordinates)
-> Maybe (BoundingBox3d units coordinates)
hullOf :
(a -> Point3d units coordinates)
-> a
-> List a
-> BoundingBox3d units coordinates
---- Rectangle2d - MAJOR ----
Added:
centeredOn :
Frame2d.Frame2d units coordinates defines
-> ( Quantity.Quantity Basics.Float units
, Quantity.Quantity Basics.Float units
)
-> Rectangle2d.Rectangle2d units coordinates
Removed:
withAxes :
Frame2d units coordinates defines
-> ( Quantity Float units, Quantity Float units )
-> Rectangle2d units coordinates
---- Sphere3d - MINOR ----
Added:
atOrigin :
Quantity.Quantity Basics.Float units
-> Sphere3d.Sphere3d units coordinates
atPoint :
Point3d.Point3d units coordinates
-> Quantity.Quantity Basics.Float units
-> Sphere3d.Sphere3d units coordinates
Published by ianmackenzie about 5 years ago
elm-geometry
2.0 is out! For now this is a bit of a preview release; it's feature-complete and I'm pretty happy with the API, but the docs are not yet as complete as they should be. Feel free to try out the new version, but please let me (@ianmackenzie) know on Slack if you find any gaps or errors in the documentation.
The main new feature in this release (that will break all your code) is the addition of type-level tracking of the units and coordinate systems associated with different values. Most types now have two type parameters; where in elm-geometry
1.x you'd have a plain
Point3d
in elm-geometry
2.x you'll have a
Point3d units coordinates
instead. Individual coordinate/component values are now Quantity
values from elm-units
, so you might construct points using
Point2d.xy (Pixels.pixels 100) (Pixels.pixels 200)
Point3d.xyz (Length.meters 2) (Length.meters 3) (Length.meters 1)
or, to be more concise (especially when prototyping/experimenting),
Point2d.pixels 100 200
Point3d.meters 2 3 1
Unlike units, which can generally be inferred to be a concrete type from usage, the coordinates
type variable is largely "optional": you can choose to annotate particular values as being in particular coordinate systems (and then the compiler can check whether those annotations are consistent with each other), but you can also often ignore it entirely. The only time a coordinates type is actually required is if you need to add a type annotation to a top level value; and in the simple case, where everything is in one coordinate system, you can do something like
type World
= World
and then annotate points as (for example)
myPoint : Point3d Meters World
myPoint =
Point3d.meters 5 10 20
If different values have different units and coordinate systems, we of course need ways to convert between them! The Frame2d
, Frame3d
and SketchPlane3d
types now both exist in a particular coordinate system and define their own coordinate system; this means that functions like placeIn
and relativeTo
now let you convert between different coordinate systems. (They always did, really, now it's just official at the type level.) For units, there are new at
and at_
functions in each module that act just like the corresponding functions at
and at_
functions in the Quantity
module.
In addition to the new units/coordinate system, point/vector/direction construction has been streamlined and made significantly more flexible. For example, here are several ways of defining the same point:
-- Most flexible, useful with Json.Decode.map3 etc.
Point3d.xyz (Length.meters 2) (Length.meters 3) (Length.meters 1)
-- Very succinct, especially handy for experimentation/REPL use
Point3d.meters 2 3 1
-- Flexible conversion from plain Elm data types
Point3d.fromRecord Length.meters { x = 2, y = 3, z = 1 }
Point3d.fromTuple Length.meters ( 2, 3, 1 )
Point3d.fromRecord Length.centimeters { x = 200, y = 300, z = 100 }
Point3d.fromTuple Length.centimeters ( 200, 300, 100 )
-- Zero-overhead construction from records that happen
-- to be in 'base' units (meters or pixels)
Point3d.fromMeters { x = 2, y = 3, z = 1 }
It's also much easier to construct directions:
Direction2d.fromAngle (Angle.degrees 30) -- like before
Direction2d.degrees 30 -- handy shorthand
Direction3d.xy (Angle.degrees 45) -- an angle on the XY plane
Direction3d.yz (Angle.degrees 60) -- an angle on the YZ plane
Direction3d.xyZ (Angle.degrees 45) -- azimuth in XY...
(Angle.degrees 30) -- ...and elevation towards +Z
Direction3d.zxY (Angle.degrees 45) -- azimuth in ZX...
(Angle.degrees 30) -- ...and elevation towards +Y
While I was working on units and coordinate systems in the coordinate-systems
branch, several new features were contributed by various members of the community; these have all now been merged into 2.0:
expandBy
and offsetBy
functions for BoundingBox2d
and BoundingBox3d
to allow expanding or contracting bounding boxes. (The former only ever expands, and returns a plain bounding box; the latter also supports contraction but returns a Maybe
to handle the case where the bounding box contracts to nothing.) Thanks @MrL1605!midpoint
functions for QuadraticSpline2d
, QuadraticSpline3d
, CubicSpline2d
and CubicSpline3d
as a convenient way to find the point half way along a spline by arc length (not parameter value). Thanks @MrL1605!centroid
functions for Polyline2d
and Polyline3d
to find the center of mass of a polyline. Thanks @davcamer!Polygon2d.contains
to check whether a given point is contained within a given polygon. Thanks @gampleman!Circle2d.intersectsBoundingBox
to check whether a circle touches a bounding box. Thanks @SebastianKG!I took the opportunity to fix one thing that's been bothering me a bit: functions that compute the centroid or hull (bounding box) of a list of points have to return a Maybe
so that they can return Nothing
if given an empty list. There are now a few different versions of those functions for different use cases, for example:
-- If you definitely have at least one point (no Maybe!)
Point3d.centroid :
Point3d units coordinates -- first point
-> List (Point3d units coordinates) -- rest
-> Point3d units coordinates
-- If you have exactly 3 points (efficient - no list allocation/manipulation)
Point3d.centroid3 :
Point3d units coordinates
-> Point3d units coordinates
-> Point3d units coordinates
-> Point3d units coordinates
-- If you have an unknown number of points (as before)
Point3d.centroidN :
List (Point3d units coordinates)
-> Maybe (Point3d units coordinates)
This means that if you've pattern-matched a list and already have it in head/tail form, then you don't have to deal with the (impossible) Nothing
case.
As part of this change a few hull-type functions were renamed/moved around; for example BoundingBox2d.from
is now Point2d.hull2
and BoundingBox2d.containingPoints
is now Point2d.hullN
.
The existing BoundingBox#d.overlappingBy
and BoundingBox#d.separatedBy
functions are very flexible but difficult to describe, inefficient to implement and generally a bit confusing. They've now been simplified to what are hopefully the most common/useful cases:
BoundingBox2d.overlappingByAtLeast :
Quantity Float units
-> BoundingBox2d units coordinates
-> BoundingBox2d units coordinates
-> Bool
BoundingBox2d.separatedByAtLeast:
Quantity Float units
-> BoundingBox2d units coordinates
-> BoundingBox2d units coordinates
-> Bool
(Plus similar for BoundingBox3d
.)
There are several more smaller changes and probably some I'm forgetting; check out the API docs and reach out if you're confused/curious about anything!
Published by ianmackenzie over 5 years ago
elm-geometry
1.3.0 is out! This is a minor release with a few nice additions, all contributed by the community:
expandBy
and offsetBy
functions for BoundingBox2d
and BoundingBox3d
to allow expanding or contracting bounding boxes. (The former only ever expands, and returns a plain bounding box; the latter also supports contraction but returns a Maybe
to handle the case where the bounding box contracts to nothing.) Thanks @MrL1605!midpoint
functions for QuadraticSpline2d
, QuadraticSpline3d
, CubicSpline2d
and CubicSpline3d
as a convenient way to find the point half way along a spline by arc length (not parameter value). Thanks @MrL1605!centroid
functions for Polyline2d
and Polyline3d
to find the center of mass of a polyline. Thanks @davcamer!Polygon2d.contains
to check whether a given point is contained within a given polygon. Thanks @gampleman!Published by ianmackenzie about 6 years ago
Add images to Voronoi/Delaunay docs
Published by ianmackenzie about 6 years ago
elm-geometry
1.2 is out! The major feature in this release is support for generation of Delaunay triangulations and Voronoi diagrams:
Huge thanks to @folkertdev for all his work on this in #58!
Additionally, this release adds a Rectangle2d
module for directly creating and manipulating rectangles (which, unlike the similar BoundingBox2d
, can be rotated/mirrored etc.).
Last (and least, really), a few functions have been renamed - the old names have been kept for now but will likely be removed in the next major release:
1.1 | 1.2 |
---|---|
BoundingBox2d.centroid |
BoundingBox2d.centerPoint |
BoundingBox3d.centroid |
BoundingBox3d.centerPoint |
Frame2d.xy |
Frame2d.atOrigin |
Frame3d.xyz |
Frame3d.atOrigin |
Finally, shoutout to @dmy for the excellent elm-doc-preview tool. I used it quite a bit when finishing up the documentation for this release, and it made things really pleasant. Highly recommended to other package authors to let you quickly iterate on your documentation before release!
Published by ianmackenzie about 6 years ago
First release for Elm 0.19! This is almost identical to the last published release for Elm 0.18 (1.0.2), but contains a handful of new functions:
LineSegment2d.intersectionWithAxis : Axis2d -> LineSegment2d -> Maybe Point2d
Point2d.centroid : List Point2d -> Maybe Point2d
Point3d.centroid : List Point3d -> Maybe Point3d
Published by ianmackenzie over 6 years ago
elm-geometry
1.0 is out! This is effectively version 3.0 of opensolid/geometry
, with quite a few changes since opensolid/geometry
2.1.0:
OpenSolid.
prefixInterval
and Scalar
modules out into their own packagesParameterValue
and SweptAngle
modulespointOn
Polygon2d
functionality significantlyIn general, to update code written for opensolid/geometry
to use elm-geometry
, first remove the OpenSolid.
prefix from all imports. Then, follow the compiler error messages and look within these release notes to see how individual function calls should be updated (for example, search for Vector3d.with
to see that it has been replaced by Vector3d.withLength
). That said, these release notes are not exhaustive, so if you run into anything not covered here, come ask in the #geometry channel on the Elm Slack!
Modules no longer include an OpenSolid.
prefix, so imports are now more succinct:
-- opensolid/geometry
import OpenSolid.Point3d as Point3d exposing (Point3d)
-- elm-geometry
import Point3d exposing (Point3d)
The module names in elm-geometry
have been chosen to try to avoid conflicts with other published Elm packages, but if you do find a conflict, please file an issue.
opensolid/geometry
included built-in support for JSON encoding and decoding, but after some discussion on Discourse and Slack it was decided to remove this functionality from elm-geometry
. It may reappear later, but likely as a separate package.
A couple of modules have been moved out into their own packages:
OpenSolid.Interval
has been split out into ianmackenzie/elm-interval
OpenSolid.Scalar
has been split out into ianmackenzie/elm-float-extra
, with the Interval
-related functions moved to elm-interval
Curve.ParameterValue
Evaluating points on curves now requires you to pass a ParameterValue
instead of a plain Float
. A ParameterValue
is effectively a Float
that is guaranteed to be between 0 and 1, which adds some extra type safety to curve evaluation. The ParameterValue
module includes functions for constructing ParameterValue
s from plain Float
s, and several convenient functions for constructing ranges of evenly-spaced parameter values.
Arc.SweptAngle
The Arc.SweptAngle
module replaces the duplicate SweptAngle
types and values that existed the Arc2d
and EllipticalArc2d
modules:
-- opensolid/geometry
Arc2d.smallPositive : Arc2d.SweptAngle
EllipticalArc2d.smallPositive : EllipticalArc2d.SweptAngle
-- elm-geometry
SweptAngle.smallPositive : SweptAngle.SweptAngle
A very common and important operation in elm-geometry
is evaluating positions and tangent directions at various points along a curve (such as an arc or a cubic Bezier spline). A few related changes have been made in elm-geometry
to make this more type-safe and explicit. First of all, as mentioned above, curve evaluation functions now generally take ParameterValue
arguments instead of plain Float
ones:
-- opensolid/geometry
CubicSpline3d.pointOn : CubicSpline3d -> Float -> Point3d
-- elm-geometry
CubicSpline3d.pointOn : CubicSpline3d -> ParameterValue -> Point3d
You can construct a ParameterValue
using ParameterValue.clamped
, but for the common case of evaluating many points at once there are also functions for directly generating a list of parameter values and then evaluating curves at those values. For example, to get 11 points on a cubic spline (including the start and end points), you could use
pointsOnSpline =
cubicSpline |> CubicSpline3d.pointsAt (ParameterValue.steps 10)
Note that if you take 1 step along a curve you get 2 points (start and end), if you take 2 steps along a curve you get 3 points (start, middle and end), if you take 10 steps along a curve you get 11 points, etc.
Curves now also support evaluating tangent directions and 'samples' (point/tangent direction pairs), but only if the curve is nondegenerate. If a curve is actually just a single point (e.g. a spline where all control points are equal), then the curve is said to be degenerate and the tangent direction is undefined. All curve types (Arc3d
, EllipticalArc2d
, CubicSpline3d
etc.) now have functions like
CubicSpline3d.nondegenerate : CubicSpline3d -> Result Point3d CubicSpline3d.Nondegenerate
to attempt to convert a curve to its guaranteed-nondegenerate form. If the curve is in fact degenerate (consists of a single point) then you will get an Err
with that point instead. Once you have a Nondegenerate
value, you can then use it to evaluate tangent directions and samples:
CubicSpline3d.tangentDirection : CubicSpline3d.Nondegenerate -> ParameterValue -> Direction3d
CubicSpline3d.sample : CubicSpline3d.Nondegenerate -> ParameterValue -> ( Point3d, Direction3d )
For example, if you wanted to animate along a cubic spline, you might call CubicSpline3d.nondegenerate
first to try to get a nondegenerate curve. If that succeeds, then use the resulting Nondegenerate
value to evaluate points and tangent directions along the curve. If it fails, then you should apply special-case logic - perhaps drop that curve entirely from your animation path, or display your animated object in a fixed position (using the point returned in the Err
case) with some default orientation.
Polygon2d
improvementsThe Polygon2d
module has been improved significantly in this release. First of all, polygons can now have holes, which necessitated several changes:
Polygon2d.fromVertices
has been renamed to Polygon2d.singleLoop
to emphasize that it constructs a polygon without holesPolygon2d.with
has been added to construct polygons with holesPolygon2d.outerLoop
and Polygon2d.innerLoops
accessors have been addedPolygon2d.clockwiseArea
, Polygon2d.counterclockwiseArea
and Polygon2d.mapVertices
have been removed since they could not easily be made to work with the new polygon representationPolygon2d.convexHull
has been added to compute the convex hull of a set of points (thanks @gampleman!):
Finally, polygons can now be triangulated, so you can define a polygon just by specifying its outline (and holes, if it has any)
then use Polygon2d.triangulate
to turn that polygon into a list of triangles:
This is primarily useful for WebGL rendering but has many other applications.
There was a significant push in this release to streamline geometry construction functions. Many functions that previously took a single record argument have been reworked to take multiple arguments instead, with the following goals in mind:
|>
, map
, map2
etc.For example,
-- opensolid/geometry
Vector2d.with { length = 3, direction = Direction2d.x }
can now be written as
-- elm-geometry
Vector2d.withLength 3 Direction2d.x
Similarly,
-- opensolid/geometry
Axis2d.with { originPoint = point, direction = direction }
can now be written as
-- elm-geometry
Axis2d.through point direction
-- OR
Axis2d.withDirection direction point
Having both versions allow you to do different things with partial application:
-- A list of axes in different directions all passing through the same origin point
List.map (Axis2d.through point) directions
-- A list of parallel axes (all having the same direction) through different points
List.map (Axis2d.withDirection direction) points
Many other constructors have been similarly updated:
opensolid/geometry |
elm-geometry |
---|---|
Arc2d.fromEndpoints |
Arc2d.withRadius: Float -> SweptAngle -> Point2d -> Point2d -> Maybe Arc2d |
Arc2d.with |
Arc2d.sweptAround: Point2d -> Float -> Point2d -> Arc2d |
Arc3d.around |
Arc3d.sweptAround: Axis3d -> Float -> Point3d -> Arc3d |
Axis3d.with |
Axis3d.through: Point3d -> Direction3d -> Axis3d Axis3d.withDirection: Direction3d -> Point3d -> Axis3d
|
Circle2d.with |
Circle2d.withRadius: Float -> Point2d -> Circle2d |
Circle3d.with |
Circle3d.withRadius: Float -> Direction3d -> Point3d -> Circle3d |
Direction3d.with |
Direction3d.fromAzimuthAndElevation: ( Float, Float ) -> Direction3d |
Frame2d.with |
Frame2d.withXDirection: Direction2d -> Point2d -> Frame2d Frame2d.withYDirection: Direction2d -> Point2d -> Frame2d
|
Frame3d.with |
Frame3d.withXDirection: Direction3d -> Point3d -> Frame3d Frame3d.withYDirection: Direction3d -> Point3d -> Frame3d Frame3d.withZDirection: Direction3d -> Point3d -> Frame3d
|
Plane3d.with |
Plane3d.through: Point3d -> Direction3d -> Plane3d Plane3d.withNormalDirection: Direction3d -> Point3d -> Plane3d
|
SketchPlane3d.with |
SketchPlane3d.withNormalDirection: Direction3d -> Point3d -> SketchPlane3d |
Sphere3d.with |
Sphere3d.withRadius: Float -> Point3d -> Sphere3d |
Vector3d.with |
Vector3d.withLength : Float -> Direction3d -> Vector3d |
The quadratic and cubic spline constructors previously known as fromControlPoints
have been updated to avoid the use of large tuples, and generally be consistent with constructors in other modules:
-- opensolid/geometry
QuadraticSpline2d.fromControlPoints ( p1, p2, p3 )
CubicSpline3d.fromControlPoints ( p1, p2, p3, p4 )
-- elm-geometry
QuadraticSpline2d.with
{ startPoint = p1
, controlPoint = p2
, endPoint = p3
}
CubicSpline3d.with
{ startPoint = p1
, startControlPoint = p2
, endControlPoint = p3
, endPoint = p4
}
Similarly, CubicSpline#d.hermite
has been replaced by fromEndpoints
:
-- opensolid/geometry
CubicSpline3d.hermite ( p1, v1 ) ( p2, v2 )
-- elm-geometry
CubicSpline3d.fromEndpoints
{ startPoint = p1
, startDerivative = v1
, endPoint = p2
, endDerivative = v2
}
As a small but very useful change, all modules with translateBy
functions now also have translateIn
functions; for example,
triangle |> Triangle3d.translateIn Direction3d.y 5
means "translate triangle
in the Y direction by 5 units".
Arc2d.from
has been added as a new and convenient way to construct arcs from a start point, end point and swept angle:
cornerArc =
Arc2d.from startPoint endPoint (degrees 90)
A new version of Arc2d.with
has also been added:
semicircle =
Arc2d.with
{ centerPoint = Point2d.origin
, radius = 3
, startAngle = degrees 0
, sweptAngle = degrees 180
}
Circle2d.sweptAround
has been added to construct a circle by sweeping one point around a center point:
circle =
Circle2d.sweptAround centerPoint pointOnCircle
Bounding boxes can now be constructed for splines:
CubicSpline2d.boundingBox : CubicSpline2d -> BoundingBox2d
CubicSpline3d.boundingBox : CubicSpline3d -> BoundingBox3d
QuadraticSpline2d.boundingBox : QuadraticSpline2d -> BoundingBox2d
QuadraticSpline3d.boundingBox : QuadraticSpline3d -> BoundingBox3d
It's now possible to compute the second derivative for cubic splines as well as quadratic ones:
CubicSpline2d.secondDerivative : CubicSpline2d -> ParameterValue -> Vector2d
CubicSpline3d.secondDerivative : CubicSpline3d -> ParameterValue -> Vector3d
If you have an arc length parameterized curve, you can now recover the original curve from it:
CubicSpline2d.fromArcLengthParameterized : CubicSpline2d.ArcLengthParameterized -> CubicSpline2d
CubicSpline3d.fromArcLengthParameterized : CubicSpline3d.ArcLengthParameterized -> CubicSpline3d
EllipticalArc2d.fromArcLengthParameterized : EllipticalArc2d.ArcLengthParameterized -> EllipticalArc2d
QuadraticSpline2d.fromArcLengthParameterized : QuadraticSpline2d.ArcLengthParameterized -> QuadraticSpline2d
QuadraticSpline3d.fromArcLengthParameterized : QuadraticSpline3d.ArcLengthParameterized -> QuadraticSpline3d
Frame2d.atCoordinates
has been added as a convenient shorthand for Frame2d.atPoint
+Point2d.fromCoordinates
, and similar for Frame3d
:
Frame2d.atCoordinates : ( Float, Float ) -> Frame2d
Frame3d.atCoordinates : ( Float, Float, Float ) -> Frame3d
Point2d
values can now be constructed directly from their polar coordinates with respect to a particular Frame2d
:
Point2d.fromPolarCoordinatesIn : Frame2d -> ( Float, Float ) -> Point2d
Finally, like Direction2d
, Vector2d
values can now also be conveniently (and efficiently) rotated 90 degrees clockwise or counterclockwise:
Vector2d.rotateClockwise : Vector2d -> Vector2d
Vector3d.rotateCounterclockwise : Vector2d -> Vector2d
Several functions have been renamed to try to be more descriptive, read better in pipelines, reduce circular dependencies between modules, or be more consistent with how other functions are named:
opensolid/geometry |
elm-geometry |
---|---|
Axis2d.flip |
Axis2d.reverse |
Axis3d.flip |
Axis3d.reverse |
BoundingBox2d.hullOf |
BoundingBox2d.aggregate |
BoundingBox3d.hullOf |
BoundingBox3d.aggregate |
BoundingBox2d.with |
BoundingBox2d.fromExtrema |
BoundingBox3d.with |
BoundingBox3d.fromExtrema |
Circle3d.around |
Circle3d.sweptAround |
Direction2d.angle |
Direction2d.toAngle |
Direction2d.flip |
Direction2d.reverse |
Direction3d.flip |
Direction3d.reverse |
Frame2d.flipX |
Frame2d.reverseX |
Frame2d.flipY |
Frame2d.reverseY |
Frame3d.flipX |
Frame3d.reverseX |
Frame3d.flipY |
Frame3d.reverseY |
Frame3d.flipZ |
Frame3d.reverseZ |
LineSegment2d.normalDirection |
LineSegment2d.perpendicularDirection |
LineSegment3d.normalDirection |
LineSegment3d.perpendicularDirection |
Plane3d.flip |
Plane3d.reverseNormal |
Point2d.hull |
BoundingBox2d.from |
Point3d.hull |
BoundingBox3d.from |
Point2d.hullOf |
BoundingBox2d.containingPoints |
Point3d.hullOf |
BoundingBox3d.containingPoints |
Point2d.in_ |
Point2d.fromCoordinatesIn |
Point3d.in_ |
Point2d.fromCoordinatesIn |
SketchPlane3d.flipX |
SketchPlane3d.reverseX |
SketchPlane3d.flipY |
SketchPlane3d.reverseY |
SketchPlane3d.plane |
SketchPlane3d.toPlane |
Vector2d.flip |
Vector2d.reverse |
Vector3d.flip |
Vector3d.reverse |
A few functions have been removed in this release, but each one was simply a deprecated alias for a better-named replacement:
Removed | Replacement |
---|---|
BoundingBox2d.overlaps |
BoundingBox2d.intersects |
BoundingBox3d.overlaps |
BoundingBox3d.intersects |
Point2d.distanceAlong |
Point2d.signedDistanceAlong |
Point3d.distanceAlong |
Point3d.signedDistanceAlong |