Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to find Direction3d perpendicular to two other Direction3ds #125

Open
MartinSStewart opened this issue Jan 16, 2020 · 8 comments

Comments

@MartinSStewart
Copy link

I wasn't able to find a function with the following signature Direction3d c -> Direction3d c -> Maybe (Direction3d c) that finds a direction that's perpendicular to two other directions (aka the axis of rotation of those two directions).

This could be implemented as:

Vector3d.cross (Direction3d.toVector dir0) (Direction3d.toVector dir1) |> Vector3d.direction

This function is pretty simple but I think it's worth including because anyone who forgot what cross products do, will have trouble figuring out how to implement this (me included until @w0rm reminded me). Unfortunately, I'm not sure what's a good name for this function.

@ianmackenzie
Copy link
Owner

The simplest name and signature would probably be

Direction3d.cross : 
    Direction3d coordinates
    -> Direction3d coordinates
    -> Maybe (Direction3d coordinates)

but that doesn't help if you don't remember what cross products do! One option would be to call it perpendicularToBoth or perpendicularTo2 since it can be thought of as an extension of the existing perpendicularTo, but then it seems a little ambiguous what should happen if the two given directions are parallel:

  • Return Nothing:
    • Makes sense if thought of as a cross product
    • Safest since it forces the user to explicitly handle that case
  • Return an arbitrary perpendicular direction (fall back to calling perpendicularTo on one of the directions):
    • Allows the function to return a Direction3d instead of a Maybe Direction3d
    • Consistent with perpendicularTo
    • Reasonably defensible because the result will in fact be a direction perpendicular to both inputs

Thoughts?

@ianmackenzie
Copy link
Owner

Side note: Vector3d.cross is designed to be used in pipeline form, so you would write

(Direction3d.toVector dir0) |> Vector3d.cross (Direction3d.toVector dir1)

instead of

Vector3d.cross (Direction3d.toVector dir0) (Direction3d.toVector dir1)

to get a right-handed cross product dir0 x dir1.

@MartinSStewart
Copy link
Author

MartinSStewart commented Jan 16, 2020

I think either perpendicularToBoth or perpendicularTo2 are good names though I'm not sure which I prefer. When trying to find this function, I looked for functions containing perpendicular or ortho so if it was named perpendicularToBoth or perpendicularTo2 then I would have found it.

I think it's best for it to return Nothing. For perpendicularTo it will consistently return an arbitrary perpendicular direction so it isn't a surprise. With this function it will only happen in an edge case so I think it's best that we force the user to handle that edge case by returning a Maybe.

Also thanks for the note about Vector3d.cross. I hadn't even thought about the handedness of the cross product (in my use case it doesn't matter at least).

Edit: I'm having second thoughts about my preference to return Maybe, Reasonably defensible because the result will in fact be a direction perpendicular to both inputs is a pretty good argument for falling back on perpendicularTo

@ianmackenzie
Copy link
Owner

Maybe it makes sense to have both the pure mathematical version and the convenient version:

Direction3d.cross :
    Direction3d coordinates
    -> Direction3d coordinates
    -> Maybe (Direction3d coordinates)

Direction3d.perpendicularToBoth :
    Direction3d coordinates
    -> Direction3d coordinates
    -> Direction3d coordinates

@ianmackenzie
Copy link
Owner

The one other thing to think about is whether it also makes sense to have a version for vectors, e.g.

Direction3d.perpendicularToTwoVectors :
    Vector3d coordinates
    -> Vector3d coordinates
    -> Direction3d coordinates

@MartinSStewart
Copy link
Author

I think it’s best to just have the Direction3d.perpendicularToTwo for now. I’ve only had need for this once. While it is nice to have, I think having 3 versions of it might be too much (also I’ve changed my mind and think it should return Direction3d rather than Maybe)

@ianmackenzie
Copy link
Owner

Yeah, I'm not sure I'd add a vector version right away, but it would be nice to have a function name that could be naturally extended to a vector version in the future. For example Direction3d.perpendicularToBothVectors and Direction3d.perpendicularTo2Vectors both seem a bit weird to me; Direction3d.perpendicularToTwoVectors seems better but then Direction3d.perpendicularToTwo seems weird.

@ianmackenzie
Copy link
Owner

Actually yeah, maybe it's not worth worrying about a vector version - there's always Vector3d.cross, and (if I implement #126) Direction3d.orthonormalize2. I think I'm leaning towards Direction3d.perpendicularTo2 to emphasize that it's a pretty direct variant of Direction3d.perpendicularTo, but I might mull it over for a while.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants