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

Rhumb no longer goes past pole #1153

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

joe-saronic
Copy link
Contributor

@joe-saronic joe-saronic commented Feb 22, 2024

  • I agree to follow the project's code of conduct.
  • I added an entry to CHANGES.md if knowledge of this change could be valuable to users.

Fixes #1152

@apendleton
Copy link
Contributor

I don't have review powers in this repo, but my two cents: one result of this change is that the rhumb-line intermediate and intermediate-fill operations might now panic given some float inputs. I think that's probably undesirable/surprising, and we'd be better off either with propagating this API change across to those methods as well, or clamping (either just for those or in general). You could consider returning an Option for intermediate, mirroring the change for destination, but I think for intermediate-fill, returning a Vec<Option<T>> will probably make the results sort of tedious to work with in practice, and I wonder if consumers might prefer to just have them clamped? And if so, if it wouldn't be better for consistency to just always clamp.

(I suppose another option would be Option<Vec<T>>, and just None the whole thing if any of them would have been None, which seems easier to use but strictly less useful.)

@joe-saronic
Copy link
Contributor Author

I am happy to add checks that both inputs are between -90 and 90. There is no other scenario that will make any of the methods fail that I'm aware of.

@apendleton
Copy link
Contributor

For sure, agreed that that's the circumstance where it matters. I think implementation isn't that important (do we check up front for -90 < x < 90 or do we just wait until the destination operation returns None and do something in that case; I think the latter is probably easier?). The main question is what happens in that case from an API perspective, and I think it probably shouldn't be "panic," it should be one of:

  • we always return a float but it's clamped
  • we return an Option<T> or Vec<Option<T>> or something, and return None in this case, or
  • We return a Result<T, E> or Vec<Result<T, E>>and return anErr` case if out-of-bounds inputs are passed in

@urschrei
Copy link
Member

For sure, agreed that that's the circumstance where it matters. I think implementation isn't that important (do we check up front for -90 < x < 90 or do we just wait until the destination operation returns None and do something in that case; I think the latter is probably easier?). The main question is what happens in that case from an API perspective, and I think it probably shouldn't be "panic," it should be one of:

  • we always return a float but it's clamped
  • we return an Option<T> or Vec<Option<T>> or something, and return None in this case, or
  • We return a Result<T, E> or Vec<Result<T, E>>and return anErr` case if out-of-bounds inputs are passed in

Happy to assign you once you accept the org invite!

@joe-saronic joe-saronic force-pushed the joe/rhumb branch 2 times, most recently from d413d3e to b57059d Compare February 23, 2024 16:04
@joe-saronic
Copy link
Contributor Author

joe-saronic commented Feb 23, 2024

I attempted to add clamping, but realized that it may be impractical. I left the broken commit with a unit test that illustrates the issue in. Basically, clamping to exactly +/-90 will make the actual point invalid and the intermediate longitudes will (correctly) be set to NaN. The alternatives are adding/subtracting epsilon to the clamp, which I think is a bad idea, or returning an Option<T> (Option<Vec<T>>, not Vec<Option<T>>, since all the longitudes will be invalid in that case). Given that an out-of-bounds value indicates user error, I think that refusing to do the computation is totally fine in this case.

Another option might be to have RhumbCalculations::new return Option<Self> rather than Self since that's really where the error is caught. Since distances are finite even pole-to-pole, constructing a RhumbCalculations must be allowable at least over that range.

@apendleton
Copy link
Contributor

@joe-saronic sorry for the delay. Yes, I think you make a good case that clamping doesn't make sense here.

I think that refusing to do the computation is totally fine in this case

That makes sense, but I don't think the mechanism for refusing should be to panic. It's user error, but needn't be unrecoverable user error. I think Result or Option would be more appropriate here. And yeah, Option<Vec<T>> seems reasonable rather than Vec<Option<T>>.

@urschrei accepted the invite, thanks!

@urschrei urschrei requested a review from apendleton February 27, 2024 11:58
@joe-saronic
Copy link
Contributor Author

@apendleton I will update the PR shortly.

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

Successfully merging this pull request may close these issues.

Rhumb destinations do not wrap angles after the first pole intersection
3 participants