예제 #1
0
        private static Point2 FindNextRingPoint(
            PolygonCrossing currentCrossing,
            PolygonCrossing[] crossingsOnRing,
            Ring2 ring,
            Func <PolygonCrossing, PolygonBoundaryLocation> getLocation,
            IComparer <PolygonCrossing> crossingComparer
            )
        {
            Contract.Requires(currentCrossing != null);
            Contract.Requires(crossingsOnRing != null);
            Contract.Requires(Contract.ForAll(crossingsOnRing, x => x != null));
            Contract.Requires(ring != null);
            Contract.Requires(getLocation != null);
            Contract.Requires(crossingComparer != null);

            var currentLocation  = getLocation(currentCrossing);
            var segmentCount     = ring.SegmentCount;
            int nextSegmentIndex = IterationUtils.AdvanceLoopingIndex(currentLocation.SegmentIndex, segmentCount);
            var nextCrossing     = FindNextCrossingNotEqual(currentCrossing, crossingsOnRing, crossingComparer);

            // NOTE: this method assumes a segment ratio less than 1, verify we can trust this
            if (null == nextCrossing)
            {
                return(ring[nextSegmentIndex]);
            }
            var nextCrossingLocation = getLocation(nextCrossing);

            Contract.Assume(nextCrossingLocation != null);
            return(currentLocation.SegmentIndex == nextCrossingLocation.SegmentIndex &&
                   currentLocation.SegmentRatio < nextCrossingLocation.SegmentRatio
                ? nextCrossing.Point
                : ring[nextSegmentIndex]);
        }
예제 #2
0
        private static void AddPointsBetweenForward(
            List <Point2> results,
            Ring2 ring,
            PolygonBoundaryLocation from,
            PolygonBoundaryLocation to
            )
        {
            Contract.Requires(results != null);
            Contract.Requires(ring != null);
            Contract.Requires(from != null);
            Contract.Requires(to != null);
            Contract.Ensures(results.Count >= Contract.OldValue(results).Count);

            if (from.SegmentIndex == to.SegmentIndex && from.SegmentRatio <= to.SegmentRatio)
            {
                return; // no points will result from this
            }
            var segmentCount        = ring.SegmentCount;
            var currentSegmentIndex = IterationUtils.AdvanceLoopingIndex(from.SegmentIndex, segmentCount);

            do
            {
                if (to.SegmentIndex == currentSegmentIndex)
                {
                    if (to.SegmentRatio > 0)
                    {
                        results.Add(ring[currentSegmentIndex]);
                    }
                    return;
                }
                results.Add(ring[currentSegmentIndex]);
                currentSegmentIndex = IterationUtils.AdvanceLoopingIndex(currentSegmentIndex, segmentCount);
            } while (true);
        }
예제 #3
0
        public void redundant_endpoint() {
            var a = new Ring2(new[] { new Point2(0, 0), new Point2(1, 1), new Point2(1, 0) });
            var b = new Ring2(new[] { new Point2(0, 0), new Point2(1, 1), new Point2(1, 0), new Point2(0, 0) });

            Assert.False(a.HasRedundantEndPoint);
            Assert.True(b.HasRedundantEndPoint);
        }
예제 #4
0
 private static string RingToString(Ring2 ring) {
     var sb = new StringBuilder();
     foreach (var p in ring) {
         sb.AppendFormat("({0},{1})\n", p.X, p.Y);
     }
     return sb.ToString();
 }
예제 #5
0
        public void constructor_expected_size()
        {
            var ring = new Ring2(12);

            Assert.Empty(ring);
            Assert.Null(ring.Hole);
        }
예제 #6
0
        public void constructor_default()
        {
            var ring = new Ring2();

            Assert.Empty(ring);
            Assert.Null(ring.Hole);
        }
예제 #7
0
        static void Main(string[] args)
        {
            Console.WriteLine("Fact: " + (GeometryFactory2Double.Instance != null));
            GeometryFactory2Base <double> factory = GeometryFactory2Double.Instance;

            Console.WriteLine("Factory is " + (factory == null ? "null" : "not null"));

            if (factory != null)
            {
                Point2 <double> pt = factory.ConstructPoint(43, 22);
                Console.WriteLine("Created point: " + pt.ToString());
                Ring2 <double>    rg = factory.ConstructRing(new Point2 <double>[] { factory.ConstructPoint(22.45, 33.33), factory.ConstructPoint(23.45, 33.33), factory.ConstructPoint(22.45, 35.33) });
                Polygon2 <double> pl = factory.ConstructPolygon(rg);

                if (rg != null)
                {
                    Console.WriteLine("Created ring: " + rg.ToString());
                    object o = Osrs.Numerics.Spatial.Postgres.NpgSpatialUtils.ToPGis(rg);
                    Console.WriteLine("Created PG Geometry: " + (o != null).ToString());
                }

                if (pl != null)
                {
                    Console.WriteLine(GeoJsonUtils.ToGeoJson(pl).ToString());
                }
            }

            Console.WriteLine("ALL DONE");
            Console.ReadLine();
        }
예제 #8
0
 public void constructor_points() {
     var ring = new Ring2(new[] { new Point2(0, 0), new Point2(1, 0), new Point2(0, 1), new Point2(0, 0) });
     Assert.Equal(4, ring.Count);
     Assert.Equal(new Point2(0, 0), ring[0]);
     Assert.Equal(new Point2(1, 0), ring[1]);
     Assert.Equal(new Point2(0, 1), ring[2]);
     Assert.Equal(new Point2(0, 0), ring[3]);
 }
예제 #9
0
        public void redundant_endpoint()
        {
            var a = new Ring2(new[] { new Point2(0, 0), new Point2(1, 1), new Point2(1, 0) });
            var b = new Ring2(new[] { new Point2(0, 0), new Point2(1, 1), new Point2(1, 0), new Point2(0, 0) });

            Assert.False(a.HasRedundantEndPoint);
            Assert.True(b.HasRedundantEndPoint);
        }
