예제 #1
0
        public void RayToRayCovergentNonOverlapping()
        {
            Ray2D ray1 = new Ray2D(new Point2D(0.0, 0.0), new Direction2D(0.0, 1.0));
            Ray2D ray2 = new Ray2D(new Point2D(-1.0, -2.0), new Direction2D(1.0, 1.0));

            Point2D result;

            Intersector.Intersection intersection = Intersector.Intersect(ray1, ray2, out result);
            Assert.AreEqual(Intersector.Intersection.DontIntersect, intersection);
        }
예제 #2
0
        public void RayToRayParallelIntersect()
        {
            Ray2D ray1 = new Ray2D(new Point2D(0.0, 0.0), new Direction2D(0.0, 1.0));
            Ray2D ray2 = new Ray2D(new Point2D(1.0, 0.0), new Direction2D(0.0, 1.0));

            Point2D result;

            Intersector.Intersection intersection = Intersector.Intersect(ray1, ray2, out result);
            Assert.AreEqual(Intersector.Intersection.DontIntersect, intersection);
        }
예제 #3
0
        public void SegmentToSegmentParallel()
        {
            Segment2D segment1 = new Segment2D(new Point2D(0.0, 0.0), new Point2D(1.0, 0.0));
            Segment2D segment2 = new Segment2D(new Point2D(0.0, 1.0), new Point2D(1.0, 1.0));

            Point2D result;

            Intersector.Intersection intersection = Intersector.Intersect(segment1, segment2, out result);
            Assert.AreEqual(Intersector.Intersection.DontIntersect, intersection);
        }
예제 #4
0
        public void RayToLineDiverging()
        {
            Ray2D  ray  = new Ray2D(new Point2D(0.0, 0.0), new Direction2D(-1.0, 1.0));
            Line2D line = new Line2D(new Point2D(1.0, 0.0), new Point2D(1.0, 1.0));

            Point2D result;

            Intersector.Intersection intersection = Intersector.Intersect(ray, line, out result);
            Assert.AreEqual(Intersector.Intersection.DontIntersect, intersection);
        }
예제 #5
0
        public void RayToRayGlancing()
        {
            Ray2D rayA = new Ray2D(new Point2D(4.0, 0.0), new Direction2D(-1.0, -1.0));
            Ray2D rayB = new Ray2D(new Point2D(2.0, 2.0), new Direction2D(0.0, -Math.Sqrt(2.0)));

            Point2D result;

            Intersector.Intersection intersection = Intersector.Intersect(rayA, rayB, out result);
            Assert.AreEqual(Intersector.Intersection.DoIntersect, intersection);
            Assert.AreEqual(new Point2D(2.0, -2.0), result);
        }
예제 #6
0
        public void IntersectingBug1()
        {
            Segment2D[] red = { new Segment2D(new Point2D(384450, 7171260), new Point2D(384450, 7171380)) };

            var one   = new Segment2D(new Point2D(393160.294372512, 7169290.29437251), new Point2D(393103.309524418, 7169266.69047558));
            var two   = new Segment2D(new Point2D(392970, 7169820), new Point2D(392970, 7169240.58874503));
            var three = new Segment2D(new Point2D(392899.705627487, 7169220), new Point2D(393967.645019878, 7169662.35498012));

            Segment2D[] blue = { one, two, three };

            Point2D?result = Intersector.Intersect(two, three);

            var rbi = new RedBlueIntersector(red, blue);
        }
예제 #7
0
        public void RayToRayOrderIndependence2()
        {
            Ray2D rayA = new Ray2D(new Point2D(0.0, 0.0), new Direction2D(0.0, 1.0));
            Ray2D rayB = new Ray2D(new Point2D(2.0, 1.0), new Direction2D(1.0, 1.0));

            Point2D resultAB;

            Intersector.Intersection intersectionAB = Intersector.Intersect(rayA, rayB, out resultAB);

            Point2D resultBA;

            Intersector.Intersection intersectionBA = Intersector.Intersect(rayB, rayA, out resultBA);

            Assert.AreEqual(intersectionAB, intersectionBA);
            Assert.AreEqual(resultAB, resultBA);
        }
예제 #8
0
        /// <summary>
        /// Compute the intersections of the bisector of the supplied node with the bisectors starting
        /// from the neightbour vertices in the LAV. Store the nearest intersection (if it exists) in the
        /// priority queue.
        /// </summary>
        /// <param name="lav">The List of Active Vertices</param>
        /// <param name="node">The node at the origin of the bisector to be intersected.</param>
        private void EnqueueNearestBisectorIntersection(CircularLinkedList <Vertex> lav, CircularLinkedListNode <Vertex> node)
        {
            // TODO: Retrieve the the lav using node.List
            // Find intersection with previous bisector
            // TODO: For some unknown reason the ternary operator does not work for the following expression
            Point2D?previousIntersection = null;

            if (node.Previous != null)
            {
                previousIntersection = Intersector.Intersect(node.Value.Bisector, node.Previous.Value.Bisector);
            }

            // Find intersection with next bisector
            // TODO: For some unknown reason the ternary operator does not work for the following expression
            Point2D?nextIntersection = null;

            if (node.Next != null)
            {
                nextIntersection = Intersector.Intersect(node.Value.Bisector, node.Next.Value.Bisector);
            }

            // Find intersection with "opposite" bisector at point B
            Point2D?oppositeIntersection = null;

            if (IsReflex(node.Value))
            {
                oppositeIntersection = OppositeIntersection(lav, node.Value);
            }

            double?previousDistance2 = previousIntersection.HasValue ? (previousIntersection.Value - node.Value.Bisector.Source).Magnitude2 : (double?)null;
            double?nextDistance2     = nextIntersection.HasValue ? (nextIntersection.Value - node.Value.Bisector.Source).Magnitude2 : (double?)null;
            double?oppDistance2      = oppositeIntersection.HasValue ? (oppositeIntersection.Value - node.Value.Bisector.Source).Magnitude2 : (double?)null;


            if (IsMinimum(previousDistance2, nextDistance2, oppDistance2))
            {
                EnqueuePreviousIntersection(node, previousIntersection.Value);
            }
            else if (IsMinimum(nextDistance2, previousDistance2, oppDistance2))
            {
                EnqueueNextIntersection(node, nextIntersection.Value);
            }
            else if (IsMinimum(oppDistance2, previousDistance2, nextDistance2))
            {
                EnqueueOppIntersection(node, oppositeIntersection.Value);
            }
        }
