예제 #1
0
파일: Path.cs 프로젝트: aramayyes/NNDrives
        /// <summary>
        /// Gets points on the path that are evenly spaced with given value.
        /// </summary>
        /// <param name="spacing">Distance between points.</param>
        /// <param name="resolution">Time value.</param>
        /// <returns>Array of points that are evenly spaced on the curve.</returns>
        public Vector2[] CalculateEvenlySpacedPoints(float spacing, float resolution = 1)
        {
            var evenlySpacedPoints = new List <Vector2>
            {
                points[0]
            };

            Vector2 lastPoint = points[0];
            float   distanceSinceLastEvenPoint = 0;

            for (int i = 0; i < SegmentsCount; i++)
            {
                Vector2[] pointsInSegment = GetPointsInSegment(i);

                float controlNetLength = Vector2.Distance(pointsInSegment[0], pointsInSegment[1])
                                         + Vector2.Distance(pointsInSegment[1], pointsInSegment[2])
                                         + Vector2.Distance(pointsInSegment[2], pointsInSegment[3]);

                float estimatedCurveLength = Vector2.Distance(pointsInSegment[0], pointsInSegment[3]) + (controlNetLength / 2);
                int   divisions            = Mathf.CeilToInt((estimatedCurveLength * resolution) * 10);

                float t = 0;
                while (t <= 1)
                {
                    t += 1.0f / divisions;

                    // Get point on the curve
                    Vector2 pointOnCurve = BezierHelper.EvaluateCubic(pointsInSegment[0], pointsInSegment[1], pointsInSegment[2], pointsInSegment[3], t);
                    distanceSinceLastEvenPoint += Vector2.Distance(lastPoint, pointOnCurve);

                    /*
                     * If distance between the last point and the new one is less than spacing, then just ignore that new point.
                     * Otherwise if the distance is equal to spacing, add that point to evenly spaced points.
                     * And if the distance is more than spacing, then move that point back so that the distance becomes equal to
                     * spacing and that point to evenly spaced points.
                     */
                    while (distanceSinceLastEvenPoint >= spacing)
                    {
                        float   overshootDistance    = distanceSinceLastEvenPoint - spacing;
                        Vector2 newEvenlySpacedPoint = pointOnCurve + ((lastPoint - pointOnCurve).normalized * overshootDistance);

                        evenlySpacedPoints.Add(newEvenlySpacedPoint);

                        distanceSinceLastEvenPoint = overshootDistance;
                        lastPoint = newEvenlySpacedPoint;
                    }

                    lastPoint = pointOnCurve;
                }
            }

            return(evenlySpacedPoints.ToArray());
        }