예제 #10
0
        public void area()
        {
            var a = new Ring2(new[] { new Point2(0, 0), new Point2(1, 0), new Point2(0, 1), new Point2(0, 0) });
            var b = new Ring2(new[] { new Point2(0, 0), new Point2(1, 0), new Point2(0, 1), new Point2(0, 0) }, true);

            Assert.Equal(0.5, a.GetArea());
            Assert.Equal(-0.5, b.GetArea());
        }
예제 #11
0
 public void Add(Ring2 <T> ring)
 {
     if (ring == null)
     {
         return;
     }
     this.AddImpl(ring, ring.Points, true);
 }
예제 #12
0
 public void Add(Ring2 <T> ring, LeakyResizableArray <Node <T> > nodes, LeakyResizableArray <Edge <T> > edges)
 {
     if (ring == null)
     {
         return;
     }
     this.AddImpl(ring, ring.Points, true, nodes, edges);
 }
예제 #13
0
        private static IEnumerable <Node> BoundBy(IEnumerable <Node> nodes, Ring2 ring)
        {
            Contract.Requires(nodes != null);
            Contract.Requires(ring != null);
            Contract.Ensures(Contract.Result <IEnumerable <Node> >() != null);

            return(nodes.Where(n => RingIsNonIntersectingBoundBy(n.Ring, ring)));
        }
        private int[] GetSortedRingSegmentIndices(Ring2 ring)
        {
            Contract.Requires(null != ring);
            Contract.Ensures(Contract.Result <int[]>() != null);
            var result = _sortedRingSegmentIndices.GetOrAdd(ring, GenerateSortedRingSegmentIndices);

            Contract.Assume(result != null);
            return(result);
        }
예제 #15
0
        public void constructor_hole() {
            var fill = new Ring2(false);
            var hole = new Ring2(true);

            Assert.Empty(fill);
            Assert.Empty(hole);
            fill.Hole.Should().Be(false);
            hole.Hole.Should().Be(true);
        }
 private int[] GetSortedRingSegmentIndices(Ring2 ring)
 {
     int[] result;
     if (!_sortedRingSegmentIndices.TryGetValue(ring, out result))
     {
         result = GenerateSortedRingSegmentIndices(ring);
         _sortedRingSegmentIndices.Add(ring, result);
     }
     return(result);
 }
예제 #17
0
        private static string RingToString(Ring2 ring)
        {
            var sb = new StringBuilder();

            foreach (var p in ring)
            {
                sb.AppendFormat("({0},{1})\n", p.X, p.Y);
            }
            return(sb.ToString());
        }
예제 #18
0
        public void constructor_points()
        {
            var ring = new Ring2(new[] { new Point2(0, 0), new Point2(1, 0), new Point2(0, 1), new Point2(0, 0) });

            Assert.Equal(4, ring.Count);
            Assert.Equal(new Point2(0, 0), ring[0]);
            Assert.Equal(new Point2(1, 0), ring[1]);
            Assert.Equal(new Point2(0, 1), ring[2]);
            Assert.Equal(new Point2(0, 0), ring[3]);
        }
예제 #19
0
        public void constructor_hole()
        {
            var fill = new Ring2(false);
            var hole = new Ring2(true);

            Assert.Empty(fill);
            Assert.Empty(hole);
            fill.Hole.Should().Be(false);
            hole.Hole.Should().Be(true);
        }
 private static Ring2 ReverseWinding(Ring2 r)
 {
     if (null == r)
     {
         return(null);
     }
     return(r.Hole.HasValue
         ? new Ring2(r.Reverse(), r.Hole.Value)
         : new Ring2(r.Reverse()));
 }
예제 #21
0
 public static PostgisPolygon ToPGis(Ring2 <double> geom)
 {
     if (geom != null)
     {
         List <List <Coordinate2D> > pts = new List <List <Coordinate2D> >();
         pts.Add(Points((IEnumerable <Point2 <double> >)geom));
         pts[0].Add(pts[0][0]);
         return(new PostgisPolygon(pts));
     }
     return(null);
 }
예제 #22
0
 private void Start()
 {
     Ring1.SetActive(false);
     Ring2.SetActive(false);
     ExplanationText.SetActive(false);
     GongURestartButton.SetActive(false);
     h1StartPosition    = h1.GetComponent <Transform>().localPosition;
     h2StartPosition    = h2.GetComponent <Transform>().localPosition;
     Ring1StartPosition = Ring1.GetComponent <Transform>().localPosition;
     Ring2StartPosition = Ring2.GetComponent <Transform>().localPosition;
 }
 private List <PolygonCrossing> GenerateRingCrossings(Ring2 ringA, Ring2 ringB, int ringIndexA, int ringIndexB)
 {
     Contract.Requires(ringA != null);
     Contract.Requires(ringA.Count > 0);
     Contract.Requires(ringB != null);
     Contract.Requires(ringB.Count > 0);
     Contract.Requires(ringIndexA >= 0);
     Contract.Requires(ringIndexB >= 0);
     Contract.Ensures(Contract.Result <List <PolygonCrossing> >() != null);
     return(GenerateRingCrossingsBruteForce(ringA, ringB, ringIndexA, ringIndexB));
     //return GenerateRingCrossingsSorted(ringA, ringB, ringIndexA, ringIndexB);
 }
예제 #24
0
    IEnumerator Explanation()
    {
        yield return(new WaitForSeconds(1f));

        Ring1.SetActive(true);
        Ring2.SetActive(true);
        yield return(new WaitForSeconds(1.5f));

        ExplanationText.SetActive(true);
        yield return(new WaitForSeconds(1f));

        GongURestartButton.SetActive(true);
    }
