Ejemplo n.º 1
0
    public static List <SegmentIntersection> GetClosestPointsBetweenPolygons(Vector3[] polygonVerticesA, Vector3[] polygonVerticesB)
    {
        // Returns a list of intersections as Vector2s. Or, in the case of no intersection the vertex in polygonVerticesA closest to polygonB
        List <SegmentIntersection> intersections = new List <SegmentIntersection>();
        float minDist = Mathf.Infinity;
        SegmentIntersection closestIntersection = new SegmentIntersection(false, polygonVerticesA[0], Mathf.Infinity, polygonVerticesA[0]);

        for (int i = 0; i < polygonVerticesA.Length - 1; i++)
        {
            for (int j = 0; j < polygonVerticesB.Length - 1; j++)
            {
                SegmentIntersection intersection = GetLineIntersection(polygonVerticesA[i], polygonVerticesA[i + 1], polygonVerticesB[j], polygonVerticesB[j + 1]);
                if (!intersection.OnSegment)
                {
                    // Not on segment
                    // Consider possibility that this is the closest segment interaction
                    //
                    if (intersection.MinDist < minDist)
                    {
                        minDist             = intersection.MinDist;
                        closestIntersection = intersection;
                    }
                    continue;
                }

                intersections.Add(intersection);
            }
        }
        if (intersections.Count == 0)
        {
            intersections.Add(closestIntersection); // No intersections. Take vertex in A closest to B
        }
        return(intersections);
    }
Ejemplo n.º 2
0
        public void CanDetermineOppositeDirection()
        {
            Line3D line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(5, 0, 0));
            Line3D line2 = new Line3D(new Pnt3D(2, 0, 0), new Pnt3D(0, 0, 0));

            const double tolerance = 0.01;

            var intersection =
                SegmentIntersection.CalculateIntersectionXY(1, 2, line1, line2, tolerance);

            Assert.True(intersection.HasLinearIntersection);
            Assert.True(intersection.LinearIntersectionInOppositeDirection);

            intersection =
                SegmentIntersection.CalculateIntersectionXY(2, 1, line2, line1, tolerance);
            Assert.True(intersection.HasLinearIntersection);
            Assert.True(intersection.LinearIntersectionInOppositeDirection);

            // Special case: The source end is very far away and deviates more than the tolerance from the target straigh:
            line1.SetEndPoint(new Pnt3D(100, 0.02, 0));

            intersection =
                SegmentIntersection.CalculateIntersectionXY(1, 2, line1, line2, tolerance);
            Assert.True(intersection.HasLinearIntersection);
            Assert.True(intersection.LinearIntersectionInOppositeDirection);
        }
Ejemplo n.º 3
0
        public void CanGetSegmentIntersectionsXY()
        {
            var line1 = new Line3D(new Pnt3D(0, 5, 0), new Pnt3D(10, 5, 0));
            var line2 = new Line3D(new Pnt3D(6, 0, 0), new Pnt3D(6, 10, 0));

            SegmentIntersection intersection =
                SegmentIntersection.CalculateIntersectionXY(
                    0, 0, line1, line2, 0.01);

            Assert.IsTrue(intersection.HasIntersection);
            Assert.AreEqual(0.6, intersection.SingleInteriorIntersectionFactor);

            line2 = new Line3D(new Pnt3D(10, 0, 0), new Pnt3D(10, 10, 0));

            intersection =
                SegmentIntersection.CalculateIntersectionXY(0, 0, line1, line2, 0.01);

            Assert.IsTrue(intersection.HasIntersection);
            Assert.IsNull(intersection.SingleInteriorIntersectionFactor);
            Assert.IsTrue(intersection.SourceEndIntersects);

            line2 = new Line3D(new Pnt3D(10, 0, 0), new Pnt3D(10, 5, 0));

            intersection =
                SegmentIntersection.CalculateIntersectionXY(0, 0, line1, line2, 0.01);
            Assert.IsTrue(intersection.HasIntersection);
            Assert.IsNull(intersection.SingleInteriorIntersectionFactor);
            Assert.IsTrue(intersection.SourceEndIntersects);
        }
