Ejemplo n.º 1
0
    public Vector3[] CalculateEvenlySpacedPoints(float spacing, float resolution = 1)
    {
        List <Vector3> evenlySpacedPoints = new List <Vector3>();

        evenlySpacedPoints.Add(points[0]);
        Vector3 previousPoint         = points[0];
        float   dstSinceLastEvenPoint = 0;

        for (int segmentIndex = 0; segmentIndex < SegmentCount; segmentIndex++)
        {
            Vector3[] p = GetPointsInSegment(segmentIndex);
            float     controlNetLength = Vector3.Distance(p[0], p[1]) + Vector3.Distance(p[1], p[2])
                                         + Vector3.Distance(p[2], p[3]);
            float estimatedCurveLength = Vector3.Distance(p[0], p[3]) + controlNetLength * 0.5f;
            int   division             = Mathf.CeilToInt(estimatedCurveLength * resolution * 10);
            float t = 0;
            while (t <= 1f)
            {
                t += 1f / division;
                Vector3 pointOnCurve = Bezier.CalculateCubic(p[0], p[1], p[2], p[3], t);
                dstSinceLastEvenPoint += Vector3.Distance(previousPoint, pointOnCurve);

                while (dstSinceLastEvenPoint >= spacing)
                {
                    float   overShootDistance    = dstSinceLastEvenPoint - spacing;
                    Vector3 newEvenlySpacedPoint = pointOnCurve + (previousPoint - pointOnCurve).normalized * overShootDistance;
                    evenlySpacedPoints.Add(newEvenlySpacedPoint);
                    dstSinceLastEvenPoint = overShootDistance;
                    previousPoint         = newEvenlySpacedPoint;
                }
                previousPoint = pointOnCurve;
            }
        }
        return(evenlySpacedPoints.ToArray());
    }
Ejemplo n.º 2
0
    /// <summary>
    /// 计算平均放置点的位置
    /// </summary>
    /// <param name="spacing"></param>
    /// <param name="resolution"></param>
    /// <returns></returns>
    public Vector2[] CalculateEvenlySpacedPoints(float spacing, float resolution = 1)
    {
        List <Vector2> evenlySpacedPoints = new List <Vector2> {
            points[0]
        };
        //前一个点
        Vector2 prePoint = points[0];
        //这个点到上个平均放置点的距离
        float sinceLastEvenPointDistance = 0;

        for (int segmentIndex = 0; segmentIndex < NumSegments; segmentIndex++)
        {
            Vector2[] segmentPoints = GetPointsInSegment(segmentIndex);
            //锚点和控制点构成的三条线段的长度
            float controlPointsLineLength = Vector2.Distance(segmentPoints[0], segmentPoints[1]) +
                                            Vector2.Distance(segmentPoints[1], segmentPoints[2]) + Vector2.Distance(segmentPoints[2], segmentPoints[3]);
            //估算的贝塞尔曲线长度:锚点间距+锚点和控制点构成的三条线段的一半
            float estimatedCurveLength = Vector2.Distance(segmentPoints[0], segmentPoints[3]) + controlPointsLineLength / 2f;
            int   divisons             = Mathf.CeilToInt(estimatedCurveLength * resolution * 10);

            float t = 0;
            while (t <= 1)
            {
                t += 1f / divisons;
                //采样点
                Vector2 pointOnCurve = Bezier.CalculateCubic(segmentPoints[0], segmentPoints[1], segmentPoints[2],
                                                             segmentPoints[3], t);
                sinceLastEvenPointDistance += Vector2.Distance(prePoint, pointOnCurve);
                //如果距离超过了期望的平均点位置
                while (sinceLastEvenPointDistance >= spacing)
                {
                    //记录期望平均点位置
                    float   offset         = sinceLastEvenPointDistance - spacing;
                    Vector2 direction      = (prePoint - pointOnCurve).normalized;
                    Vector2 addEvenlyPoint = pointOnCurve + direction * offset;
                    evenlySpacedPoints.Add(addEvenlyPoint);
                    sinceLastEvenPointDistance = offset;
                    prePoint = addEvenlyPoint;
                }

                prePoint = pointOnCurve;
            }
        }

        return(evenlySpacedPoints.ToArray());
    }
Ejemplo n.º 3
0
    public Vector3 GetPoint(float t)
    {
        int i; // segment index

        if (t >= 1f)
        {
            t = 1f;
            i = points.Count - 4;
        }
        else
        {
            t  = Mathf.Clamp01(t) * SegmentCount;
            i  = (int)t;
            t -= i;
            i *= 3;
        }

        return(Bezier.CalculateCubic(points[i], points[i + 1], points[i + 2], points[i + 3], t));
    }
Ejemplo n.º 4
0
        protected override void UpdateTrail(TrailGraphics trail, float deltaTime)
        {
            if (!trail.activeSelf)
            {
                return;
            }

            int trailPointIdx = 0;

            for (int i = 0; i < controlPoints.Count; i++)
            {
                trail.points[trailPointIdx].position = controlPoints[i].position;

                trail.points[trailPointIdx].forwardDirection = controlPoints[i].forward;

                trailPointIdx++;
                if (i < controlPoints.Count - 1)
                {
                    Vector3 cp1, cp2;
                    float   distance = Vector3.Distance(controlPoints[i].position, controlPoints[i + 1].position) / 2;
                    if (i == 0)
                    {
                        cp1 = controlPoints[i].position + (controlPoints[i + 1].position - controlPoints[i].position).normalized * distance;
                    }
                    else
                    {
                        cp1 = controlPoints[i].position + (controlPoints[i + 1].position - controlPoints[i - 1].position).normalized * distance;
                    }

                    int nextIdx = i + 1;

                    if (nextIdx == controlPoints.Count - 1)
                    {
                        cp2 = controlPoints[nextIdx].position + (controlPoints[nextIdx - 1].position - controlPoints[nextIdx].position).normalized * distance;
                    }
                    else
                    {
                        cp2 = controlPoints[nextIdx].position + (controlPoints[nextIdx - 1].position - controlPoints[nextIdx + 1].position).normalized * distance;
                    }

                    TrailPoint current = trail.points[trailPointIdx - 1];
                    TrailPoint next    = trail.points[trailPointIdx + pointsInMiddle];

                    for (int j = 0; j < pointsInMiddle; j++)
                    {
                        float t = (((float)j + 1) / ((float)pointsInMiddle + 1));
                        trail.points[trailPointIdx].position  = Bezier.CalculateCubic(t, controlPoints[i].position, cp1, cp2, controlPoints[i + 1].position);
                        trail.points[trailPointIdx].timeSoFar = Mathf.Lerp(current.timeSoFar, next.timeSoFar, t);

                        trail.points[trailPointIdx].forwardDirection = Vector3.Lerp(current.forwardDirection, next.forwardDirection, t);

                        trailPointIdx++;
                    }
                }
            }

            int lastCPIdx   = (pointsInMiddle + 1) * (controlPoints.Count - 1);
            int prevCPIdx   = lastCPIdx - pointsInMiddle - 1;
            int activeCount = lastCPIdx + 1;

            float distance2Src = trail.points[prevCPIdx].distance2Src;

            for (int i = prevCPIdx + 1; i < activeCount; i++)
            {
                distance2Src += Vector3.Distance(trail.points[i - 1].position, trail.points[i].position);
                trail.points[i].distance2Src = distance2Src;
            }
        }