-
Notifications
You must be signed in to change notification settings - Fork 189
Add incidentEdgeTracker and indexCellData types and tests #180
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
base: master
Are you sure you want to change the base?
Conversation
These are ports of the C++ s2/internal/ types that are needed for ValidationQuery for Loops and Polygons. Work for issues golang#72, golang#108.
Clean up some comments and variable names. Update some of the methods to match current C++ logic. Add more unit tests for multiloop polygons to validate that holes are inverted ordering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sending some initial thoughts since you've been waiting a while and some comments might need discussion. I'll look more tomorrow. Thanks for doing this!
@@ -0,0 +1,173 @@ | |||
// Copyright 2025 The S2 Geometry Project Authors. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume we need to resolve this discussion about what to do with Copyrights before proceeding: https://github.com/golang/geo/pull/178/files#r2094005567
|
||
package s2 | ||
|
||
// incidentEdgeKey is a tuple of (shape id, vertex) that compares by shape id. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: id -> ID throughout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
s2/incident_edge_tracker.go
Outdated
// shape's edges may be defined with multiple sequences of startShape(), | ||
// addEdge()... , finishShape() calls. | ||
// | ||
// The reason for this is simple: most edges don't have more than two incident |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this supposed to read "most vertices don't have more than two incident edges"? I'm having a hard time following these two paragraphs and I don't think it' s just my lack of subject-matter experience...
If we're OK with more divergence with the C++, I think it'd be clearer to make the 3rd paragraph about how we only look for vertices with 3 or more incident edges and that we don't remember vertices with fewer incident edges after a call to finishShape. Then in the 4th (and 5th if necessary) paragraph, I'd talk about how "a single shape's edges may be defined with multiple sequences..." as long as the caller ensures that all the edges on a given vertex are handled in the same sequence of calls via something like ShapeIndex cells.
But if you want to stick to correcting obvious errors, that seems like a very reasonable choice.
// adds it second endpoint as well. | ||
func (t *incidentEdgeTracker) addEdge(edgeID int32, e Edge) { | ||
if t.currentShapeID < 0 { | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error handling across these functions is pretty bad. Here, you silently drop edges. There's no checking to ensure that calls are made in the right sequence. Should we re-examine the API to make erroneous usage more difficult? All the internal calls to the C++ version look like:
incident_edge_tracker_.StartShape(shape_id);
for (const auto& edge : CurrentCell().shape_edges(shape_id)) {
incident_edge_tracker_.AddEdge(edge.id, edge);
}
incident_edge_tracker_.FinishShape();
So we could have an interface that looks like:
// Add all edges to the tracker. After calling, any vertices with multiple (> 2) incident
// edges will appear in the incident edge map. Returns an error if any edges have a different
// shape ID than shapeID.
func (t *incidentEdgeTracker) addShapeEdges(shapeID int32, edges []ShapeEdge) error
This would also remove the need for a "nursery" and the associated type, resolving one of my other comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, this should be a complete set of comments.
index string | ||
want int | ||
}{ | ||
// These shapeindex strings came from validation query's test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to align these tests with https://github.com/google/s2-geometry-library-java/blob/master/tests/tests/com/google/common/geometry/S2IncidentEdgeTrackerTest.java?
Co-authored-by: Alan Strohm <[email protected]>
Co-authored-by: Alan Strohm <[email protected]>
// A collection of Loops is similar, but not the same as a Polygon, so | ||
// from this creation method, we do not need to track Loop orientation | ||
// as hole or shell like Polygon does. | ||
func LaxPolygonFromLoops(loops []Loop) *LaxPolygon { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this function necessary? I'm not seeing a corresponding function in https://github.com/google/s2geometry/blob/master/src/s2/s2lax_polygon_shape.cc
if shape.Edge(edge.e) != (Edge{v0, v1}) { | ||
t.Errorf("sfsdaa") | ||
if got, want := shape.Edge(edge.e), (Edge{v0, v1}); got != want { | ||
t.Errorf("Shape Edge(%d) = %v, want %v", edge.e, got, want) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: shape.Edge
type shapeRegion struct { | ||
id int32 | ||
region indexCellRegion | ||
type shapeRange struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this one too generic? Would indexShapeRange
be better?
Add incidentEdgeTracker and indexCellData types and tests.
Update LaxPolygon to support proper vertex ordering on holes and shells.
Fix comments and variable names in LaxPolygon.
Add more of the missing LaxPolygon tests to validate fixes.
These are ports of the corresponding C++ s2/internal/ types that are needed for ValidationQuery for Loops and Polygons.
This PR works towards issues #72, #108.