Ejemplo n.º 4
0
        private static SegmentIntersection AssertLinearIntersection(
            Line3D line1, Line3D line2, double tolerance,
            bool?oppositeDirection = null)
        {
            var intersection =
                SegmentIntersection.CalculateIntersectionXY(0, 0, line1, line2, tolerance);
            var intersectionTargetIsSource =
                SegmentIntersection.CalculateIntersectionXY(0, 0, line2, line1, tolerance);

            Assert.True(intersection.HasLinearIntersection);
            Assert.True(intersectionTargetIsSource.HasLinearIntersection);

            Assert.True(intersection.IsPotentialPseudoLinearIntersection(
                            line1, line2, tolerance));
            Assert.True(
                intersectionTargetIsSource.IsPotentialPseudoLinearIntersection(
                    line2, line1, tolerance));

            if (oppositeDirection != null)
            {
                if (oppositeDirection.Value)
                {
                    Assert.True(intersection.LinearIntersectionInOppositeDirection);
                    Assert.True(intersectionTargetIsSource.LinearIntersectionInOppositeDirection);
                }
                else
                {
                    Assert.False(intersection.LinearIntersectionInOppositeDirection);
                    Assert.False(intersectionTargetIsSource.LinearIntersectionInOppositeDirection);
                }
            }

            return(intersection);
        }
Ejemplo n.º 5
0
    public static List <SegmentIntersection> GetPolygonIntersections(Vector3[] polygonVerticesA, Vector3[] polygonVerticesB)
    {
        // Should add some validation here
        List <SegmentIntersection> intersections = new List <SegmentIntersection>();

        for (int i = 0; i < polygonVerticesA.Length - 1; i++)
        {
            for (int j = 0; j < polygonVerticesB.Length - 1; j++)
            {
                SegmentIntersection intersection = GetLineIntersection(polygonVerticesA[i], polygonVerticesA[i + 1], polygonVerticesB[j], polygonVerticesB[j + 1]);
                if (!intersection.OnSegment)
                {
                    continue;
                }

                intersections.Add(intersection);
            }
        }
        return(intersections);
    }
Ejemplo n.º 6
0
        public static float GetDistance(Segment seg, List <Segment> segments)
        {
            var minDist = seg.From.DistanceTo(seg.To);

            for (int i = 0; i < segments.Count; i++)
            {
                var s = segments[i];
                var p = SegmentIntersection.FindIntersection(seg.From, seg.To, s.From, s.To);
                if (p != null)
                {
                    var dist = p.Value.DistanceTo(seg.From);
                    if (dist < minDist)
                    {
                        minDist = dist;
                    }
                    return(minDist);
                }
            }

            return(minDist);
        }
Ejemplo n.º 7
0
        public void CanDetermineCorrectOrientationForPseudoLinearIntersecion()
        {
            // The linear intersection can be somewhat un-intuitive if the end points are witin the tolerance to the
            // other line but just outside the tolerance to the other end point.

            Line3D line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(5, 0, 0));
            Line3D line2 = new Line3D(new Pnt3D(0.011, 0, 0), new Pnt3D(-10, 10, 0));

            const double tolerance = 0.01;

            SegmentIntersection intersection =
                AssertLinearIntersection(line1, line2, tolerance, true);

            double startAlongSource;
            Pnt3D  sourceStart =
                intersection.GetLinearIntersectionStart(line1, out startAlongSource);

            double endAlongSource;
            Pnt3D  sourceEnd = intersection.GetLinearIntersectionEnd(line1, out endAlongSource);

            line2.ReverseOrientation();
            AssertLinearIntersection(line1, line2, tolerance, false);

            line2 = new Line3D(new Pnt3D(0.009, -0.008, 0), new Pnt3D(-10, 10, 0));
            AssertLinearIntersection(line1, line2, tolerance, true);

            line2.ReverseOrientation();
            AssertLinearIntersection(line1, line2, tolerance, false);

            // Really acute:
            line2 = new Line3D(new Pnt3D(0.03, 0.0, 0), new Pnt3D(-10, 1, 0));
            AssertLinearIntersection(line1, line2, tolerance, true);

            line2.ReverseOrientation();
            AssertLinearIntersection(line1, line2, tolerance, false);
        }
