/// <summary> /// Forces the fill winding of the points within the ring. /// </summary> /// <param name="desiredWinding">The desired winding order to specify a fill region.</param> /// <remarks> /// If the current <see cref="Vertesaur.Ring2.Hole"/> property of this ring is <c>null</c> /// then the Hole property will be set if possible to the value corresponding to the given /// fill point winding. /// If the current <see cref="Vertesaur.Ring2.Hole"/> property of this ring is <c>true</c> /// or <c>false</c> then the points will be ordered if possible in a way to match the given /// fill point winding and hole property. /// <list type="bullet"> /// <item><term>Example 1</term><description> /// Hole is initially <c>null</c> and points are in CounterClockwise order. /// If <paramref name="desiredWinding"/> is Clockwise then Hole will then be set to <c>true</c> /// and the points will not be changed. /// </description></item> /// <item><term>Example 2</term><description> /// Hole is <c>false</c> and points are in Clockwise order. If <paramref name="desiredWinding"/> /// is CounterClockwise then the order of the points in the ring will be reversed. /// </description></item> /// </list> /// </remarks> public void ForceFillWinding(PointWinding desiredWinding) { if (PointWinding.Unknown == desiredWinding) { throw new ArgumentException("DesiredWinding may not be Unknown.", "desiredWinding"); } Contract.EndContractBlock(); var currentWinding = DetermineWinding(); if (PointWinding.Unknown == currentWinding) { return; } if (_hole.HasValue) { if ( (currentWinding != desiredWinding && !_hole.Value) || (currentWinding == desiredWinding && _hole.Value) ) { _pointList.Reverse(); } } else { _hole = (currentWinding != desiredWinding); } }
public IntersectionResults Turtle(PointWinding fillWinding) { Contract.Ensures(Contract.Result <IntersectionResults>() != null); // now that it is all sorted the turtle starts scooting around, making new rings: // // --== .-----. | ~ard // --== / \ | // A --== <_______(`~`) B | D E // ---*---------//-----//------*-------------*---*---------*--- // C | // | // // please wait while SPEED TURTLE!!! assembles your new rings var rings = new Polygon2(); PolygonCrossing startEntrance; while ((startEntrance = FindNextStartableEntrance()) != null) { var buildingRing = new List <Point2>(); var entrance = startEntrance; do { var exit = TraverseBSide(entrance, buildingRing); if (exit == null) { VisitEntrance(startEntrance); // may need to do this to be safe break; // unmatched entrance } VisitExit(exit); entrance = TraverseASide(exit, buildingRing); if (entrance == null) { break; // unmatched exit } VisitEntrance(entrance); } while (entrance != startEntrance); if (buildingRing.Count >= 3) { rings.Add(new Ring2(buildingRing)); // here is a new ring } } if (fillWinding != PointWinding.Unknown) { rings.ForceFillWinding(fillWinding); } return(BuildFinalResults(rings)); }
/// <summary> /// Forces the fill winding of the points within all contained rings to be uniform. /// </summary> /// <param name="desiredWinding">The desired winding order that defines a fill ring.</param> /// <seealso cref="Vertesaur.Ring2.ForceFillWinding"/> public void ForceFillWinding(PointWinding desiredWinding) { if (PointWinding.Unknown == desiredWinding) { throw new ArgumentException("desiredWinding may not be Unknown", "desiredWinding"); } Contract.EndContractBlock(); foreach (var ring in this) { Contract.Assume(ring != null); ring.ForceFillWinding(desiredWinding); } }
public IntersectionResults Turtle(PointWinding fillWinding) { Contract.Ensures(Contract.Result<IntersectionResults>() != null); // now that it is all sorted the turtle starts scooting around, making new rings: // // --== .-----. | ~ard // --== / \ | // A --== <_______(`~`) B | D E // ---*---------//-----//------*-------------*---*---------*--- // C | // | // // please wait while SPEED TURTLE!!! assembles your new rings var rings = new Polygon2(); PolygonCrossing startEntrance; while ((startEntrance = FindNextStartableEntrance()) != null) { var buildingRing = new List<Point2>(); var entrance = startEntrance; do { var exit = TraverseBSide(entrance, buildingRing); if (exit == null) { VisitEntrance(startEntrance); // may need to do this to be safe break; // unmatched entrance } VisitExit(exit); entrance = TraverseASide(exit, buildingRing); if (entrance == null) { break; // unmatched exit } VisitEntrance(entrance); } while (entrance != startEntrance); if (buildingRing.Count >= 3) rings.Add(new Ring2(buildingRing)); // here is a new ring } if (fillWinding != PointWinding.Unknown) rings.ForceFillWinding(fillWinding); return BuildFinalResults(rings); }