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); }
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); }
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); }
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); }
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); }
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); }
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); }
/// <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); } }
/// <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); }