Ejemplo n.º 8
0
    private List <Vector2> GetInnerStageVertex()
    {
        int            numPoints         = shapeCreator.shapes[stageShape].points.Count;
        List <Vector2> intersectionsList = new List <Vector2>();

        intersection = gameObject.GetComponent <SegmentIntersection>();
        Vector3[] stageMeshVertices  = new Vector3[numPoints];
        Vector2   intersectionVector = new Vector2();

        for (int i = 0; i < numPoints; i++)
        {
            stageMeshVertices[i] = shapeCreator.shapes[stageShape].points[i];
        }

        //foreach shadowMeshes pair of vertices we check each stageMeshVertices
        for (int i = 0; i < shadowCaster.shadowMeshes.Count; i++)
        {
            for (int k = 0; k < stageMeshVertices.Length; k++)
            {
                int k2 = 0;

                if (!(k == stageMeshVertices.Length - 1))
                {
                    k2 = k + 1;
                }

                Vector2 stageVert1 = new Vector2(stageMeshVertices[k].x, stageMeshVertices[k].z);
                Vector2 stageVert2 = new Vector2(stageMeshVertices[k2].x, stageMeshVertices[k2].z);

                Vector2 vec2Player = new Vector2(player.position.x, player.position.z);
                //Vector2 rayFromPlayer = (stageVert1 - vec2Player)*0.99f;

                for (int shape = stageShape + 1; shape < shapeCreator.shapes.Count; shape++)
                {
                    for (int p = 0; p < shapeCreator.shapes[shape].points.Count; p++)
                    {
                        Vector3 point1 = shapeCreator.shapes[shape].points[p];
                        Vector3 point2 = new Vector3();
                        if (!(p == shapeCreator.shapes[shape].points.Count - 1))
                        {
                            point2 = shapeCreator.shapes[shape].points[p + 1];
                        }
                        else
                        {
                            point2 = shapeCreator.shapes[shape].points[0];
                        }

                        Vector2 pointVert1 = new Vector2(point1.x, point1.z);
                        Vector2 pointVert2 = new Vector2(point2.x, point2.z);


                        Vector2 tempIntersectionVector = new Vector2();
                        if (intersection.LineIntersection(vec2Player, stageVert1, pointVert1, pointVert2, ref tempIntersectionVector))
                        {
                            p = shapeCreator.shapes[shape].points.Count;
                            allShadowVertices.Add(new ShadowVertex(stageShape, k, stageVert1, 0));
                        }
                    }
                }

                ShadowRange shadowRange = new ShadowRange();
                shadowRange.meshIndex        = i;
                shadowRange.wallSegmentIndex = k;

                for (int j = 0; j < shadowCaster.shadowMeshes[i].vertices.Length; j++)
                {
                    int j2 = 0;

                    if (!(j == shadowCaster.shadowMeshes[i].vertices.Length - 1))
                    {
                        j2 = j + 1;
                    }
                    Vector2 shadowVert1 = new Vector2(shadowCaster.shadowMeshes[i].vertices[j].x, shadowCaster.shadowMeshes[i].vertices[j].z);
                    Vector2 shadowVert2 = new Vector2(shadowCaster.shadowMeshes[i].vertices[j2].x, shadowCaster.shadowMeshes[i].vertices[j2].z);

                    if (intersection.LineIntersection(stageVert1, stageVert2, shadowVert1, shadowVert2, ref intersectionVector))
                    {
                        intersectionsList.Add(intersectionVector);

                        float distanceAlongStageEdge = (intersectionVector - stageVert1).magnitude / (stageVert2 - stageVert1).magnitude;

                        shadowRange.rangePointPairs.Add(new RangePointPair(distanceAlongStageEdge, intersectionVector));

                        //Debug.Log(intersectionVector);

                        /*
                         * GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                         * Destroy(sphere, 0.01f);
                         * sphere.transform.position = new Vector3(intersectionVector.x, 0, intersectionVector.y);
                         * sphere.transform.localScale = Vector3.one * (intersectionEdgeCount*0.01f + 0.05f);
                         */
                    }
                }

                shadowRanges.Add(shadowRange);
            }
        }
        return(intersectionsList);
    }
