using UnityEngine; namespace XFramework.UIExtensions { /** * Created by vivi on 16/5/11. */ public class BezierUtils { public float P0x; public float P1x; public float P2x; public float P3x; public float P0y; public float P1y; public float P2y; public float P3y; public BezierUtils(float p0x, float p0y, float p1x, float p1y, float p2x, float p2y, float p3x, float p3y) { P0x = p0x; P0y = p0y; P1x = p1x; P1y = p1y; P2x = p2x; P2y = p2y; P3x = p3x; P3y = p3y; } public BezierUtils(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3) { P0x = p0.x; P0y = p0.y; P1x = p1.x; P1y = p1.y; P2x = p2.x; P2y = p2.y; P3x = p3.x; P3y = p3.y; } public float beze_x(float t) { float it = 1 - t; return it * it * it * P0x + 3 * it * it * t * P1x + 3 * it * t * t * P2x + t * t * t * P3x; } public float beze_y(float t) { float it = 1 - t; return it * it * it * P0y + 3 * it * it * t * P1y + 3 * it * t * t * P2y + t * t * t * P3y; } //------------------------------------------------------------------------------------- public float beze_speed_x(float t) { float it = 1 - t; return -3 * P0x * it * it + 3 * P1x * it * it - 6 * P1x * it * t + 6 * P2x * it * t - 3 * P2x * t * t + 3 * P3x * t * t; } public float beze_speed_y(float t) { float it = 1 - t; return -3 * P0y * it * it + 3 * P1y * it * it - 6 * P1y * it * t + 6 * P2y * it * t - 3 * P2y * t * t + 3 * P3y * t * t; } private float beze_speed(float t) { float sx = beze_speed_x(t); float sy = beze_speed_y(t); return (float)Mathf.Sqrt(Mathf.Pow(sx, 2) + Mathf.Pow(sy, 2)); } //------------------------------------------------------------------------------------- private float beze_length(float t) { float LATESTCOUNT = 10000; int steps = (int)Mathf.Ceil(LATESTCOUNT * t); if (steps == 0) return 0; if (steps % 2 != 0) steps++; float halfSteps = steps * .5f; float nSum = 0; float n1Sum = 0; float disStep = t / steps; for (int i = 0; i < halfSteps; i++) { n1Sum += beze_speed((2 * i + 1) * disStep); nSum += beze_speed(2 * i * disStep); } return (beze_speed(0) + beze_speed(1) + 2 * n1Sum + 4 * nSum) * disStep / 3; } //------------------------------------------------------------------------------------- private float beze_even(float t) { float len = t * beze_length(1); float uc = 0; do { float ulen = beze_length(t); float uspeed = beze_speed(t); uc = t - (ulen - len) / uspeed; if (Mathf.Abs(uc - t) < 0.0001) break; t = uc; } while (true); return uc; } private float totallength = -1; public float getTotalLength() { if (totallength < 0) totallength = beze_length(1); return totallength; } public Vector2 getPosition(float t) { return new Vector2(beze_x(t), beze_y(t)); } } }