예제 #25
0
            private bool NonIntersectingHolesContains(Ring2 other)
            {
                Contract.Requires(other != null);

                foreach (var node in _nodes)
                {
                    if (!other.NonIntersectingWithin(node.Ring))
                    {
                        return(node.Count > 0 && node.NonIntersectingContains(other));
                    }
                }
                return(Count > 0);
            }
예제 #26
0
            private bool NonIntersectingFillsContains(Ring2 other)
            {
                Contract.Requires(other != null);

                foreach (var node in _nodes)
                {
                    if (other.NonIntersectingWithin(node.Ring))
                    {
                        return(node.Count <= 0 || node.NonIntersectingContains(other));
                    }
                }
                return(false);
            }
예제 #27
0
        public void centroid()
        {
            var a = new Ring2(new[] {
                new Point2(0, 0),
                new Point2(1, 0),
                new Point2(1, .5),
                new Point2(.5, .5),
                new Point2(.5, .75),
                new Point2(0, .75)
            });

            Assert.Equal(new Point2(9 / 20.0, 13 / 40.0), a.GetCentroid());
        }
        private static int[] GenerateSortedRingSegmentIndices(Ring2 ring)
        {
            Contract.Requires(ring != null);
            Contract.Ensures(Contract.Result <int[]>() != null);

            var indices = new int[ring.Count];

            for (int i = 0; i < indices.Length; i++)
            {
                indices[i] = i;
            }
            indices.Sort((a, b) => Compare(a, b, ring));
            return(indices);
        }
        private static List <PolygonCrossing> GenerateRingCrossingsBruteForce(Ring2 ringA, Ring2 ringB, int ringIndexA, int ringIndexB)
        {
            Contract.Requires(ringA != null);
            Contract.Requires(ringA.Count > 0);
            Contract.Requires(ringB != null);
            Contract.Requires(ringB.Count > 0);
            Contract.Requires(ringIndexA >= 0);
            Contract.Requires(ringIndexB >= 0);
            Contract.Ensures(Contract.Result <List <PolygonCrossing> >() != null);

            var ringACount         = ringA.Count;
            var ringBCount         = ringB.Count;
            var segmentStartIndexA = ringACount - 1;
            var b         = ringA[segmentStartIndexA];
            var crossings = new List <PolygonCrossing>();

            for (int segmentEndIndexA = 0; segmentEndIndexA < ringACount; segmentStartIndexA = segmentEndIndexA++)
            {
                var a = b;
                b = ringA[segmentEndIndexA];
                var segmentDataA = new Segment2Data(
                    new Segment2(a, b),
                    segmentStartIndexA,
                    ringIndexA
                    );
                var segmentMbrA        = segmentDataA.Segment.GetMbr();
                var segmentStartIndexB = ringBCount - 1;
                var d = ringB[segmentStartIndexB];
                for (int segmentEndIndexB = 0; segmentEndIndexB < ringBCount; segmentStartIndexB = segmentEndIndexB++)
                {
                    var c = d;
                    d = ringB[segmentEndIndexB];
                    if (!segmentMbrA.Intersects(c, d))
                    {
                        continue;
                    }

                    AddPointCrossings(
                        crossings,
                        segmentDataA,
                        new Segment2Data(
                            new Segment2(c, d),
                            segmentStartIndexB,
                            ringIndexB
                            )
                        );
                }
            }
            return(crossings);
        }
예제 #30
0
 public void GongUSimulationReStart()
 {
     h1.transform.localPosition    = h1StartPosition;
     h2.transform.localPosition    = h2StartPosition;
     Ring1.transform.localPosition = Ring1StartPosition;
     Ring2.transform.localPosition = Ring2StartPosition;
     Ring1.SetActive(false);
     Ring2.SetActive(false);
     ExplanationText.SetActive(false);
     GongURestartButton.SetActive(false);
     e1.GetComponent <Animation>().Play();
     e2.GetComponent <Animation>().Play();
     Invoke("GongUSimulationStart", 2f);
 }
예제 #31
0
        private static Node FindParent(Ring2 ring, IEnumerable <Node> roots)
        {
            Contract.Requires(ring != null);
            Contract.Requires(roots != null);

            foreach (var node in roots)
            {
                if (RingIsNonIntersectingBoundBy(ring, node.Ring))
                {
                    return(FindParent(ring, node) ?? node);
                }
            }
            return(null);
        }
예제 #32
0
            /// <summary>
            /// Determines if the given ring which does not intersect the boundary of any node is contained within the nodes.
            /// </summary>
            /// <param name="other"></param>
            /// <returns>true if the ring with contained by the nodes.</returns>
            /// <remarks>
            /// The logic assumes the given ring does not intersect the boundary of any node within this collection or any node deeper in the tree.
            /// </remarks>
            public bool NonIntersectingContains(Ring2 other)
            {
                if (null == other)
                {
                    throw new ArgumentNullException("other");
                }
                Contract.EndContractBlock();

                var nodeHoleFlag = NodesAreHole;

                return(nodeHoleFlag.HasValue && nodeHoleFlag.Value // nodes are hole nodes?
                    ? NonIntersectingHolesContains(other)
                    : NonIntersectingFillsContains(other));
            }
 public RingCrossingGenerationTask(Ring2 ringA, Ring2 ringB, int ringIndexA, int ringIndexB)
 {
     Contract.Requires(ringA != null);
     Contract.Requires(ringA.Count > 0);
     Contract.Requires(ringIndexA >= 0);
     Contract.Requires(ringIndexA < ringA.Count);
     Contract.Requires(ringB != null);
     Contract.Requires(ringB.Count > 0);
     Contract.Requires(ringIndexB >= 0);
     Contract.Requires(ringIndexB < ringB.Count);
     RingA      = ringA;
     RingB      = ringB;
     RingIndexA = ringIndexA;
     RingIndexB = ringIndexB;
 }