Ejemplo n.º 9
0
        public void CanGetLinearIntersectionInteriorXY()
        {
            var line1 = new Line3D(new Pnt3D(0, 0, 0), new Pnt3D(10, 10, 0));
            var line2 = new Line3D(new Pnt3D(6, 6, 3), new Pnt3D(8, 8, 3));

            SegmentIntersection intersection =
                SegmentIntersection.CalculateIntersectionXY(
                    0, 7, line1, line2, 0.01);

            Assert.IsTrue(intersection.HasIntersection);
            Assert.IsNull(intersection.SingleInteriorIntersectionFactor);

            Assert.IsTrue(intersection.HasLinearIntersection);
            Assert.IsFalse(intersection.SegmentsAreEqualInXy);
            Assert.IsFalse(intersection.SourceStartIntersects);
            Assert.IsFalse(intersection.SourceEndIntersects);

            Assert.IsTrue(intersection.TargetStartIntersects);
            Assert.IsTrue(intersection.TargetEndIntersects);

            Assert.IsFalse(intersection.LinearIntersectionInOppositeDirection);
            Assert.IsTrue(intersection.HasSourceInteriorIntersection);

            Assert.AreEqual(0.6, intersection.GetFirstIntersectionAlongSource());

            double startFactorAlongSource;

            Assert.IsTrue(new Pnt3D(6, 6, 0).Equals(
                              intersection.GetLinearIntersectionStart(
                                  line1, out startFactorAlongSource)));
            Assert.AreEqual(0.6, startFactorAlongSource);

            double endFactorAlongSource;

            Assert.IsTrue(new Pnt3D(8, 8, 0).Equals(
                              intersection.GetLinearIntersectionEnd(
                                  line1, out endFactorAlongSource)));
            Assert.AreEqual(0.8, endFactorAlongSource);

            Assert.AreEqual(0.6, intersection.GetLinearIntersectionStartFactor(true));
            Assert.AreEqual(0.8, intersection.GetLinearIntersectionEndFactor(true));

            Assert.IsTrue(new Pnt3D(6, 6, 3).Equals(
                              intersection.GetLinearIntersectionStartOnTarget(line2)));
            Assert.IsTrue(new Pnt3D(8, 8, 3).Equals(
                              intersection.GetLinearIntersectionEndOnTarget(line2)));

            Assert.IsTrue(new Line3D(
                              new Pnt3D(6, 6, 0),
                              new Pnt3D(8, 8, 0)
                              ).Equals(intersection.TryGetIntersectionLine(line1)));

            Assert.AreEqual(0, intersection.GetRatioAlongTargetLinearStart());
            Assert.AreEqual(1.0, intersection.GetRatioAlongTargetLinearEnd());

            // Now the source is inside the target and reversed:
            line1.ReverseOrientation();
            intersection =
                SegmentIntersection.CalculateIntersectionXY(
                    0, 7, line2, line1, 0.01);

            Assert.IsTrue(intersection.HasIntersection);
            Assert.IsNull(intersection.SingleInteriorIntersectionFactor);

            Assert.IsTrue(intersection.HasLinearIntersection);
            Assert.IsFalse(intersection.SegmentsAreEqualInXy);
            Assert.IsTrue(intersection.SourceStartIntersects);
            Assert.IsTrue(intersection.SourceEndIntersects);

            Assert.IsFalse(intersection.TargetStartIntersects);
            Assert.IsFalse(intersection.TargetEndIntersects);

            Assert.IsTrue(intersection.LinearIntersectionInOppositeDirection);
            Assert.IsTrue(intersection.HasSourceInteriorIntersection);

            Assert.AreEqual(0, intersection.GetFirstIntersectionAlongSource());

            Assert.IsTrue(new Pnt3D(6, 6, 3).Equals(
                              intersection.GetLinearIntersectionStart(
                                  line2, out startFactorAlongSource)));
            Assert.AreEqual(0, startFactorAlongSource);

            Assert.IsTrue(new Pnt3D(8, 8, 3).Equals(
                              intersection.GetLinearIntersectionEnd(
                                  line2, out endFactorAlongSource)));
            Assert.AreEqual(1, endFactorAlongSource);

            Assert.AreEqual(0, intersection.GetLinearIntersectionStartFactor(true));
            Assert.AreEqual(1, intersection.GetLinearIntersectionEndFactor(true));

            Assert.IsTrue(new Pnt3D(6, 6, 0).Equals(
                              intersection.GetLinearIntersectionStartOnTarget(line1)));
            Assert.IsTrue(new Pnt3D(8, 8, 0).Equals(
                              intersection.GetLinearIntersectionEndOnTarget(line1)));

            Assert.IsTrue(new Line3D(
                              new Pnt3D(6, 6, 3),
                              new Pnt3D(8, 8, 3)
                              ).Equals(intersection.TryGetIntersectionLine(line2)));

            Assert.AreEqual(0.4, intersection.GetRatioAlongTargetLinearStart());
            Assert.AreEqual(0.2, intersection.GetRatioAlongTargetLinearEnd());
        }