Example #1
0
 private static IEnumerable <Vector3> ArcVertices(IArc arc, IArc nextArc, Sweepline sweepline)
 {
     if (arc.LeftNeighbour == arc.Site)
     {
         var azimuths = DrawingUtilities.AnglesInRange(0, 2 * Mathf.PI, NumberOfVerticesPerArc);
         var vertices = azimuths.Select(azimuth => PointOnEllipse(arc, azimuth, sweepline)).ToList();
         return(vertices);
     }
     else if (Mathf.Approximately((float)arc.Site.Priority, (float)sweepline.Priority))
     {
         var intersection = arc.PointOfIntersection(sweepline).ToUnityVector3();
         var site         = arc.Site.Position.ToUnityVector3();
         var downArc      = DrawingUtilities.VerticesOnGeodesic(intersection, site, NumberOfVerticesPerArc);
         var upArc        = DrawingUtilities.VerticesOnGeodesic(site, intersection, NumberOfVerticesPerArc);
         var vertices     = downArc.Concat(upArc);
         return(vertices);
     }
     else
     {
         var leftLimit  = DrawingUtilities.AzimuthOf(arc.LeftIntersection(sweepline).ToUnityVector3());
         var rightLimit = DrawingUtilities.AzimuthOf(nextArc.LeftIntersection(sweepline).ToUnityVector3());
         var azimuths   = DrawingUtilities.AnglesInRange(leftLimit, rightLimit, NumberOfVerticesPerArc);
         var vertices   = azimuths.Select(azimuth => PointOnEllipse(arc, azimuth, sweepline)).ToList();
         return(vertices);
     }
 }
        public void LeftIntersection_WhenSweeplinePassesThroughLowerOfTheTwoFocii_ShouldReturnDirectionOfThatFocus
            (Arc arc, Sweepline sweepline)
        {
            arc.LeftNeighbour.Position = Utilities.VectorAt(114, 94);
            arc.Site.Position          = Utilities.VectorAt(96, 77);
            sweepline = Utilities.SweeplineAt(121);

            // Fixture setup
            var focus      = arc.Site.Position;
            var leftFocus  = arc.LeftNeighbour.Position;
            var lowerFocus = focus.Z < leftFocus.Z ? focus : leftFocus;

            var directionOfLowerFocus = AngleUtilities.EquatorialDirection(lowerFocus);

            sweepline.Z = lowerFocus.Z;

            // Exercise system
            var directionOfLeftIntersection = arc.LeftIntersection(sweepline);

            // Verify outcome
            var failureString = String.Format("Direction of left intersection: {0},\n",
                                              directionOfLeftIntersection);

            Assert.True(Vector.AlmostEqual(directionOfLowerFocus, directionOfLeftIntersection, Tolerance), failureString);

            // Teardown
        }
        public void LeftIntersection_WhenFociiAreAboveSweepline_ShouldReturnAVectorWhichWhenMappedToAPointOnTheArcIsEquidistantFromBothSites
            (Arc arc, Sweepline sweepline)
        {
            // Fixture setup
            var focus     = arc.Site.Position;
            var leftFocus = arc.LeftNeighbour.Position;

            // Exercise system
            var directionOfIntersection = arc.LeftIntersection(sweepline);
            var intersection            = arc.PointAt(directionOfIntersection, sweepline);

            // Verify outcome
            var distanceFromSite     = Trig.InverseCosine(focus.ScalarMultiply(intersection));
            var distanceFromLeftSite = Trig.InverseCosine(leftFocus.ScalarMultiply(intersection));

            var failureString = String.Format("Direction of intersection: {0},\n" +
                                              "Intersection: {1},\n" +
                                              "Distance from site: {2},\n" +
                                              "Distance from left site: {3}",
                                              directionOfIntersection, intersection, distanceFromSite, distanceFromLeftSite);

            Assert.True(Number.AlmostEqual(distanceFromSite, distanceFromLeftSite, Tolerance), failureString);

            // Teardown
        }
        public void LeftIntersection_OfLowerFocusWhenSweeplineIsBelowIt_ShouldBeInOrderLeftIntersectionThenSiteThenRightIntersection
            (Arc arc, Sweepline sweepline)
        {
            // Fixture setup
            var dualArc = new Arc {
                LeftNeighbour = arc.Site, Site = arc.LeftNeighbour
            };

            var lowerArc              = arc.Site.Position.Z < dualArc.Site.Position.Z ? arc : dualArc;
            var higherArc             = arc.Site.Position.Z >= dualArc.Site.Position.Z ? arc : dualArc;
            var directionOfLowerFocus = AngleUtilities.EquatorialDirection(lowerArc.Site.Position);

            // Exercise system
            var directionOfLeftIntersection  = lowerArc.LeftIntersection(sweepline);
            var directionOfRightIntersection = higherArc.LeftIntersection(sweepline);

            // Verify outcome
            var areInOrder = ArcOrderer.AreInOrder(directionOfLeftIntersection, directionOfLowerFocus, directionOfRightIntersection);

            var failureString = String.Format("Direction of left intersection: {0},\n" +
                                              "Direction of right intersection: {1},\n",
                                              directionOfLeftIntersection, directionOfRightIntersection);

            Assert.True(areInOrder, failureString);

            // Teardown
        }