예제 #34
0
 public void Dispose()
 {
     Armor.Dispose();
     MainHand.Dispose();
     OffHand.Dispose();
     Ring.Dispose();
     Ring2.Dispose();
     Amulet.Dispose();
     Helm.Dispose();
     Gloves.Dispose();
     Boots.Dispose();
     Belt.Dispose();
     Flasks.ForEach(vm => vm.Dispose());
     TreeJewels.ForEach(vm => vm.Dispose());
     ItemJewels.Values.Flatten().ForEach(vm => vm.Dispose());
 }
예제 #35
0
        public void segments() {
            var a = new Ring2(new[] { new Point2(0, 0), new Point2(1, 0), new Point2(0, 1), new Point2(0, 0) });
            var b = new Ring2();
            var c = new Ring2(new[] { new Point2(0, 0) });
            var d = new Ring2(new[] { new Point2(0, 0), new Point2(1, 1) });
            var e = new Ring2(new[] { new Point2(0, 0), new Point2(1, 1), new Point2(1, 0) });

            Assert.Equal(4, a.SegmentCount);
            Assert.Equal(new Segment2(new Point2(0, 0), new Point2(1, 0)), a.GetSegment(0));
            Assert.Equal(new Segment2(new Point2(1, 0), new Point2(0, 1)), a.GetSegment(1));
            Assert.Equal(new Segment2(new Point2(0, 1), new Point2(0, 0)), a.GetSegment(2));
            Assert.Equal(new Segment2(new Point2(0, 0), new Point2(0, 0)), a.GetSegment(3));
            Assert.Equal(0, b.SegmentCount);
            Assert.Equal(0, c.SegmentCount);
            Assert.Equal(1, d.SegmentCount);
            Assert.Equal(3, e.SegmentCount);
        }
        private static Point2 FindNextRingPoint(
            PolygonCrossing currentCrossing,
            PolygonCrossing[] crossingsOnRing,
            Ring2 ring,
            Func<PolygonCrossing, PolygonBoundaryLocation> getLocation,
            IComparer<PolygonCrossing> crossingComparer
        ) {
            Contract.Requires(currentCrossing != null);
            Contract.Requires(crossingsOnRing != null);
            Contract.Requires(Contract.ForAll(crossingsOnRing, x => x != null));
            Contract.Requires(ring != null);
            Contract.Requires(getLocation != null);
            Contract.Requires(crossingComparer != null);

            var currentLocation = getLocation(currentCrossing);
            var segmentCount = ring.SegmentCount;
            int nextSegmentIndex = IterationUtils.AdvanceLoopingIndex(currentLocation.SegmentIndex, segmentCount);
            var nextCrossing = FindNextCrossingNotEqual(currentCrossing, crossingsOnRing, crossingComparer);
            // NOTE: this method assumes a segment ratio less than 1, verify we can trust this
            if (null == nextCrossing) {
                return ring[nextSegmentIndex];
            }
            var nextCrossingLocation = getLocation(nextCrossing);
            Contract.Assume(nextCrossingLocation != null);
            return currentLocation.SegmentIndex == nextCrossingLocation.SegmentIndex
                && currentLocation.SegmentRatio < nextCrossingLocation.SegmentRatio
                ? nextCrossing.Point
                : ring[nextSegmentIndex];
        }
