Skip to content

Commit

Permalink
msiner's golang#76 proposed to official package
Browse files Browse the repository at this point in the history
  • Loading branch information
Philiphil committed Nov 18, 2022
1 parent 66816e8 commit 2e4441f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
28 changes: 25 additions & 3 deletions s2/polygon.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ type Polygon struct {
// hasHoles tracks if this polygon has at least one hole.
hasHoles bool

// hasInconsistentLoopOrientation is true if PolygonFromOrientedLoops() was
// called and the given loops had inconsistent orientations (i.e., it is not
// possible to construct a polygon such that the interior is on the left-hand
// side of all loops). We need to remember this error so that it can be
// returned later by Validate(), since it is not possible to detect this error
// once the polygon has been initialized. This field is not preserved by
// Encode/Decode.
hasInconsistentLoopOrientations bool

// numVertices keeps the running total of all of the vertices of the contained loops.
numVertices int

Expand Down Expand Up @@ -180,6 +189,19 @@ func PolygonFromOrientedLoops(loops []*Loop) *Polygon {
}
}

// Verify that the original loops had consistent shell/hole orientations.
// Each original loop L should have been inverted if and only if it now
// represents a hole.
for _, l := range p.Loops() {
if (containedOrigin[l] != l.ContainsOrigin()) != l.IsHole() {
// There is no point in saving the loop index because the error is a
// property of the entire set of loops. In general, there is no way to
// determine which ones are incorrect.
p.hasInconsistentLoopOrientations = true
break
}
}

return p
}

Expand Down Expand Up @@ -468,9 +490,9 @@ func (p *Polygon) Validate() error {
// }

// Check whether initOriented detected inconsistent loop orientations.
// if p.hasInconsistentLoopOrientations {
// return fmt.Errorf("inconsistent loop orientations detected")
// }
if p.hasInconsistentLoopOrientations {
return fmt.Errorf("inconsistent loop orientations detected")
}

// Finally, verify the loop nesting hierarchy.
return p.findLoopNestingError()
Expand Down
9 changes: 9 additions & 0 deletions s2/polygon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,15 @@ func TestPolygonIsValidLoopNestingInvalid(t *testing.T) {
}
}

func TestPolygonIsValidInconsistentOrientations(t *testing.T) {
const iters = 1000

for iter := 0; iter < iters; iter++ {
loops := generatePolygonConcentricTestLoops(2+randomUniformInt(5), 3)
checkPolygonInvalid(t, "inconsistent loop orientations", loops, true, nil)
}
}

// TODO(roberts): Implement remaining validity tests.
// IsValidTests
// TestUnitLength
Expand Down

0 comments on commit 2e4441f

Please sign in to comment.