コード例 #1
0
ファイル: TextureConverter.cs プロジェクト: jocamar/Caravel
        private bool SearchForOutstandingVertex(Vertices hullArea, out Vector2 outstanding)
        {
            Vector2 outstandingResult = Vector2.Zero;
            bool    found             = false;

            if (hullArea.Count > 2)
            {
                int hullAreaLastPoint = hullArea.Count - 1;

                Vector2 tempVector1;
                Vector2 tempVector2 = hullArea[0];
                Vector2 tempVector3 = hullArea[hullAreaLastPoint];

                // Search between the first and last hull point.
                for (int i = 1; i < hullAreaLastPoint; i++)
                {
                    tempVector1 = hullArea[i];

                    // Check if the distance is over the one that's tolerable.
                    if (LineUtils.DistanceBetweenPointAndLineSegment(ref tempVector1, ref tempVector2, ref tempVector3) >= _hullTolerance)
                    {
                        outstandingResult = hullArea[i];
                        found             = true;
                        break;
                    }
                }
            }

            outstanding = outstandingResult;
            return(found);
        }
コード例 #2
0
    /// Gets the necessary info for adding a new line via a warp, adds it, and keeps looking.
    private void AddWarpLineRecursively(BeamRendererCollision coll)
    {
        float   angleIn = coll.angleIn;
        Vector2 posIn   = coll.pos;
        float   loc     = LineUtils.PosToLoc(coll.collLine.line, posIn);
        // Translate pos/rot in to pos/rot out.
        float angleOut;

        switch (coll.collLine.collType)
        {
        case BeamRendererCollision.Types.WarpFlipH:
            angleOut = MathUtils.FlipDegHorz(angleIn);
            break;

        case BeamRendererCollision.Types.WarpFlipV:
            angleOut = MathUtils.FlipDegVert(angleIn);
            break;

        default:
            angleOut = angleIn;
            break;
        }

        Line    lineOut = coll.collLine.lineOut;
        Vector2 posOut  = lineOut.LocToPos(loc);

        AddLineRecursively(posOut, angleOut);
    }
コード例 #3
0
    // ----------------------------------------------------------------
    //  Getters
    // ----------------------------------------------------------------
    /** beamAngle: in DEGREES. */
    public BeamRendererCollision GetBeamRendererCollision(Vector2 beamPos, float beamAngle)
    {
        // Make a huge-ass line! Note: I'm doing line-line collision instead of ray-line collision because there's less code and it's easier to understand.
        Line beamLine = new Line(beamPos, beamPos + MathUtils.GetVectorFromDeg(beamAngle) * 100000);

        // Get the CLOSEST line-on-line collision!
        BeamRendererCollision closestColl = new BeamRendererCollision(null, beamLine.end, beamAngle);         // default this to the farthest theoretical collision possible.
        float closestDist = float.PositiveInfinity;

        Vector2 intPos;

        foreach (BeamRendererColliderLine collLine in allColliderLines)
        {
            bool isIntersection = LineUtils.GetIntersectionLineToLine(out intPos, beamLine, collLine.line);
            if (isIntersection)               // There IS an intersection!
            {
                float intDist = Vector2.Distance(intPos, beamLine.start);
                if (closestDist > intDist)                   // It's the closest one yet! Update the values I'm gonna return!
                {
                    closestDist     = intDist;
                    closestColl.pos = intPos;
                    closestColl.SetCollLine(collLine);
                    closestColl.angleIn = beamAngle;
                    //float lineAngle = collLine.line.GetAngleDeg();
                    //closestColl.exitRotation = MathUtils.GetAngleReflection (beamAngle, lineAngle);
//					Debug.Log ("lineAngle: " + lineAngle + "  pos: " + intPos + "  closestCollisionDist: " + closestCollisionDist);
//					Debug.Log ("beamAngle: " + beamAngle + " lineAngle: " + lineAngle + "  exitRotation: " + closestCollision.exitRotation);
                }
            }
        }
        return(closestColl);
//		// Oh, jeez. SOMEhow we didn't intersect with anything, not even my outer bounds!! This is an error. Just return a made-up intersection at the end of the fake line we used.
//		Debug.LogWarning ("Oops! A BeamRenderer didn't have a collision with ANYthing! It should at least be hitting the Arena's bounds.");
//		return new BeamRendererCollision(false, beamAngle, beamLine.end);
    }