예제 #37
0
 public RingPairTestData(string name, Ring2 a, Ring2 b) {
     Name = name;
     A = a;
     B = b;
 }
        public static IEnumerable<RingPairTestData> GenerateRingPairTestData() {

            var cascadeBoxes = new RingPairTestData(
                "Cascade Boxes",
                new Ring2(false){
					new Point2(0,0),
					new Point2(1,0), 
					new Point2(1,1),
					new Point2(0,1)},
                new Ring2(false) {
					new Point2(0.5,0.5),
					new Point2(1.5,0.5), 
					new Point2(1.5,1.5),
					new Point2(0.5,1.5)}
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(1, .5),
					new Point2(.5, 1)
				}
            };
            yield return cascadeBoxes;

            yield return new RingPairTestData(
                "Cascade Boxes: fill and a hole",
                new Ring2(false){
					new Point2(0,0),
					new Point2(1,0), 
					new Point2(1,1),
					new Point2(0,1)},
                new Ring2(cascadeBoxes.B.Reverse(), true)
            ) {
                CrossingPoints = new List<Point2>(cascadeBoxes.CrossingPoints)
            };

            yield return new RingPairTestData(
                "Cascade Boxes: dual hole",
                new Ring2(cascadeBoxes.A.Reverse(), true),
                new Ring2(cascadeBoxes.B.Reverse(), true)
            ) {
                CrossingPoints = new List<Point2>(cascadeBoxes.CrossingPoints)
            };

            yield return new RingPairTestData(
                "Cascade Boxes: reverse winding A",
                new Ring2(cascadeBoxes.A.Reverse(), false),
                new Ring2(cascadeBoxes.B, false)
            ) {
                CrossingPoints = new List<Point2>(cascadeBoxes.CrossingPoints)
            };

            yield return new RingPairTestData(
                "Cascade Boxes: reverse winding B",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(cascadeBoxes.B.Reverse(), false)
            ) {
                CrossingPoints = new List<Point2>(cascadeBoxes.CrossingPoints)
            };

            yield return new RingPairTestData(
                "Cascade Boxes: reverse winding both",
                new Ring2(cascadeBoxes.A.Reverse(), false),
                new Ring2(cascadeBoxes.B.Reverse(), false)
            ) {
                CrossingPoints = new List<Point2>(cascadeBoxes.CrossingPoints)
            };

            yield return new RingPairTestData(
                "Cascade Boxes: left down box",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(new[]{
					new Point2(-.5,-.5),
					new Point2(.5,-.5),
					new Point2(.5,.5),
					new Point2(-.5,.5)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(.5,0),
					new Point2(0,.5)
				}
            };

            var leftTriangleInBox = new RingPairTestData(
                "Triangle In Box: side touch",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(new[]{
					new Point2(0,.25),
					new Point2(.75,.5),
					new Point2(0,.75)
				}, false)
            ) {
                CrossingPoints = new[] { new Point2(0, 0.25), new Point2(0, 0.75) }.ToList()
            };
            yield return leftTriangleInBox;

            yield return new RingPairTestData(
                "Triangle In Box: point touch",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(new[]{
					new Point2(0,.5),
					new Point2(.75,.25),
					new Point2(.75,.75)
				}, false)
            ) {
                CrossingPoints = new[] { new Point2(0, .5) }.ToList()
            };

            var triangleOverBox = new RingPairTestData(
                "Triangle Over Box: point segment through",
                new Ring2(leftTriangleInBox.A, false),
                new Ring2(new Ring2(new[]{
					new Point2(0,0),
					new Point2(.5,-.25),
					new Point2(.5,.25)
				}, false), false)
            ) {
                CrossingPoints = new[] { Point2.Zero, new Point2(0.5, 0) }.ToList()
            };
            yield return triangleOverBox;

            yield return new RingPairTestData(
                "Triangle Over Box: segment through",
                new Ring2(leftTriangleInBox.A, false),
                new Ring2(new Ring2(new[]{
					new Point2(0,.75),
					new Point2(-.25,.25),
					new Point2(.25,.25)
				}, false), false)
            ) {
                CrossingPoints = new[] { new Point2(0, .25), new Point2(0, .75) }.ToList()
            };

            var diamondInBox = new RingPairTestData(
                "Diamond In Box: two ends touch sides",
                new Ring2(new[]{
					new Point2(0,0),
					new Point2(1,0),
					new Point2(1,1),
					new Point2(0,1)
				}, false),
                new Ring2(new[]{
					new Point2(0,.5),
					new Point2(.5,.25),
					new Point2(1,.5),
					new Point2(.5,.75)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0, .5),
					new Point2(1, .5)
				}
            };
            yield return diamondInBox;

            var trapezoidInBox = new RingPairTestData(
                "Trapezoid In Box: touches side",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(new[]{
					new Point2(0,.6),
					new Point2(0,.4),
					new Point2(.5,.25),
					new Point2(.5,.75)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0, .6),
					new Point2(0, .4)
				}
            };
            yield return trapezoidInBox;

            yield return new RingPairTestData(
                "Trapezoid In Box: with crossing nub",
                new Ring2(trapezoidInBox.A, false),
                new Ring2(new[]{
					new Point2(0,.6),
					new Point2(-.5,.6),
					new Point2(-.5,.4),
					new Point2(0,.4),
					new Point2(.5,.25),
					new Point2(.5,.75)
				}, false)
            ) {
                CrossingPoints = trapezoidInBox.CrossingPoints.ToList()
            };

            var zThingInABox = new RingPairTestData(
                "Z-Thing in a Box",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(new[]{
					new Point2(0,.75),
					new Point2(0,.5),
					new Point2(.25,.5),
					new Point2(0,.25),
					new Point2(1,.25),
					new Point2(1,.5),
					new Point2(.75,.5),
					new Point2(1,.75)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0, .75),
					new Point2(0, .5),
					new Point2(0, .25),
					new Point2(1, .25),
					new Point2(1, .5),
					new Point2(1, .75),
				}
            };
            yield return zThingInABox;

            var stackedBoxes = new RingPairTestData(
                "Two Stacked Boxes",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(cascadeBoxes.A.Select(p => p.Add(Vector2.YUnit)), false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0, 1),
					new Point2(1, 1)
				}
            };
            yield return stackedBoxes;

            yield return new RingPairTestData(
                "Two Sunk In Boxes",
                new Ring2(stackedBoxes.A, false),
                new Ring2(stackedBoxes.A.Select(p => p.Add(new Vector2(0, 0.5))), false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0, 1),
					new Point2(0, .5),
					new Point2(1, .5),
					new Point2(1, 1)
				}
            };

            yield return new RingPairTestData(
                "Two Boxes Touching: with one side segment within another",
                new Ring2(stackedBoxes.A, false),
                new Ring2(new[]{
					new Point2(1,.25),
					new Point2(2,.25),
					new Point2(2,.75),
					new Point2(1,.75)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(1, .25),
					new Point2(1, .75)
				}
            };

            yield return new RingPairTestData(
                "One Box in Another: with one side segment within another",
                new Ring2(stackedBoxes.A, false),
                new Ring2(new[]{
					new Point2(0,.25),
					new Point2(.5,.25),
					new Point2(.5,.75),
					new Point2(0,.75)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0, .25),
					new Point2(0, .75)
				}
            };

            var sameRing = new Ring2(cascadeBoxes.A, false);
            yield return new RingPairTestData(
                "Same Boxes",
                sameRing,
                sameRing
            ) {
                CrossingPoints = sameRing.ToList()
            };

            yield return new RingPairTestData(
                "Equal Boxes",
                new Ring2(sameRing, false),
                new Ring2(sameRing, false)
            ) {
                CrossingPoints = sameRing.ToList()
            };

            yield return new RingPairTestData(
                "Geometrically Equal Boxes",
                new Ring2(sameRing, false),
                new Ring2(new[] { sameRing[2], sameRing[3], sameRing[0], sameRing[1] }, false)
            ) {
                CrossingPoints = sameRing.ToList()
            };

            yield return new RingPairTestData(
                "Boxes Overlapping: within one segment",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(new[]{
					new Point2(-.25,.25),
					new Point2(.25,.25),
					new Point2(.25,.75),
					new Point2(-.25,.75)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0, .25),
					new Point2(0, .75)
				}
            };

            yield return new RingPairTestData(
                "Boxes Overlapping: through two segments",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(new[]{
					new Point2(-.25,.25),
					new Point2(1.25,.25),
					new Point2(1.25,.75),
					new Point2(-.25,.75)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(1, .25),
					new Point2(1, .75),
					new Point2(0, .75),
					new Point2(0, .25)
				}
            };

            var topHalfBox = new Ring2(new[]{
				new Point2(0,.5),
				new Point2(1,.5),
				new Point2(1,1),
				new Point2(0,1)
			}, false);
            yield return new RingPairTestData(
                "Boxes Overlapping: top half",
                new Ring2(cascadeBoxes.A, false),
                topHalfBox
            ) {
                CrossingPoints = topHalfBox.ToList()
            };

            var innerRectangle = new Ring2(new[]{
				new Point2(0,.25),
				new Point2(1,.25),
				new Point2(1,.75),
				new Point2(0,.75)
			}, false);
            yield return new RingPairTestData(
                "Rectangle in Box: touching two sides",
                new Ring2(cascadeBoxes.A, false),
                innerRectangle
            ) {
                CrossingPoints = innerRectangle.ToList()
            };

            var fillInAnother = new RingPairTestData(
                "Nested: fill within another, not touching",
                new Ring2(cascadeBoxes.A, false),
                new Ring2(new[]{
					new Point2(.25,.25),
					new Point2(.75,.25),
					new Point2(.75,.75),
					new Point2(.25,.75)
				}, false)
            ) {
                CrossingPoints = new List<Point2>(0)
            };
            yield return fillInAnother;

            yield return new RingPairTestData(
                "Nested: hole within a hole, not touching",
                new Ring2(fillInAnother.A.Reverse(), true),
                new Ring2(fillInAnother.B.Reverse(), true)
            ) {
                CrossingPoints = new List<Point2>(0)
            };

            yield return new RingPairTestData(
                "Nested: hole within a fill, not touching",
                new Ring2(fillInAnother.A, false),
                new Ring2(fillInAnother.B.Reverse(), true)
            ) {
                CrossingPoints = new List<Point2>(0)
            };

            yield return new RingPairTestData(
                "Nested: fill within a hole, not touching",
                new Ring2(fillInAnother.A.Reverse(), true),
                new Ring2(fillInAnother.B, false)
            ) {
                CrossingPoints = new List<Point2>(0)
            };

            var diamondInDoubleDiamond = new RingPairTestData(
                "Diamond in Double Diamond: touching sides",
                new Ring2(new[]{
					new Point2(0.0,1.0),
					new Point2(1.0,0.0),
					new Point2(1.5,0.5),
					new Point2(2.0,0.0),
					new Point2(3.0,1.0),
					new Point2(2.0,2.0),
					new Point2(1.5,1.5),
					new Point2(1.0,2.0)
				}, false),
                new Ring2(new[]{
					new Point2(1.0,1.0),
					new Point2(2.0,0.0),
					new Point2(3.0,1.0),
					new Point2(2.0,2.0)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(2.0, 0.0),
					new Point2(3.0, 1.0),
					new Point2(2.0, 2.0),
					new Point2(1.5, 1.5),
					new Point2(1.5, 0.5)
				}
            };
            yield return diamondInDoubleDiamond;

            yield return new RingPairTestData(
                "Cascade Diamond",
                new Ring2(new[]{
					new Point2(1,0),
					new Point2(2,1),
					new Point2(1,2),
					new Point2(0,1)
				}, false),
                new Ring2(new[]{
					new Point2(2,0),
					new Point2(3,1),
					new Point2(2,2),
					new Point2(1,1)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(1.5, 1.5),
					new Point2(1.5, 0.5),
				}
            };

            var zigZag = new RingPairTestData(
                "Zig-zag Thing",
                new Ring2(new[]{
					new Point2(0,0),
					new Point2(.5,0),
					new Point2(.5,-.5),
					new Point2(1.5,-.5),
					new Point2(1.5,.5), 
					new Point2(.5,.5), 
					new Point2(1,1), 
					new Point2(0,1)
				}, false),
                new Ring2(cascadeBoxes.A, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(1, 1),
					new Point2(0, 1),
					new Point2(0, 0),
					new Point2(.5, 0),
					new Point2(1, .5),
				}
            };
            yield return zigZag;

            yield return new RingPairTestData(
                "Zig-zag Thing: holes",
                new Ring2(zigZag.A.Reverse(), true),
                new Ring2(cascadeBoxes.A.Reverse(), true)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(1, 1),
					new Point2(0, 1),
					new Point2(0, 0),
					new Point2(.5, 0),
					new Point2(1, .5),
				}
            };

            yield return new RingPairTestData(
                "Under Ledge",
                new Ring2(new[]{
					new Point2(1,1),
					new Point2(2,1),
					new Point2(2,2),
					new Point2(1,2)
				}, false),
                new Ring2(new[]{
					new Point2(3,0),
					new Point2(4,0),
					new Point2(4,4),
					new Point2(0,4),
					new Point2(0,3),
					new Point2(3,3)
				}, false)
            ) {
                CrossingPoints = new List<Point2>(0)
            };

            yield return new RingPairTestData(
                "Fuzzed: 1",
                new Ring2(new[]{
					new Point2(0.46987951807228917,0.40367346938775517),
					new Point2(0.44987951807228915,0.38367346938775515),
					new Point2(0.46987951807228917,0.36367346938775513),
					new Point2(0.47074010327022375,0.36453405458568972),
					new Point2(0.47160068846815834,0.36367346938775513),
					new Point2(0.49160068846815835,0.38367346938775515),
					new Point2(0.47160068846815834,0.40367346938775517),
					new Point2(0.47074010327022375,0.40281288418982059)
				}, false),
                new Ring2(new[]{
					new Point2(0.49160068846815835,0.38367346938775515),
					new Point2(0.47160068846815834,0.40367346938775517),
					new Point2(0.45160068846815832,0.38367346938775515),
					new Point2(0.47160068846815834,0.36367346938775513)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0.47074010327022375,0.40281288418982059),
					new Point2(0.47074010327022375,0.36453405458568972),
					new Point2(0.47160068846815834,0.36367346938775513),
					new Point2(0.49160068846815835,0.38367346938775515),
					new Point2(0.47160068846815834,0.40367346938775517),


				}
            };

            yield return new RingPairTestData(
                "Fuzzed: 2",
                new Ring2(new[]{
					new Point2(0.45611015490533563,0.44857142857142862),
					new Point2(0.43611015490533561,0.4285714285714286),
					new Point2(0.45611015490533563,0.40857142857142859),
					new Point2(0.47611015490533565,0.4285714285714286),
					new Point2(0.4742291615441358,0.43045242193262845)
				}, false),
                new Ring2(new[]{
					new Point2(0.47611015490533565,0.4285714285714286),
					new Point2(0.45611015490533563,0.44857142857142862),
					new Point2(0.43611015490533561,0.4285714285714286),
					new Point2(0.45611015490533563,0.40857142857142859)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0.45611015490533563,0.44857142857142862),
					new Point2(0.43611015490533561,0.4285714285714286),
					new Point2(0.45611015490533563,0.40857142857142859),
					new Point2(0.47611015490533565,0.4285714285714286),
					new Point2(0.4742291615441358,0.43045242193262845),
				}
            };

            yield return new RingPairTestData(
                "Fuzzed: 3",
                new Ring2(new[]{
					new Point2(0.5025817555938038	,0.51387755102040822	),
					new Point2(0.48258175559380379	,0.4938775510204082	),
					new Point2(0.5025817555938038	,0.47387755102040818	),
					new Point2(0.50344234079173833	,0.47473813621834277	),
					new Point2(0.504302925989673	,0.47387755102040818	),
					new Point2(0.50516351118760761	,0.47473813621834277	),
					new Point2(0.50602409638554213	,0.47387755102040818	),
					new Point2(0.52602409638554215	,0.4938775510204082	),
					new Point2(0.50602409638554213	,0.51387755102040822	),
					new Point2(0.50516351118760761	,0.51301696582247358	),
					new Point2(0.504302925989673	,0.51387755102040822	),
					new Point2(0.50344234079173833	,0.51301696582247369	)
				}, false),
                new Ring2(new[]{
					new Point2(0.52602409638554215	,0.4938775510204082	),
					new Point2(0.50602409638554213	,0.51387755102040822	),
					new Point2(0.48602409638554211	,0.4938775510204082	),
					new Point2(0.50602409638554213	,0.47387755102040818	)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0.50516351118760761	,0.47473813621834277	),
					new Point2(0.50602409638554213	,0.47387755102040818	),
					new Point2(0.52602409638554215	,0.4938775510204082	),
					new Point2(0.50602409638554213	,0.51387755102040822	),
					new Point2(0.50516351118760761	,0.51301696582247358	),
				}
            };

            yield return new RingPairTestData(
                "Fuzzed: 4",
                new Ring2(new[]{
					new Point2(0.42578313253012046,0.44489795918367347),
					new Point2(0.44492254733218589,0.42575854438160804),
					new Point2(0.46406196213425133,0.44489795918367347),
					new Point2(0.44492254733218589,0.46403737398573891)
				}, false),
                new Ring2(new[]{
					new Point2(0.46406196213425133,0.44489795918367347),
					new Point2(0.44406196213425131,0.46489795918367349),
					new Point2(0.42406196213425129,0.44489795918367347),
					new Point2(0.44406196213425131,0.42489795918367346)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
                    new Point2(0.44492254733218589,0.46403737398573891),
					new Point2(0.44492254733218589,0.42575854438160804),
					new Point2(0.46406196213425133,0.44489795918367347),
				}
            };

            yield return new RingPairTestData(
                "Fuzzed: 5",
                new Ring2(new[]{
					new Point2(0.32874354561101549,0.36979591836734693),
					new Point2(0.3487435456110155,0.38979591836734695),
					new Point2(0.32874354561101549,0.40979591836734697),
					new Point2(0.3278829604130809,0.40893533316941238),
					new Point2(0.32702237521514632,0.40979591836734697),
					new Point2(0.3070223752151463,0.38979591836734695),
					new Point2(0.32702237521514632,0.36979591836734693),
					new Point2(0.3278829604130809,0.37065650356528151)
				}, false),
                new Ring2(new[]{
					new Point2(0.34702237521514634,0.38979591836734695),
					new Point2(0.32702237521514632,0.40979591836734697),
					new Point2(0.3070223752151463,0.38979591836734695),
					new Point2(0.32702237521514632,0.36979591836734693)
				}, false)
            ) {
                CrossingPoints = new List<Point2> {
					new Point2(0.3278829604130809,0.40893533316941238),
					new Point2(0.32702237521514632,0.40979591836734697),
					new Point2(0.3070223752151463,0.38979591836734695),
					new Point2(0.32702237521514632,0.36979591836734693),
					new Point2(0.3278829604130809,0.37065650356528151)
				}
            };

        }
        private static Point2 FindPreviousRingPoint(
            PolygonCrossing currentCrossing,
            PolygonCrossing[] crossingsOnRing,
            Ring2 ring,
            Func<PolygonCrossing, PolygonBoundaryLocation> getLocation,
            IComparer<PolygonCrossing> crossingComparer
        ) {
            Contract.Requires(currentCrossing != null);
            Contract.Requires(crossingsOnRing != null);
            Contract.Requires(Contract.ForAll(crossingsOnRing, x => x != null));
            Contract.Requires(ring != null);
            Contract.Requires(getLocation != null);
            Contract.Requires(crossingComparer != null);

            var currentLocation = getLocation(currentCrossing);
            var segmentCount = ring.SegmentCount;
            Contract.Assume(currentLocation.SegmentIndex < segmentCount);
            var previousSegmentIndex = IterationUtils.RetreatLoopingIndex(currentLocation.SegmentIndex, segmentCount);
            var previousCrossing = FindPreviousCrossingNotEqual(currentCrossing, crossingsOnRing, crossingComparer);
            if (null == previousCrossing) {
                return ring[
                    currentLocation.SegmentRatio == 0
                    ? previousSegmentIndex
                    : currentLocation.SegmentIndex
                ];
            }
            var previousCrossingLocation = getLocation(previousCrossing);
            Contract.Assume(previousCrossingLocation != null);
            if (currentLocation.SegmentRatio == 0) {
                return previousSegmentIndex == previousCrossingLocation.SegmentIndex
                    ? previousCrossing.Point
                    : ring[previousSegmentIndex];
            }
            return currentLocation.SegmentIndex == previousCrossingLocation.SegmentIndex
                && currentLocation.SegmentRatio > previousCrossingLocation.SegmentRatio
                ? previousCrossing.Point
                : ring[currentLocation.SegmentIndex];
        }
예제 #40
0
        public void winding_detection() {
            var a = new Ring2(new[] {
				new Point2(0,0), 
				new Point2(1,0), 
				new Point2(1,.5), 
				new Point2(.5,.5), 
				new Point2(.5,.75), 
				new Point2(0,.75)});
            var b = new Ring2(new[] { new Point2(0, 1), new Point2(1, 0), new Point2(0, 0) });
            var c = new Ring2(new[] { new Point2(0, 0) });
            var d = new Ring2(true);
            var e = new Ring2(false);
            var f = new Ring2();

            Assert.Equal(PointWinding.CounterClockwise, a.DetermineWinding());
            Assert.Equal(PointWinding.Clockwise, b.DetermineWinding());
            Assert.Equal(PointWinding.Unknown, c.DetermineWinding());
            Assert.Equal(PointWinding.Unknown, d.DetermineWinding());
            Assert.Equal(PointWinding.Unknown, e.DetermineWinding());
            Assert.Equal(PointWinding.Unknown, f.DetermineWinding());
        }
        private static void AddPointsBetweenForward(
            List<Point2> results,
            Ring2 ring,
            PolygonBoundaryLocation from,
            PolygonBoundaryLocation to
        ) {
            Contract.Requires(results != null);
            Contract.Requires(ring != null);
            Contract.Requires(from != null);
            Contract.Requires(to != null);
            Contract.Ensures(results.Count >= Contract.OldValue(results).Count);

            if (from.SegmentIndex == to.SegmentIndex && from.SegmentRatio <= to.SegmentRatio)
                return; // no points will result from this

            var segmentCount = ring.SegmentCount;
            var currentSegmentIndex = IterationUtils.AdvanceLoopingIndex(from.SegmentIndex, segmentCount);
            do {
                if (to.SegmentIndex == currentSegmentIndex) {
                    if (to.SegmentRatio > 0) {
                        results.Add(ring[currentSegmentIndex]);
                    }
                    return;
                }
                results.Add(ring[currentSegmentIndex]);
                currentSegmentIndex = IterationUtils.AdvanceLoopingIndex(currentSegmentIndex, segmentCount);
            } while (true);
        }
 /// <summary>
 /// Inverts a ring.
 /// </summary>
 /// <param name="ring">The ring to get the inverse of.</param>
 /// <returns>An inverted polygon.</returns>
 public static Ring2 Invert(Ring2 ring) {
     Contract.Ensures(ring == null ? Contract.Result<Ring2>() == null : Contract.Result<Ring2>() != null);
     return null == ring ? null : ring.GetInverse();
 }
예제 #43
0
        public void constructor_expected_size() {
            var ring = new Ring2(12);

            Assert.Empty(ring);
            Assert.Null(ring.Hole);
        }
예제 #44
0
        public void magnitude_or_perimeter() {
            var a = new Ring2(new[] { new Point2(0, 0), new Point2(1, 0), new Point2(0, 1), new Point2(0, 0) });

            Assert.Equal(2 + System.Math.Sqrt(2), a.GetMagnitude());
        }
예제 #45
0
        public void centroid() {
            var a = new Ring2(new[] {
				new Point2(0,0), 
				new Point2(1,0), 
				new Point2(1,.5), 
				new Point2(.5,.5), 
				new Point2(.5,.75), 
				new Point2(0,.75)});

            Assert.Equal(new Point2(9 / 20.0, 13 / 40.0), a.GetCentroid());
        }
예제 #46
0
        public void area () {
            var a = new Ring2(new[] { new Point2(0, 0), new Point2(1, 0), new Point2(0, 1), new Point2(0, 0) });
            var b = new Ring2(new[] { new Point2(0, 0), new Point2(1, 0), new Point2(0, 1), new Point2(0, 0) }, true);

            Assert.Equal(0.5, a.GetArea());
            Assert.Equal(-0.5, b.GetArea());
        }
예제 #47
0
        public void constructor_default() {
            var ring = new Ring2();

            Assert.Empty(ring);
            Assert.Null(ring.Hole);
        }
 private static Ring2 ReverseWinding(Ring2 r) {
     if (null == r)
         return null;
     return r.Hole.HasValue
         ? new Ring2(r.Reverse(), r.Hole.Value)
         : new Ring2(r.Reverse());
 }