Example #5
0
        private static GameObject InitializeSweeplineObject(Sweepline sweepline)
        {
            var vertices   = SweeplineVertices(sweepline);
            var gameObject = DrawingUtilities.CreateLineObject("Sweepline", vertices, "SweeplineMaterial");

            return(gameObject);
        }
Example #6
0
        private static Vector3 VertexOnSweepline(Sweepline sweepline, float azimuth)
        {
            var z = (float)sweepline.Z;

            var x = (float)Math.Sqrt(1 - z * z) * Mathf.Cos(azimuth);
            var y = (float)-Math.Sqrt(1 - z * z) * Mathf.Sin(azimuth);

            return(new Vector3(x, y, z));
        }
        public void Customize(IFixture fixture)
        {
            var randomZ          = (-1.0 + 2.0 * new Random().NextDouble());
            var randomColatitude = Trig.InverseCosine(randomZ);

            var sweepline = new Sweepline {
                Colatitude = randomColatitude
            };

            fixture.Inject(sweepline);
        }
Example #8
0
        private static Vector3[] SweeplineVertices(Sweepline sweepline)
        {
            if (Math.Abs(sweepline.Z) >= 1)
            {
                return(new Vector3[0]);
            }

            var azimuths = DrawingUtilities.AnglesInRange(0, 2 * Mathf.PI, NumberOfVertices);
            var vertices = azimuths.Select(azimuth => VertexOnSweepline(sweepline, azimuth)).ToArray();

            return(vertices);
        }
