Implement shapeutil_visit_crossing_edge_pairs#135
Implement shapeutil_visit_crossing_edge_pairs#135missinglink wants to merge 1 commit intogolang:masterfrom
shapeutil_visit_crossing_edge_pairs#135Conversation
|
Worth noting an oddity between the CPP and Go implementations, the edge crossings |
jmr
left a comment
There was a problem hiding this comment.
We would like to add this functionality.
Can you explain your basic process for converting this? Is it a straightforward translation of the C++ code?
Where did you do something differently from C++?
| // VisitCrossingEdgePairs finds all crossing edge pairs in an index. | ||
| func VisitCrossingEdgePairs(index *ShapeIndex, crossingType CrossingType, visitor EdgePairVisitor) bool { | ||
| needAdjacent := crossingType == CrossingTypeAll | ||
| for it := index.Iterator(); !it.Done(); it.Next() { |
There was a problem hiding this comment.
I don't understand why this doesn't call VisitCrossings like the C++ does.
There was a problem hiding this comment.
Two lines below.
There was a problem hiding this comment.
It calls visitCrossings in a loop. Could this be a single call to VisitCrossings, like the C++ does? It looks like you're reimplementing VisitCrossings.
The main obstacle to a 1:1 port are CPP function overloading, this necessitates some function renaming as Golang doesn't support overloading. There are numerous differences, I'm not going to even try to list them all, most notably is the one I commented about above, different struct definitions between the two, use of pointers in CPP but values in Go, porting stdlib fiction calls, etc. Functionally the code is the same, you can probably ask an AI to summarize if you're not comfortable reviewing by eye. |
| crosser.RestartAt(b.Edge.V0) | ||
| } | ||
| sign := crosser.ChainCrossingSign(b.Edge.V1) | ||
| // missinglink: enum ordering is reversed compared to C++ |
There was a problem hiding this comment.
I'm not sure what to get out of "missinglink:"? Is this
// Note that enum ordering is reversed compared to C++
// TODO(missinglink): Make them match.
?
| } | ||
|
|
||
| func FindCrossingError(shape Shape, a, b ShapeEdge, isInterior bool) error { | ||
| ap := shape.ChainPosition(int(a.ID.EdgeID)) |
There was a problem hiding this comment.
Is there a reason not to have is_polygon in the error messages?
| polygon := makePolygon(tc.polygonStr, true) | ||
| testHasCrossingPermutations(t, polygon.loops, 0, tc.hasCrossing) | ||
| } | ||
| } |
There was a problem hiding this comment.
How do these test cases match up with the C++ coverage? I don't see a FindSelfIntersection test.
TEST(GetCrossingEdgePairs, NoIntersectionsOneIndex) {
TEST(GetCrossingEdgePairs, NoIntersectionsTwoIndexes) {
TEST(GetCrossingEdgePairs, EdgeGridOneIndex) {
TEST(GetCrossingEdgePairs, EdgeGridTwoIndexes) {
TEST(FindSelfIntersection, Basic) {
|
|
||
| import "fmt" | ||
|
|
||
| type ShapeEdgeVector []ShapeEdge |
There was a problem hiding this comment.
should be package private since it's only used in private methods
|
|
||
| import "fmt" | ||
|
|
||
| type ShapeEdgeVector []ShapeEdge |
There was a problem hiding this comment.
Go slice types of types should generally be named as the plural of the type. e.g. shapeEdges []ShapeEdge.
(also Vector is used through s2 already as an X,Y,Z object, so the name would be somewhat confusing that the defined type has no ShapeEdge but no Vector part.)
| return true | ||
| } | ||
|
|
||
| // Visits all pairs of crossing edges in the given S2ShapeIndex, terminating |
There was a problem hiding this comment.
https://go.dev/doc/comment#func
Func comments should start with the name of the function. (here and all others)
|
|
||
| type EdgePairVisitor func(a, b ShapeEdge, isInterior bool) bool | ||
|
|
||
| // getShapeEdges returns all edges in the given S2ShapeIndexCell. |
There was a problem hiding this comment.
Replace all C++ type names with the Go counterparts in comments.
e.g. S2ShapeIndexCell -> ShapeIndexCell
| return true | ||
| } | ||
|
|
||
| func FindCrossingError(shape Shape, a, b ShapeEdge, isInterior bool) error { |
There was a problem hiding this comment.
should be private and needs the corresponding doc comments from c++
| } | ||
| } | ||
|
|
||
| func testHasCrossingPermutations(t *testing.T, loops []*Loop, i int, hasCrossing bool) { |
There was a problem hiding this comment.
add the c++ function comments to this
| } | ||
|
|
||
| func TestGetCrossingEdgePairsGrid(t *testing.T) { | ||
| kGridSize := 10.0 |
| t.Errorf("Fail") | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
There are none of the two index versions of the tests. Can you add a TODO for them to be added?
|
|
||
| index.Add(&shape) | ||
| if len(getCrossingEdgePairsBruteForce(index, CrossingTypeAll)) != 112 { | ||
| t.Errorf("Fail") |
There was a problem hiding this comment.
error messages should be more descriptive than just 'fail'
| "testing" | ||
| ) | ||
|
|
||
| type EdgePair struct { |
| if isInterior { | ||
| if ap.ChainID != bp.ChainID { | ||
| return fmt.Errorf( | ||
| "Loop %d edge %d crosses loop %d edge %d", |
There was a problem hiding this comment.
Here and elsewhere: Error messages should start with lower-case, since they may be wrapped with more context (https://google.github.io/styleguide/go/decisions.html#error-strings)
| // However, the vertical lines do not reach the top line as it curves on the | ||
| // surface of the sphere: despite "epsilon" those 9 are not even very close | ||
| // to intersecting. Thus 9 * 12 = 108 interior and four more at the corners | ||
| // when CrossingType::ALL is used. |
| index.Add(polygon) | ||
|
|
||
| if hasCrossing != FindSelfIntersection(index) { | ||
| t.Error("Test failed: expected and actual crossing results do not match") |
There was a problem hiding this comment.
Idiomatic Go style is like
if got := FindSelfIntersection(index); got != hasCrossing {
t.Errorf("FindSelfIntersection got %v, want %v", got, hasCrossing)
}It would be nice to include something about the loops (FindSelfIntersection(%s)), though there isn't a loopToString textformat function yet.
This PR implements
shapeutil_visit_crossing_edge_pairswhich is required to resolve #108.If this is something you'd be interested in merging then let me know.
All the tests (so far) are passing, it just needs to be cleaned up a bit.