@@ -57,6 +57,15 @@ type Polygon struct {
5757 // hasHoles tracks if this polygon has at least one hole.
5858 hasHoles bool
5959
60+ // hasInconsistentLoopOrientation is true if PolygonFromOrientedLoops() was
61+ // called and the given loops had inconsistent orientations (i.e., it is not
62+ // possible to construct a polygon such that the interior is on the left-hand
63+ // side of all loops). We need to remember this error so that it can be
64+ // returned later by Validate(), since it is not possible to detect this error
65+ // once the polygon has been initialized. This field is not preserved by
66+ // Encode/Decode.
67+ hasInconsistentLoopOrientations bool
68+
6069 // numVertices keeps the running total of all of the vertices of the contained loops.
6170 numVertices int
6271
@@ -180,6 +189,19 @@ func PolygonFromOrientedLoops(loops []*Loop) *Polygon {
180189 }
181190 }
182191
192+ // Verify that the original loops had consistent shell/hole orientations.
193+ // Each original loop L should have been inverted if and only if it now
194+ // represents a hole.
195+ for _ , l := range p .Loops () {
196+ if (containedOrigin [l ] != l .ContainsOrigin ()) != l .IsHole () {
197+ // There is no point in saving the loop index because the error is a
198+ // property of the entire set of loops. In general, there is no way to
199+ // determine which ones are incorrect.
200+ p .hasInconsistentLoopOrientations = true
201+ break
202+ }
203+ }
204+
183205 return p
184206}
185207
@@ -468,9 +490,9 @@ func (p *Polygon) Validate() error {
468490 // }
469491
470492 // Check whether initOriented detected inconsistent loop orientations.
471- // if p.hasInconsistentLoopOrientations {
472- // return fmt.Errorf("inconsistent loop orientations detected")
473- // }
493+ if p .hasInconsistentLoopOrientations {
494+ return fmt .Errorf ("inconsistent loop orientations detected" )
495+ }
474496
475497 // Finally, verify the loop nesting hierarchy.
476498 return p .findLoopNestingError ()
0 commit comments