This is a meta-issue for potential breaking changes to make for an elm-geometry
1.0 version. Feel free to post suggestions in the comments and I'll edit this issue text.
Module naming
I used prefixed module names like OpenSolid.Point2d
to avoid potential naming conflicts with modules from other packages, but based on elm/compiler#1625 it seems that this might be considered "silly module renaming". Should the prefixes be removed? I think they should remain in a few cases like OpenSolid.Geometry.Decode
, but otherwise module names could be switched to just plain Point2d
, Triangle2d
etc. What about the Scalar
and Interval
modules? Those are fairly generic names, so might benefit from staying as OpenSolid.Scalar
and OpenSolid.Interval
...but then that feels a bit inconsistent/arbitrary. Rename to Scalar1d
and Interval1d
and just lay claim to all module names ending in 1d
, 2d
or 3d
?
Switching to non-prefixed names would be more consistent with other Elm packages - elm-community/elm-test
uses top-level Expect
, Fuzz
and Test
modules, mdgriffith/style-elements
uses top-level Style
and Element
modules, terezka/elm-plot
uses a top-level Plot
module, etc.
Additionally, if the non-prefixed names don't work out and run into conflicts with other packages, then these conflicts will provide additional data points for elm/compiler#1625.
Package split
This is tracked in a separate issue, but splitting this package into two smaller packages would certainly be a major version change (although it shouldn't actually require any code changes, just modifications to dependencies in elm-package.json
).
Moves/renames
- It would probably make sense to have
SweptAngle
as its own module now that Arc2d
and EllipticalArc2d
both use the same concept (currently just two independent but identical Arc2d.SweptAngle
and EllipticalArc2d.SweptAngle
types). This would likely mean adding an Internal.SweptAngle
type and just exposing SweptAngle.smallPositive
etc.; the Arc2d
and EllipticalArc2d
modules could then pattern-match on the Internal.SweptAngle
constructors. (Directly referring to stuff like SweptAngle.SmallPositive
feels a bit weird, and I can't think of any cases where it would be useful for end-user code to pattern-match on SweptAngle
values.) On the other hand, if the OpenSolid
prefix is removed, then it might not make sense to have a top-level SweptAngle
module (unlikely to conflict with modules from other packages, but a little less obvious what package it comes from than something like Point3d
).
- I find I often want to write
Direction2d.toAngle
instead of Direction2d.angle
. angle
is consistent with other functions like components
and coordinates
in that it treats the returned angle as a property of the direction ("the angle of the direction") instead of an alternate representation ("the direction converted to an angle"); I wouldn't want to have Point2d.toTuple
or Point2d.toCoordinates
, for example, but somehow Direction2d.toAngle
feels more natural than Direction2d.angle
. Similarly should SketchPlane3d.plane
be SketchPlane3d.toPlane
? Does it make more sense to talk about "the plane of a sketch plane" or "converting a sketch plane to a plane"?
- It may be more clear to rename some or all of the
with
functions to have more descriptive names. In some cases like Axis#d.fromOriginAndDirection
this might also imply switching from a single record argument to multiple 'plain' arguments. Possible renames:
Frame2d.with
to Frame2d.fromOriginAndXDirection
(and add Frame2d.fromOriginAndYDirection
)
Frame3d.with
to Frame3d.fromOriginAndZDirection
(and add Frame3d.fromOriginAndXDirection
, Frame3d.fromOriginAndYDirection
)
Vector#d.with
to Vector#d.fromLengthAndDirection
BoundingBox#d.with
to BoundingBox#d.fromExtrema
Interval.with
to Interval.fromExtrema
Axis#d.with
to Axis#d.fromOriginAndDirection
Plane3d.with
to Plane3d.fromPointAndNormal
Arc2d.with
to Arc2d.fromCenterAndStart
Circle#d.with
to Circle#d.fromCenterAndRadius
(although Circle3d
also requires an axialDirection
parameter...)
Sphere3d.with
to Sphere3d.fromCenterAndRadius
Direction3d.with
to Direction3d.fromSphericalAngles
Ellipse2d.with
to Ellipse2d.fromCenter
, or perhaps change to Ellipse2d.centeredOn : Frame2d -> { xRadius : Float, yRadius : Float } -> Ellipse2d
EllipticalArc2d.with
to EllipticalArc2d.fromCenter
, or perhaps change to EllipticalArc2d.centeredOn : Frame2d -> { xRadius : Float, yRadius : Float, startAngle : Float, endAngle : Float } -> EllipticalArc2d
SketchPlane3d.with
to SketchPlane3d.fromPointAndNormal
Rectangle2d.with
to Rectangle2d.axisAligned
Switch from Maybe
to Result
Currently there are several constructor/factory functions such as Arc2d.fromEndpoints
that return Maybe
values if construction fails (invalid arguments given, no solution found, etc.). Ideally many of these should be switched to return Result
values instead with a custom error type that indicates the failure reason; for example, @folkertdev's proposal for EllipticalArc2d.fromEndpoints
:
type ArcError
= IdenticalStartAndEndpoint -- omit this segment
| RadiusIsZero -- (i.e. endpoint == center) draw straight line segment
| NoSolution -- maybe point to docs on how svg deals with this
One possible modification: change the NoSolution
case to actually include the 'best approximation' elliptical arc with X and Y radius scaled to make arc construction possible. This way attempting to construct an ellipse with invalid/impossible radii is an Err
, but the user can explicitly choose to fall back to the scaled ellipse if they want (which is what browser SVG engines do, since that's what's mandated by the SVG spec).