Example #9
0
        public static LinkedList <LineSegmentIntersection> FindIntersections(IEnumerable <DCEL_HalfEdge> lineSegments)
        {
            LinkedList <LineSegmentIntersection> result = new LinkedList <LineSegmentIntersection>();

            Sweepline sweepline = new Sweepline();
            RBTreeMap <EventPoint, LinkedList <Segment> > eventQueue = new RBTreeMap <EventPoint, LinkedList <Segment> >((x, y) => x.CompareTo(y));

            var segments = lineSegments.Where(lineSegment => lineSegment.Origin.Position != lineSegment.Destination.Position)
                           .Select(lineSegment => new Segment(lineSegment, sweepline));

            //segments = FixOverlappingSegments(segments);

            foreach (var segment in segments)
            {
                var node = eventQueue.Find(segment.Upper);
                LinkedList <Segment> upperList = (node != null ? node.Value : null);
                if (upperList == null)
                {
                    upperList = new LinkedList <Segment>();
                    eventQueue.Add(new RBTreeMapNode <EventPoint, LinkedList <Segment> >(new EventPoint(segment.Upper), upperList));
                }
                upperList.AddLast(segment);

                if (!eventQueue.ContainsKey(segment.Lower))
                {
                    eventQueue.Add(new RBTreeMapNode <EventPoint, LinkedList <Segment> >(new EventPoint(segment.Lower), new LinkedList <Segment>()));
                }
            }

            RBTreeSet <Segment> status = new RBTreeSet <Segment>((x, y) => x.CompareTo(y));

            while (eventQueue.Count > 0)
            {
                var pair = eventQueue.MinNode;
                eventQueue.RemoveMin();

                EventPoint           nextEventPoint = pair.Key;
                LinkedList <Segment> upperList      = pair.Value;

                LineSegmentIntersection reportedIntersection;
                HandleEventPoint(nextEventPoint, upperList, sweepline, eventQueue, status, out reportedIntersection);
                if (reportedIntersection != null)
                {
                    result.AddLast(reportedIntersection);
                }
            }

            return(result);
        }
        public void LeftIntersection_WhenLeftNeigbourIsSameAsArcSite_ShouldReturnDirectionOfFocus
            (Arc arc, Sweepline sweepline)
        {
            // Fixture setup
            arc.LeftNeighbour = arc.Site;
            var directionOfFocus = AngleUtilities.EquatorialDirection(arc.Site.Position);

            // Exercise system
            var directionOfLeftIntersection = arc.LeftIntersection(sweepline);

            // Verify outcome
            var failureString = String.Format("Direction of left intersection: {0},\n",
                                              directionOfLeftIntersection);

            Assert.True(Vector.AlmostEqual(directionOfFocus, directionOfLeftIntersection, Tolerance), failureString);

            // Teardown
        }
        public void PointAt_ShouldReturnAPointWithTheSameAzimuthAsTheArgument
            (Arc arc, Vector3 vector, Sweepline sweepline)
        {
            // Fixture setup

            // Exercise system
            var point = arc.PointAt(vector, sweepline);

            // Verify outcome
            var argumentAzimuth = Trig.InverseTangentFromRational(vector.Y, vector.X);
            var resultAzimuth   = Trig.InverseTangentFromRational(point.Y, point.X);

            var failureString = String.Format("Argument azimuth was {0} \nResult azimuth was {1}", argumentAzimuth, resultAzimuth);

            Assert.True(Number.AlmostEqual(argumentAzimuth, resultAzimuth, Tolerance), failureString);

            // Teardown
        }
        public void Vectors_ShouldAllBeAboveSweepline(List <Vector3> vectors, Sweepline anonymousSweepline)
        {
            // Fixture setup

            // Exercise system

            // Verify outcome
            var expectedResult = Trig.Cosine(anonymousSweepline.Colatitude);

            foreach (var vector in vectors)
            {
                var result = vector[2];

                var failureString = String.Format("Had Z {0}, expected Z was {1}", result, expectedResult);
                Assert.True(result >= expectedResult, failureString);
            }
            // Teardown
        }
        public void PointAt_ShouldReturnAPointEquidistantFromTheSweeplineAndTheFocus
            (Arc arc, Vector3 vector, Sweepline sweepline)
        {
            // Fixture setup
            var focus = arc.Site.Position;

            // Exercise system
            var point = arc.PointAt(vector, sweepline);

            // Verify outcome
            var distanceToFocus     = Trig.InverseCosine(point.ScalarMultiply(focus));
            var distanceToSweepline = Math.Abs(sweepline.Colatitude - Trig.InverseCosine(point.Z));

            var failureString = String.Format("Distance to focus was {0}\nDistance to sweepline was {1}", distanceToFocus, distanceToSweepline);

            Assert.True(Number.AlmostEqual(distanceToFocus, distanceToSweepline, Tolerance), failureString);

            // Teardown
        }
        public void PointAt_IfSweeplinePassesThroughFocusAndVectorIsNotAtSameAzimuthAsFocus_ShouldReturnNorthPole
            (Arc arc, Vector3 vector)
        {
            // Fixture setup
            var sweepline = new Sweepline {
                Z = arc.Site.Position.Z
            };
            var northPole = new Vector3(0, 0, 1);

            // Exercise system
            var point = arc.PointAt(vector, sweepline);

            // Verify outcome
            var failureString = String.Format("Point was {0}", point);

            Assert.True(Vector.AlmostEqual(northPole, point, Tolerance), failureString);

            // Teardown
        }
Example #15
0
            public Segment(DCEL_HalfEdge source, Sweepline sweepline)
            {
                Source = source;
                EventPoint origin      = new EventPoint(source.Origin);
                EventPoint destination = new EventPoint(source.Destination);
                int        comp        = origin.CompareTo(destination);

                if (comp < 0)
                {
                    Upper = origin;
                    Lower = destination;
                }
                else if (comp > 0)
                {
                    Upper = destination;
                    Lower = origin;
                }
                else
                {
                    throw new InvalidOperationException("Trivial line segment.");
                }
                Sweepline = sweepline;
            }
        public void LeftIntersection_WhenSweeplinePassesThroughBothFocuses_ShouldReturnEquatorialMidpointOfFocii
            (Arc arc, Sweepline sweepline)
        {
            // Fixture setup
            var colatitudeOfFocus  = arc.Site.Position.SphericalCoordinates().Colatitude;
            var azimuthOfFocus     = arc.Site.Position.SphericalCoordinates().Azimuth;
            var azimuthOfLeftFocus = arc.LeftNeighbour.Position.SphericalCoordinates().Azimuth;

            arc.Site.Position          = new SphericalCoords(colatitudeOfFocus, azimuthOfFocus).CartesianCoordinates();
            arc.LeftNeighbour.Position = new SphericalCoords(colatitudeOfFocus, azimuthOfLeftFocus).CartesianCoordinates();

            // Exercise system
            var directionOfLeftIntersection = arc.LeftIntersection(sweepline);

            // Verify outcome
            var equatorialMidpoint = AngleUtilities.EquatorialMidpoint(arc.LeftNeighbour.Position, arc.Site.Position);
            var failureString      = String.Format("Direction of left intersection: {0},\n",
                                                   directionOfLeftIntersection);

            Assert.True(Vector.AlmostEqual(equatorialMidpoint, directionOfLeftIntersection, Tolerance), failureString);

            // Teardown
        }