コード例 #4
0
        /// <summary>
        /// Checks if the vertices forms an simple polygon by checking for edge crossings.
        /// </summary>
        public bool IsSimple()
        {
            //The simplest polygon which can exist in the Euclidean plane has 3 sides.
            if (Count < 3)
            {
                return(false);
            }

            for (int i = 0; i < Count; ++i)
            {
                Vector2 a1 = this[i];
                Vector2 a2 = NextVertex(i);
                for (int j = i + 1; j < Count; ++j)
                {
                    Vector2 b1 = this[j];
                    Vector2 b2 = NextVertex(j);

                    Vector2 temp;

                    if (LineUtils.LineIntersect2(ref a1, ref a2, ref b1, ref b2, out temp))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
コード例 #5
0
        public static List <Curve> SplitCurve(Curve c, XYZ p, double shortCurveTolerance, bool preserveDirection = true)
        {
            //only lines are splited, arcs must implemented
            if (c != null &&
                p != null
                //&& c is Line
                && IsPointOnCurve(c, p))
            {
                XYZ cS = GetEndPoint(c, 0);
                XYZ cE = GetEndPoint(c, 1);

                if (!p.IsAlmostEqualTo(cS) && !p.IsAlmostEqualTo(cE) &&
                    (p.DistanceTo(cS) > shortCurveTolerance || DoubleUtilities.IsDoublesEqual(p.DistanceTo(cS), shortCurveTolerance)) &&
                    (p.DistanceTo(cE) > shortCurveTolerance || DoubleUtilities.IsDoublesEqual(p.DistanceTo(cE), shortCurveTolerance)))
                {
                    Curve c1 = null;
                    Curve c2 = null;

                    if (c is Arc)
                    {
                        Arc arc = c as Arc;

                        //XYZ center = arc.Evaluate(0.5, true);

                        XYZ center1 = PushOnCurveByCurve(c, GetEndPoint(c, 0), VectorUtils.GetVectorOfCurve(c), cS.DistanceTo(p) / 2.0);
                        XYZ center2 = PushOnCurveByCurve(c, GetEndPoint(c, 1), VectorUtils.GetVectorOfCurve(c).Negate(), cE.DistanceTo(p) / 2.0);

                        c1 = Arc.Create(cS, p, center1);

                        c2 = Arc.Create(p, cE, center2);
                    }
                    else
                    {
                        if (preserveDirection)
                        {
                            c1 = LineUtils.NewLineBound(cS, p) as Curve;
                            c2 = LineUtils.NewLineBound(p, cE) as Curve;
                        }
                        else
                        {
                            c1 = LineUtils.NewLineBound(p, cS) as Curve;
                            c2 = LineUtils.NewLineBound(p, cE) as Curve;
                        }
                    }

                    if (c1 != null && c2 != null)
                    {
                        return(new List <Curve>()
                        {
                            c1, c2
                        });
                    }
                }
            }

            return(null);
        }
コード例 #6
0
        public static StartedLineState Create(GraphVisual graphVisual, NumEllipse startingEllipse, Point currentPoint)
        {
            var ellipseCenter = startingEllipse.Ellipse.GetCanvasCenter();
            var weight        = (graphVisual.MinWeight + graphVisual.MaxWeight) / 2.0;
            var thickness     = (graphVisual.MinLineThickness + graphVisual.MaxLineThickness) / 2.0;
            var line          = LineUtils.CreateLine(ellipseCenter, currentPoint, graphVisual.LineBrush, thickness, graphVisual.PenLineCap);

            graphVisual.Canvas.Children.Add(line);
            return(new StartedLineState(graphVisual, startingEllipse, line, weight));
        }
コード例 #7
0
        private static bool CanSee(int i, int j, Vertices vertices)
        {
            if (Reflex(i, vertices))
            {
                if (LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices)) &&
                    RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices)))
                {
                    return(false);
                }
            }
            else
            {
                if (RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices)) ||
                    LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices)))
                {
                    return(false);
                }
            }

            if (Reflex(j, vertices))
            {
                if (LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices)) &&
                    RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices)))
                {
                    return(false);
                }
            }
            else
            {
                if (RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices)) ||
                    LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices)))
                {
                    return(false);
                }
            }

            for (var k = 0; k < vertices.Count; ++k)
            {
                if ((k + 1) % vertices.Count == i || k == i || (k + 1) % vertices.Count == j || k == j)
                {
                    continue; // ignore incident edges
                }
                Vector2 intersectionPoint;

                if (LineUtils.LineIntersect(At(i, vertices), At(j, vertices), At(k, vertices), At(k + 1, vertices),
                                            out intersectionPoint))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #8
0
        private bool DistanceToHullAcceptable(Vertices polygon, Vector2 point, bool higherDetail)
        {
            if (polygon == null)
            {
                throw new ArgumentNullException(nameof(polygon), "'polygon' can't be null.");
            }

            if (polygon.Count < 3)
            {
                throw new ArgumentException("'polygon.Count' can't be less then 3.");
            }

            var     edgeVertex2 = polygon[polygon.Count - 1];
            Vector2 edgeVertex1;

            if (higherDetail)
            {
                for (var i = 0; i < polygon.Count; i++)
                {
                    edgeVertex1 = polygon[i];

                    if (LineUtils.DistanceBetweenPointAndLineSegment(ref point, ref edgeVertex1, ref edgeVertex2) <=
                        _hullTolerance || Vector2.Distance(point, edgeVertex1) <= _hullTolerance)
                    {
                        return(false);
                    }

                    edgeVertex2 = polygon[i];
                }

                return(true);
            }
            else
            {
                for (var i = 0; i < polygon.Count; i++)
                {
                    edgeVertex1 = polygon[i];

                    if (LineUtils.DistanceBetweenPointAndLineSegment(ref point, ref edgeVertex1, ref edgeVertex2) <=
                        _hullTolerance)
                    {
                        return(false);
                    }

                    edgeVertex2 = polygon[i];
                }

                return(true);
            }
        }
コード例 #9
0
ファイル: ImageLine.cs プロジェクト: BATzerk/Unity-BlockSlide
 // ----------------------------------------------------------------
 //  Update Things
 // ----------------------------------------------------------------
 private void UpdateAngleLengthPosition()
 {
     // Update values
     angle  = LineUtils.GetAngle_Degrees(startPos, endPos);
     length = LineUtils.GetLength(startPos, endPos);
     // Transform image!
     if (float.IsNaN(endPos.x))
     {
         Debug.LogError("Ahem! An ImageLine's endPos is NaN! (Its startPos is " + startPos + ".)");
     }
     this.GetComponent <RectTransform>().anchoredPosition = LineUtils.GetCenterPos(startPos, endPos);        //.transform.localPosition
     this.transform.localEulerAngles = new Vector3(0, 0, angle);
     SetThickness(thickness);
 }
コード例 #10
0
 // ----------------------------------------------------------------
 //  Update Things
 // ----------------------------------------------------------------
 private void UpdateAngleLengthPosition()
 {
     // Update values
     angle  = LineUtils.GetAngle_Degrees(startPos, endPos);
     length = LineUtils.GetLength(startPos, endPos);
     // Transform sprite!
     if (float.IsNaN(endPos.x))
     {
         Debug.LogError("Ahem! A SpriteLine's endPos is NaN! (Its startPos is " + startPos + ".)");
     }
     this.transform.localPosition    = LineUtils.GetCenterPos(startPos, endPos);
     this.transform.localEulerAngles = new Vector3(0, 0, angle);
     GameUtils.SizeSpriteRenderer(sprite, length, thickness);
 }
コード例 #11
0
    private bool _checkForCollisions()
    {
        bool shouldEndGame = false;

        // For every Branch that is growing, we need to check if it's crossing other branches.
        foreach (BranchComponent branch in _branches.Where((b) => b.isGrowing && b.LineSegments.Count > 0))
        {
            LineSegment latestSegment = branch.WorldLineSegments.Last();
            foreach (BranchComponent other in _branches)
            {
                if (branch != other && (branch.parentBranch == null || branch.parentBranch != other))
                {
                    foreach (LineSegment line in other.WorldLineSegments)
                    {
                        // If the segments are the same origin, we assume
                        //	this is where they branch off.
                        bool areSameOrigin = latestSegment.StartPoint == line.StartPoint;
                        bool doCross       = !areSameOrigin && LineUtils.CrossProductIntersectTest(latestSegment, line);
                        if (doCross)
                        {
                            bool    areCrossing = false;
                            Vector2 point       = LineUtils.GetIntersectionPointCoordinates(latestSegment.StartPoint, latestSegment.EndPoint, line.StartPoint, line.EndPoint, out areCrossing);
                            // PLAY THE CRACK!
                            SoundManager.instance.PlayBackgroundSfx(3);
                            ZoomToPointComponent zoomer = gameObject.AddComponent <ZoomToPointComponent>();
                            zoomer.targetPoint = point;
                            //zoomer.timeToZoom = 0.75f;
                            zoomer.pauseTime = 0.5f;

                            shouldEndGame = true;
                            break;
                        }
                    }

                    if (shouldEndGame)
                    {
                        return(shouldEndGame);
                    }
                }
            }
        }
        return(false);
    }
コード例 #12
0
        private static void SimplifySection(Vertices vertices, int i, int j, bool[] usePoint, float distanceTolerance)
        {
            if (i + 1 == j)
            {
                return;
            }

            var a = vertices[i];
            var b = vertices[j];

            var maxDistance = -1.0f;
            var maxIndex    = i;

            for (var k = i + 1; k < j; k++)
            {
                var point = vertices[k];

                var distance = LineUtils.DistanceBetweenPointAndLineSegment(ref point, ref a, ref b);

                if (distance > maxDistance)
                {
                    maxDistance = distance;
                    maxIndex    = k;
                }
            }

            if (maxDistance <= distanceTolerance)
            {
                for (var k = i + 1; k < j; k++)
                {
                    usePoint[k] = false;
                }
            }
            else
            {
                SimplifySection(vertices, i, maxIndex, usePoint, distanceTolerance);
                SimplifySection(vertices, maxIndex, j, usePoint, distanceTolerance);
            }
        }
コード例 #13
0
ファイル: SimplifyTools.cs プロジェクト: jocamar/Caravel
        private static void SimplifySection(Vertices vertices, int i, int j, bool[] usePoint, float distanceTolerance)
        {
            if ((i + 1) == j)
            {
                return;
            }

            Vector2 a = vertices[i];
            Vector2 b = vertices[j];

            double maxDistance = -1.0;
            int    maxIndex    = i;

            for (int k = i + 1; k < j; k++)
            {
                Vector2 point = vertices[k];

                double distance = LineUtils.DistanceBetweenPointAndLineSegment(ref point, ref a, ref b);

                if (distance > maxDistance)
                {
                    maxDistance = distance;
                    maxIndex    = k;
                }
            }

            if (maxDistance <= distanceTolerance)
            {
                for (int k = i + 1; k < j; k++)
                {
                    usePoint[k] = false;
                }
            }
            else
            {
                SimplifySection(vertices, i, maxIndex, usePoint, distanceTolerance);
                SimplifySection(vertices, maxIndex, j, usePoint, distanceTolerance);
            }
        }
コード例 #14
0
ファイル: TextureConverter.cs プロジェクト: jocamar/Caravel
        private bool SplitPolygonEdge(Vertices polygon, Vector2 coordInsideThePolygon, out int vertex1Index, out int vertex2Index)
        {
            Vector2 slope;
            int     nearestEdgeVertex1Index = 0;
            int     nearestEdgeVertex2Index = 0;
            bool    edgeFound = false;

            float shortestDistance = float.MaxValue;

            bool    edgeCoordFound = false;
            Vector2 foundEdgeCoord = Vector2.Zero;

            List <float> xCoords = SearchCrossingEdges(polygon, (int)coordInsideThePolygon.Y);

            vertex1Index = 0;
            vertex2Index = 0;

            foundEdgeCoord.Y = coordInsideThePolygon.Y;

            if (xCoords != null && xCoords.Count > 1 && xCoords.Count % 2 == 0)
            {
                float distance;
                for (int i = 0; i < xCoords.Count; i++)
                {
                    if (xCoords[i] < coordInsideThePolygon.X)
                    {
                        distance = coordInsideThePolygon.X - xCoords[i];

                        if (distance < shortestDistance)
                        {
                            shortestDistance = distance;
                            foundEdgeCoord.X = xCoords[i];

                            edgeCoordFound = true;
                        }
                    }
                }

                if (edgeCoordFound)
                {
                    shortestDistance = float.MaxValue;

                    int edgeVertex2Index = polygon.Count - 1;

                    int edgeVertex1Index;
                    for (edgeVertex1Index = 0; edgeVertex1Index < polygon.Count; edgeVertex1Index++)
                    {
                        Vector2 tempVector1 = polygon[edgeVertex1Index];
                        Vector2 tempVector2 = polygon[edgeVertex2Index];
                        distance = LineUtils.DistanceBetweenPointAndLineSegment(ref foundEdgeCoord,
                                                                                ref tempVector1, ref tempVector2);
                        if (distance < shortestDistance)
                        {
                            shortestDistance = distance;

                            nearestEdgeVertex1Index = edgeVertex1Index;
                            nearestEdgeVertex2Index = edgeVertex2Index;

                            edgeFound = true;
                        }

                        edgeVertex2Index = edgeVertex1Index;
                    }

                    if (edgeFound)
                    {
                        slope = polygon[nearestEdgeVertex2Index] - polygon[nearestEdgeVertex1Index];
                        slope.Normalize();

                        Vector2 tempVector = polygon[nearestEdgeVertex1Index];
                        distance = Vector2.Distance(tempVector, foundEdgeCoord);

                        vertex1Index = nearestEdgeVertex1Index;
                        vertex2Index = nearestEdgeVertex1Index + 1;

                        polygon.Insert(nearestEdgeVertex1Index, distance * slope + polygon[vertex1Index]);
                        polygon.Insert(nearestEdgeVertex1Index, distance * slope + polygon[vertex2Index]);

                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #15
0
    // ----------------------------------------------------------------
    //  Initialize
    // ----------------------------------------------------------------
    public void Initialize(Board b, Rect r_board)
    {
        allColliderLines = new List <BeamRendererColliderLine>();
        boundsLines      = new List <BeamRendererColliderLine>();

        //// Populate me first with far-reaching boundaries!!
        //Rect br = new Rect (-1000,-1000, 3000,3000);
        //boundsLines.Add (new BeamRendererColliderLine (null, new Line (br.xMin,br.yMin,  br.xMax,br.yMin), BeamRendererCollision.Types.End));
        //boundsLines.Add (new BeamRendererColliderLine (null, new Line (br.xMax,br.yMin,  br.xMax,br.yMax), BeamRendererCollision.Types.End));
        //boundsLines.Add (new BeamRendererColliderLine (null, new Line (br.xMax,br.yMax,  br.xMin,br.yMax), BeamRendererCollision.Types.End));
        //boundsLines.Add (new BeamRendererColliderLine (null, new Line (br.xMin,br.yMax,  br.xMin,br.yMin), BeamRendererCollision.Types.End));
        // Add bounds on each Board side!
        Rect br = r_board;

        br.position = Vector2.zero;
        switch (b.WrapH)
        {
        case WrapTypes.Parallel:
            AddBoundsLine(LineUtils.GetLineCW(br, Sides.L), LineUtils.GetLineCCW(br, Sides.R), BeamRendererCollision.Types.WarpParallel);   // Left
            AddBoundsLine(LineUtils.GetLineCCW(br, Sides.R), LineUtils.GetLineCW(br, Sides.L), BeamRendererCollision.Types.WarpParallel);   // Right
            break;

        case WrapTypes.Flip:
            AddBoundsLine(LineUtils.GetLineCW(br, Sides.L), LineUtils.GetLineCW(br, Sides.R), BeamRendererCollision.Types.WarpFlipH);   // Left
            AddBoundsLine(LineUtils.GetLineCW(br, Sides.R), LineUtils.GetLineCW(br, Sides.L), BeamRendererCollision.Types.WarpFlipH);   // Right
            break;

        default:
            boundsLines.Add(new BeamRendererColliderLine(LineUtils.GetLineCW(br, Sides.L)));     // Left
            boundsLines.Add(new BeamRendererColliderLine(LineUtils.GetLineCW(br, Sides.R)));     // Right
            break;
        }
        switch (b.WrapV)
        {
        case WrapTypes.Parallel:
            AddBoundsLine(LineUtils.GetLineCW(br, Sides.B), LineUtils.GetLineCCW(br, Sides.T), BeamRendererCollision.Types.WarpParallel);   // Bottom
            AddBoundsLine(LineUtils.GetLineCCW(br, Sides.T), LineUtils.GetLineCW(br, Sides.B), BeamRendererCollision.Types.WarpParallel);   // Top
            break;

        case WrapTypes.Flip:
            AddBoundsLine(LineUtils.GetLineCW(br, Sides.B), LineUtils.GetLineCW(br, Sides.T), BeamRendererCollision.Types.WarpFlipH);   // Bottom
            AddBoundsLine(LineUtils.GetLineCW(br, Sides.T), LineUtils.GetLineCW(br, Sides.B), BeamRendererCollision.Types.WarpFlipH);   // Top
            break;

        default:
            boundsLines.Add(new BeamRendererColliderLine(LineUtils.GetLineCW(br, Sides.B)));     // Bottom
            boundsLines.Add(new BeamRendererColliderLine(LineUtils.GetLineCW(br, Sides.T)));     // Top
            break;
        }



        //// Right
        //switch (b.WrapH) {
        //    case WrapTypes.Parallel:
        //        boundsLines.Add(new BeamRendererColliderLine(LineUtils.GetLine(br, Sides.R), LineUtils.GetLine(br, Sides.L), BeamRendererCollision.Types.Warp)); break;
        //    //case WrapTypes.Flip:TODO: This.
        //        //boundsLines.Add(new BeamRendererColliderLine(null, LineUtils.GetLine(br, Sides.R), BeamRendererCollision.Types.Warp)); break;
        //    default:
        //        boundsLines.Add(new BeamRendererColliderLine(null, LineUtils.GetLine(br, Sides.R), BeamRendererCollision.Types.End)); break;
        //}
        foreach (BeamRendererColliderLine boundLine in boundsLines)
        {
            BeamRendererColliderLine _boundLine = boundLine;
            AddLine(ref _boundLine);
        }
    }
コード例 #16
0
        private static List <Vertices> TriangulatePolygon(Vertices vertices)
        {
            List <Vertices> list = new List <Vertices>();
            Vector2         lowerInt = new Vector2();
            Vector2         upperInt = new Vector2(); // intersection points
            int             lowerIndex = 0, upperIndex = 0;
            Vertices        lowerPoly, upperPoly;

            for (int i = 0; i < vertices.Count; ++i)
            {
                if (Reflex(i, vertices))
                {
                    float upperDist;
                    float lowerDist = upperDist = float.MaxValue;
                    for (int j = 0; j < vertices.Count; ++j)
                    {
                        // if line intersects with an edge
                        float   d;
                        Vector2 p;
                        if (Left(At(i - 1, vertices), At(i, vertices), At(j, vertices)) && RightOn(At(i - 1, vertices), At(i, vertices), At(j - 1, vertices)))
                        {
                            // find the point of intersection
                            p = LineUtils.LineIntersect(At(i - 1, vertices), At(i, vertices), At(j, vertices), At(j - 1, vertices));

                            if (Right(At(i + 1, vertices), At(i, vertices), p))
                            {
                                // make sure it's inside the poly
                                d = SquareDist(At(i, vertices), p);
                                if (d < lowerDist)
                                {
                                    // keep only the closest intersection
                                    lowerDist  = d;
                                    lowerInt   = p;
                                    lowerIndex = j;
                                }
                            }
                        }

                        if (Left(At(i + 1, vertices), At(i, vertices), At(j + 1, vertices)) && RightOn(At(i + 1, vertices), At(i, vertices), At(j, vertices)))
                        {
                            p = LineUtils.LineIntersect(At(i + 1, vertices), At(i, vertices), At(j, vertices), At(j + 1, vertices));

                            if (Left(At(i - 1, vertices), At(i, vertices), p))
                            {
                                d = SquareDist(At(i, vertices), p);
                                if (d < upperDist)
                                {
                                    upperDist  = d;
                                    upperIndex = j;
                                    upperInt   = p;
                                }
                            }
                        }
                    }

                    // if there are no vertices to connect to, choose a point in the middle
                    if (lowerIndex == (upperIndex + 1) % vertices.Count)
                    {
                        Vector2 p = (lowerInt + upperInt) / 2;

                        lowerPoly = Copy(i, upperIndex, vertices);
                        lowerPoly.Add(p);
                        upperPoly = Copy(lowerIndex, i, vertices);
                        upperPoly.Add(p);
                    }
                    else
                    {
                        double highestScore = 0, bestIndex = lowerIndex;
                        while (upperIndex < lowerIndex)
                        {
                            upperIndex += vertices.Count;
                        }

                        for (int j = lowerIndex; j <= upperIndex; ++j)
                        {
                            if (CanSee(i, j, vertices))
                            {
                                double score = 1 / (SquareDist(At(i, vertices), At(j, vertices)) + 1);
                                if (Reflex(j, vertices))
                                {
                                    if (RightOn(At(j - 1, vertices), At(j, vertices), At(i, vertices)) && LeftOn(At(j + 1, vertices), At(j, vertices), At(i, vertices)))
                                    {
                                        score += 3;
                                    }
                                    else
                                    {
                                        score += 2;
                                    }
                                }
                                else
                                {
                                    score += 1;
                                }
                                if (score > highestScore)
                                {
                                    bestIndex    = j;
                                    highestScore = score;
                                }
                            }
                        }
                        lowerPoly = Copy(i, (int)bestIndex, vertices);
                        upperPoly = Copy((int)bestIndex, i, vertices);
                    }
                    list.AddRange(TriangulatePolygon(lowerPoly));
                    list.AddRange(TriangulatePolygon(upperPoly));
                    return(list);
                }
            }

            // polygon is already convex
            if (vertices.Count > Settings.MaxPolygonVertices)
            {
                lowerPoly = Copy(0, vertices.Count / 2, vertices);
                upperPoly = Copy(vertices.Count / 2, 0, vertices);
                list.AddRange(TriangulatePolygon(lowerPoly));
                list.AddRange(TriangulatePolygon(upperPoly));
            }
            else
            {
                list.Add(vertices);
            }

            return(list);
        }
コード例 #17
0
ファイル: YuPengClipper.cs プロジェクト: jocamar/Caravel
        /// <summary>
        /// Calculates all intersections between two polygons.
        /// </summary>
        /// <param name="polygon1">The first polygon.</param>
        /// <param name="polygon2">The second polygon.</param>
        /// <param name="slicedPoly1">Returns the first polygon with added intersection points.</param>
        /// <param name="slicedPoly2">Returns the second polygon with added intersection points.</param>
        private static void CalculateIntersections(Vertices polygon1, Vertices polygon2,
                                                   out Vertices slicedPoly1, out Vertices slicedPoly2)
        {
            slicedPoly1 = new Vertices(polygon1);
            slicedPoly2 = new Vertices(polygon2);

            // Iterate through polygon1's edges
            for (int i = 0; i < polygon1.Count; i++)
            {
                // Get edge vertices
                Vector2 a = polygon1[i];
                Vector2 b = polygon1[polygon1.NextIndex(i)];

                // Get intersections between this edge and polygon2
                for (int j = 0; j < polygon2.Count; j++)
                {
                    Vector2 c = polygon2[j];
                    Vector2 d = polygon2[polygon2.NextIndex(j)];

                    Vector2 intersectionPoint;

                    // Check if the edges intersect
                    if (LineUtils.LineIntersect(a, b, c, d, out intersectionPoint))
                    {
                        // calculate alpha values for sorting multiple intersections points on a edge
                        float alpha;

                        // Insert intersection point into first polygon
                        alpha = GetAlpha(a, b, intersectionPoint);
                        if (alpha > 0f && alpha < 1f)
                        {
                            int index = slicedPoly1.IndexOf(a) + 1;
                            while (index < slicedPoly1.Count &&
                                   GetAlpha(a, b, slicedPoly1[index]) <= alpha)
                            {
                                ++index;
                            }
                            slicedPoly1.Insert(index, intersectionPoint);
                        }

                        // Insert intersection point into second polygon
                        alpha = GetAlpha(c, d, intersectionPoint);
                        if (alpha > 0f && alpha < 1f)
                        {
                            int index = slicedPoly2.IndexOf(c) + 1;
                            while (index < slicedPoly2.Count &&
                                   GetAlpha(c, d, slicedPoly2[index]) <= alpha)
                            {
                                ++index;
                            }
                            slicedPoly2.Insert(index, intersectionPoint);
                        }
                    }
                }
            }

            // Check for very small edges
            for (int i = 0; i < slicedPoly1.Count; ++i)
            {
                int iNext = slicedPoly1.NextIndex(i);

                //If they are closer than the distance remove vertex
                if ((slicedPoly1[iNext] - slicedPoly1[i]).LengthSquared() <= ClipperEpsilonSquared)
                {
                    slicedPoly1.RemoveAt(i);
                    --i;
                }
            }
            for (int i = 0; i < slicedPoly2.Count; ++i)
            {
                int iNext = slicedPoly2.NextIndex(i);

                //If they are closer than the distance remove vertex
                if ((slicedPoly2[iNext] - slicedPoly2[i]).LengthSquared() <= ClipperEpsilonSquared)
                {
                    slicedPoly2.RemoveAt(i);
                    --i;
                }
            }
        }