Ejemplo n.º 1
0
    /// <summary>
    /// Distance between a point and the shape.
    /// </summary>
    /// <param name="pt">Test point</param>
    /// <returns>Distance from point to nearest point on shape</returns>
    public override float Distance(Vector2 pt)
    {
        float distance = Mathf.Infinity;
        float segDist;

        int count = closed ? vertices.Length : vertices.Length - 1;

        for (int i = 0; i < count; i++)
        {
            Vertex vert     = vertices[i];
            Vertex vertNext = vertices[NextIndex(i)];

            if (vertices[i].segmentCurves)
            {
                segDist = VectorShapeUtils.DistancePointToBezierCurve(pt, vert.position, vert.exitCP, vertNext.enterCP, vertNext.position);
            }
            else
            {
                segDist = VectorShapeUtils.DistancePointToLineSegment(pt, vert.position, vertNext.position);
            }

            if (segDist < distance)
            {
                distance = segDist;
            }
        }

        return(distance);
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Build a 2D bounding box for the shape.
    /// </summary>
    protected override void GenerateBounds()
    {
        // TO DO
        // http://www.iquilezles.org/www/articles/bezierbbox/bezierbbox.htm
        int            bezierSteps = VectorShapeUtils.bezierSteps;
        List <Vector2> pointList   = new List <Vector2>();
        float          step        = 1f / bezierSteps;

        for (int i = 0; i < vertices.Length; i++)
        {
            Vertex vert = vertices[i];

            pointList.Add(vert.position);
            if (vert.segmentCurves)
            {
                Vertex vertNext = vertices[NextIndex(i)];
                float  t        = step;
                for (int j = 1; j < bezierSteps; j++)
                {
                    pointList.Add(VectorShapeUtils.EvaluateCubicCurve(vert.position, vert.exitCP, vertNext.enterCP, vertNext.position, t));
                    t += step;
                }
            }
        }

        shapeBounds = VectorUtils.Bounds(pointList);
        boundsDirty = false;
    }
Ejemplo n.º 3
0
 /// <summary>
 /// Build a 2D bounding box for the shape.
 /// </summary>
 protected override void GenerateBounds()
 {
     if (_components.Count == 0)
     {
         shapeBounds = new Rect();
     }
     else
     {
         shapeBounds = _components[0].ShapeBounds;
         for (int i = 1; i < _components.Count; i++)
         {
             shapeBounds = VectorShapeUtils.RectUnion(shapeBounds, _components[i].ShapeBounds);
         }
     }
     boundsDirty = false;
 }
Ejemplo n.º 4
0
    /// <summary>
    /// Distance between a point and the shape.
    /// </summary>
    /// <param name="pt">Test point</param>
    /// <param name="mode">Snap modes to consider</param>
    /// <returns>Distance from point to nearest point on shape</returns>
    public override SnapPoint GetSnap(Vector2 pt, SnapPoint.Mode mode)
    {
        SnapPoint snap     = new SnapPoint();
        float     distance = float.MaxValue;

        if ((mode & SnapPoint.Mode.Center) != 0)
        {
            if (closed && (vertices.Length > 0))
            {
                Vector2 center = new Vector2();
                for (int i = 0; i < vertices.Length; i++)
                {
                    center += vertices[i].position;
                }

                center /= vertices.Length;
                float d = Vector2.Distance(pt, center);
                if (d < distance)
                {
                    distance   = d;
                    snap.mode  = SnapPoint.Mode.Center;
                    snap.point = center;
                }
            }
        }

        if ((mode & SnapPoint.Mode.Endpoint) != 0)
        {
            for (int i = 0; i < vertices.Length; i++)
            {
                float d = Vector2.Distance(pt, vertices[i].position);
                if (d < distance)
                {
                    distance   = d;
                    snap.mode  = SnapPoint.Mode.Endpoint;
                    snap.point = vertices[i].position;
                }
            }
        }

        if ((mode & SnapPoint.Mode.Midpoint) != 0)
        {
            int count = closed ? vertices.Length : vertices.Length - 1;
            for (int i = 0; i < count; i++)
            {
                Vertex  vert     = vertices[i];
                Vertex  vertNext = vertices[NextIndex(i)];
                Vector2 midPoint;

                if (vertices[i].segmentCurves)
                {
                    midPoint = VectorShapeUtils.EvaluateCubicCurve(vert.position, vert.exitCP, vertNext.enterCP, vertNext.position, 0.5f);
                }
                else
                {
                    midPoint = (vert.position + vertNext.position) / 2f;
                }
                float d = Vector2.Distance(pt, midPoint);
                if (d < distance)
                {
                    distance   = d;
                    snap.mode  = SnapPoint.Mode.Midpoint;
                    snap.point = midPoint;
                }
            }
        }

        if ((mode & SnapPoint.Mode.Edge) != 0)
        {
            int count = closed ? vertices.Length : vertices.Length - 1;
            for (int i = 0; i < count; i++)
            {
                Vertex  vert     = vertices[i];
                Vertex  vertNext = vertices[NextIndex(i)];
                Vector2 closest;

                if (vertices[i].segmentCurves)
                {
                    closest = VectorShapeUtils.ClosetPointOnBezierCurve(pt, vert.position, vert.exitCP, vertNext.enterCP, vertNext.position);
                }
                else
                {
                    closest = VectorShapeUtils.ClosestPointOnLineSegment(pt, vert.position, vertNext.position);
                }
                float d = Vector2.Distance(pt, closest);
                if (d < distance)
                {
                    distance   = d;
                    snap.mode  = SnapPoint.Mode.Edge;
                    snap.point = closest;
                }
            }
        }

        return(snap);
    }
Ejemplo n.º 5
0
    /// <summary>
    /// Build a 2D collider for the shape.
    /// </summary>
    protected override void AddColliderToGO(GameObject target)
    {
        PolygonCollider2D[] polyColliders = target.GetComponents <PolygonCollider2D>();
        PolygonCollider2D   polyCollider  = null;

        for (int i = 0; i < polyColliders.Length; i++)
        {
            if (polyColliders[i].name == this.guid)
            {
                polyCollider = polyColliders[i];
            }
        }

        EdgeCollider2D[] edgeColliders = target.GetComponents <EdgeCollider2D>();
        EdgeCollider2D   edgeCollider  = null;

        for (int i = 0; i < edgeColliders.Length; i++)
        {
            if (edgeColliders[i].name == this.guid)
            {
                edgeCollider = edgeColliders[i];
                break;
            }
        }

        if (closed)
        {
            if (polyCollider == null)
            {
                polyCollider      = target.AddComponent <PolygonCollider2D>();
                polyCollider.name = this.guid;
            }

            if (edgeCollider != null)
            {
                Object.Destroy(edgeCollider);
            }
        }
        else
        {
            if (edgeCollider == null)
            {
                edgeCollider      = target.AddComponent <EdgeCollider2D>();
                edgeCollider.name = this.guid;
            }

            if (polyCollider != null)
            {
                Object.Destroy(polyCollider);
            }
        }

        int            bezierSteps = VectorShapeUtils.bezierSteps;
        List <Vector2> pointList   = new List <Vector2>();
        float          step        = 1f / bezierSteps;

        int edgeCount = closed ? vertices.Length : vertices.Length - 1;

        for (int i = 0; i < edgeCount; i++)
        {
            Vertex vert = vertices[i];

            pointList.Add(vert.position);
            if (vert.segmentCurves)
            {
                Vertex vertNext = vertices[NextIndex(i)];
                float  t        = step;
                for (int j = 1; j < bezierSteps; j++)
                {
                    pointList.Add(VectorShapeUtils.EvaluateCubicCurve(vert.position, vert.exitCP, vertNext.enterCP, vertNext.position, t));
                    t += step;
                }
            }
        }

        if (closed)
        {
            polyCollider.points = pointList.ToArray();
        }
        else
        {
            edgeCollider.points = pointList.ToArray();
        }
    }