Example #17
0
        private static void HandleEventPoint(EventPoint eventPoint, LinkedList <Segment> upperList,
                                             Sweepline sweepline, RBTreeMap <EventPoint, LinkedList <Segment> > eventQueue, RBTreeSet <Segment> status, out LineSegmentIntersection reportedIntersection)
        {
            reportedIntersection = null;

            sweepline.IncidentEventPoint = eventPoint;
            sweepline.BeforeEventPoint   = true;

            //1.
            //upperList brought in as part of the input. None of its elements currently intersect the sweepline!

            //2.
            IEnumerable <Segment> middleList, lowerList;

            status.FindRange(Segment.CompareSweeplineIntersectionToCurrentEventPoint).Select(node => node.Key)
            .Partition(Segment.LowerIsCurrentEventPoint, out lowerList, out middleList);

            //3.
            if (upperList.Count + middleList.Count() + lowerList.Count() > 1)
            {
                //4.
                reportedIntersection = new LineSegmentIntersection(
                    eventPoint.Position,
                    upperList.Concat(middleList).Concat(lowerList).Select(segment => segment.Source));
            }

            //5.
            foreach (var lower in lowerList)
            {
                status.Remove(lower);
            }
            foreach (var middle in middleList)
            {
                status.Remove(middle);
            }

            sweepline.BeforeEventPoint = false;

            //6.

            foreach (var middle in middleList)
            {
                status.Add(new RBTreeSetNode <Segment>(middle));
            }

            foreach (var upper in upperList)
            {
                status.Add(new RBTreeSetNode <Segment>(upper));
            }


            //7.
            //Just a comment in the book

            //8.
            if (upperList.IsEmpty() && middleList.IsEmpty())
            {
                //9.
                var predecessorNode = status.FindMax(Segment.IntersectsSweeplineLeftOfEventPoint);
                var successorNode   = status.FindMin(Segment.IntersectsSweeplineRightOfEventPoint);

                //10.
                if (predecessorNode != null && successorNode != null)
                {
                    FindNewEvent(predecessorNode.Key, successorNode.Key, eventPoint, eventQueue);
                }
            }
            else
            {
                //11.
                var leftmostIntersectingNode = status.FindMin(Segment.IntersectsSweeplineRightOfEventPoint);

                //14.
                var rightmostIntersectingNode = status.FindMax(Segment.IntersectsSweeplineLeftOfEventPoint);

                //12.
                var leftmostPredecessorNode = leftmostIntersectingNode.Predecessor;

                //15.
                var rightmostSuccessorNode = rightmostIntersectingNode.Successor;

                //13.
                if (leftmostPredecessorNode != null)
                {
                    //RemoveFutureEvent(leftmostPredecessor, rightmostIntersecting, eventPoint, eventQueue);
                    FindNewEvent(leftmostPredecessorNode.Key, leftmostIntersectingNode.Key, eventPoint, eventQueue);
                }

                //16.
                if (rightmostSuccessorNode != null)
                {
                    //RemoveFutureEvent(leftmostIntersecting, rightmostSuccessor, eventPoint, eventQueue);
                    FindNewEvent(rightmostIntersectingNode.Key, rightmostSuccessorNode.Key, eventPoint, eventQueue);
                }
            }
        }
Example #18
0
 public SweeplineDrawer(Sweepline sweepline)
 {
     _sweepline  = sweepline;
     _gameObject = InitializeSweeplineObject(sweepline);
 }
Example #19
0
        public static Vector3 PointOnEllipse(IArc arc, float azimuth, Sweepline sweepline)
        {
            var direction = new Generator.Vector3(Trig.Cosine(azimuth), Trig.Sine(azimuth), 0);

            return(arc.PointAt(direction, sweepline).ToUnityVector3());
        }