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

Hint at what orientation means in the error message #144

Merged
merged 5 commits into from
Jul 21, 2024

Conversation

asinghvi17
Copy link
Contributor

@asinghvi17 asinghvi17 commented Jul 21, 2024

Small PR that changes the error text when you pass in e.g. boundary nodes with the wrong orientation. Feel free to close/edit if this doesn't make sense.

Should DelaunayTriangulation just reverse the order of points and go on with life?

@DanielVandH
Copy link
Member

The advice depends on whether the curve is contiguous or has multiple sections.

julia> v = [[1, 2, 3], [3, 4, 5], [5, 6, 1]];

julia> rev = [[1, 6, 5], [5, 4, 3], [3, 2, 1]];

julia> reverse(v) # the sections don't line up
3-element Vector{Vector{Int64}}:
 [5, 6, 1]
 [3, 4, 5]
 [1, 2, 3]

julia> reverse(reverse.(v)) == rev # need to reverse sections and the entire curve
true

julia> v_contiguous = [1, 2, 3, 4, 5, 1]; rev_contiguous = [1, 5, 4, 3, 2, 1];

julia> reverse(v_contiguous) == rev_contiguous # good
true

julia> reverse(reverse.(v_contiguous))
ERROR: MethodError: no method matching reverse(::Int64)
The function `reverse` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  reverse(::Base.AnnotatedString)
   @ Base strings\annotated.jl:318
  reverse(::SubString{<:Base.AnnotatedString})
   @ Base strings\annotated.jl:328
  reverse(::Base.Order.Ordering)
   @ Base ordering.jl:56
  ...

Stacktrace:
 [1] _broadcast_getindex_evalf
   @ .\broadcast.jl:673 [inlined]
 [2] _broadcast_getindex
   @ .\broadcast.jl:646 [inlined]
 [3] getindex
   @ .\broadcast.jl:605 [inlined]
 [4] copy
   @ .\broadcast.jl:906 [inlined]
 [5] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{…}, Nothing, typeof(reverse), Tuple{…}})
   @ Base.Broadcast .\broadcast.jl:867
 [6] top-level scope
   @ REPL[31]:1
Some type information was truncated. Use `show(err)` to see complete types.

So the advice needs to be

  • If the curve is contiguous, reverse(curve).
  • If the curve is made of multiple sections, reverse(reverse.(curve)).

@DanielVandH
Copy link
Member

DanielVandH commented Jul 21, 2024

We could pass whether the curve has multiple sections or not into the struct defining the error (see has_multiple_sections), or just breaking the advice into those two parts is probably fine..

Should DelaunayTriangulation just reverse the order of points and go on with life?

This is an option as well but I usually prefer not to modify the user's input at all and error instead. We could continue, but then there's a mismatch between their provided boundary nodes and those stored inside the Triangulation. I would also need to then add support for reversing the boundary nodes for general boundaries since they don't have to be vectors. It's easier to just error I think

If you do think that it would still be better to just flip the boundary for the user and then continue, maybe another approach is to define e.g.

function reverse_orientation(boundary_nodes)
if has_multiple_sections(boundary_nodes)
return reverse(reverse.(boundary_nodes))
elseif !has_multiple_curves(boundary_nodes)
return reverse(boundary_nodes)
end
throw(ArgumentError("Cannot reverse multiple curves at once."))
end

If reverse isn't defined for their definition of boundary_nodes this will just error anyway. You could then do a @warn (with maxlog=1 maybe) saying that the user's curve was incorrectly oriented and was flipped. If the user does have multiple curves though this is a bit annoying since we'd have to either mutate their original boundary nodes vector to put the reversed version in (so we need a set_curve! function or something) or copy it and then mutate.

Copy link

codecov bot commented Jul 21, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 94.57%. Comparing base (49a6580) to head (5eec7d0).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #144      +/-   ##
==========================================
- Coverage   94.59%   94.57%   -0.02%     
==========================================
  Files          94       94              
  Lines        9785     9792       +7     
==========================================
+ Hits         9256     9261       +5     
- Misses        529      531       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@DanielVandH DanielVandH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of this? Wanted to do the suggestion all as one big change but it wouldn't let me...

src/algorithms/triangulation/check_args.jl Show resolved Hide resolved
src/algorithms/triangulation/check_args.jl Outdated Show resolved Hide resolved
src/algorithms/triangulation/check_args.jl Outdated Show resolved Hide resolved
@asinghvi17
Copy link
Contributor Author

I didn't think of the impact on node order, it does make sense to simply error out then. Will implement a has_multiple_sections parameter in the error then!

asinghvi17 and others added 3 commits July 21, 2024 22:41
Co-authored-by: Daniel VandenHeuvel <95613936+DanielVandH@users.noreply.github.com>
Co-authored-by: Daniel VandenHeuvel <95613936+DanielVandH@users.noreply.github.com>
Co-authored-by: Daniel VandenHeuvel <95613936+DanielVandH@users.noreply.github.com>
@DanielVandH
Copy link
Member

Will implement a has_multiple_sections parameter in the error then!

This also turned out to be annoying since the error isn't actually look at the boundary nodes it's looking at the PolygonTree. We could change it to also take the boundary nodes but that's a bit of work

@@ -86,10 +86,11 @@ function Base.showerror(io::IO, err::InconsistentConnectionError)
end
function Base.showerror(io::IO, err::InconsistentOrientationError)
print(io, "InconsistentOrientationError: ")
str = " You can fix by passing the curve as `reverse(curve)` if the nodes are contiguous, or `reverse(reverse.(curve))` if it has multiple sections."
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
str = " You can fix by passing the curve as `reverse(curve)` if the nodes are contiguous, or `reverse(reverse.(curve))` if it has multiple sections."
str = " You can fix by passing the curve as `reverse(curve)` if the nodes are contiguous (i.e., a vector of indices), or `reverse(reverse.(curve))` if it has multiple sections (i.e., a vector of vectors of indices)."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this makes sense to you then feel free to merge!

@DanielVandH
Copy link
Member

Ahh actually this advice also doesn't really work for curve-bounded domains where reverse wouldn't really be defined... I will make some edits.

@DanielVandH
Copy link
Member

See what you think now @asinghvi17. Also added some tests.

@DanielVandH DanielVandH reopened this Jul 21, 2024
@asinghvi17
Copy link
Contributor Author

Looks good to me - thanks!

@DanielVandH DanielVandH merged commit c57ec4f into main Jul 21, 2024
11 of 18 checks passed
@DanielVandH DanielVandH deleted the as/orientation_error_message branch July 21, 2024 19:23
@DanielVandH
Copy link
Member

Thanks!

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.

2 participants