예제 #9
0
        /// <summary>
        /// Determination of the co-ordinates of point B
        ///
        /// Point B can be characterized as having the same perpendicular distance to the straight line carrying
        /// the "opposite" line segment to the vertex V and from both straight lines containing the line segments
        /// starting at the vertex V. We have to find such an "opposite" line segment.
        ///
        /// We traverse all line segments e of the original polygon [polyline] and test them whether they can be
        /// "opposite" line segments. Unfortunately, a simple test of the intersection between a bisector starting
        /// at V and the currently tested line segment cannot be used.  We have to test the intersection with the
        /// line holding the edge ei and by the bisectors bi and bi+1 leading from vertices at both ends of this
        /// line segment.
        /// </summary>
        /// <param name="lav"></param>
        /// <param name="vertex"></param>
        /// <returns></returns>
        private static Point2D?OppositeIntersection(CircularLinkedList <Vertex> lav, Vertex vertex)
        {
            double  minDistance2 = Double.MaxValue;
            Point2D?minIncenter  = null;

            // Project the supporting the edges starting at V (node) as rays
            Ray2D inRay  = new Ray2D(vertex.inEdge.target.Position, new Direction2D(vertex.inEdge.Vector));
            Ray2D outRay = new Ray2D(vertex.outEdge.source.Position, new Direction2D(-vertex.outEdge.Vector));

            // Ignore cases where the in and out edges are collinear.
            if (!inRay.SupportingLine.IsParallelTo(outRay.SupportingLine))
            {
                lav.ForEachPair(delegate(Vertex oppA, Vertex oppB)
                {
                    // Ignore testing againt the in and out edges of V
                    if (oppA == vertex || oppB == vertex)
                    {
                        return;
                    }

                    // Simple intersection test between the bisector starting at V and the (whole) line containing the
                    // currently tested line segment ei rejects the line segments laying "behind" the vertex V. We then compute
                    // the co-ordinates of the candidate point Bi as the intersection between the bisector at V and the axis [bisector]
                    // of the angle between of the edges starting at V and the tested line segment ei. Simple check should be performed
                    // to exclude the case where one of the line segments starting at V us parallel to ei. The resulting point B
                    // is selected from all the candidates Bi as the nearest point to the vertex V

                    // TODO: Performance: How much code can be factored out of this loop?

                    // TODO: Do we need to prevent testing against the in and out edges of V?
                    // and the candiate "opposite" line
                    Line2D oppositeLine = new Line2D(oppA.outEdge.source.Position, oppA.outEdge.target.Position);

                    // TODO: Need to use a ray-line intersection here, where inLine and outLine are
                    //       replaced by rays which start at V and project in alignment with the two incident edges
                    Point2D?inOppIntersection  = Intersector.Intersect(inRay, oppositeLine);
                    Point2D?outOppIntersection = Intersector.Intersect(outRay, oppositeLine);

                    if (inOppIntersection.HasValue && outOppIntersection.HasValue)
                    {
                        Triangle2D triangle = new Triangle2D(vertex.Position, inOppIntersection.Value, outOppIntersection.Value);
                        if (!triangle.IsDegenerate)
                        {
                            Point2D incenter = triangle.Incenter;

                            // Is the incenter in the zone bounded by the oppositeLine and bisectors at the beginning
                            // and end of the segment embedded within it?

                            // TODO: Check which way round these lines are - so the the positive side defines our zone of interest
                            Line2D oppositeBoundary1 = oppA.Bisector.SupportingLine.Opposite;
                            Line2D oppositeBoundary2 = oppB.Bisector.SupportingLine;

                            OrientedSide sideA = oppositeBoundary1.Side(incenter);
                            OrientedSide sideB = oppositeLine.Side(incenter);
                            OrientedSide sideC = oppositeBoundary2.Side(incenter);

                            if (sideA == OrientedSide.Negative && sideB == OrientedSide.Negative && sideC == OrientedSide.Negative)
                            {
                                double distance2 = (incenter - vertex.Position).Magnitude2;
                                if (distance2 > 0.0 && distance2 < minDistance2)
                                {
                                    minDistance2 = distance2;
                                    minIncenter  = incenter;
                                }
                            }
                        }
                    }
                });
            }
            return(minIncenter);
        }