Unity中贝塞尔曲线(Bezier),实现二阶和三阶
下图为贝塞尔曲线一阶,二阶,三阶,四阶。
图片来自 https://www.jasondavies.com/animated-bezier/
刚开始知道贝塞尔曲线的时候觉得这东西好难,今天花了点时间想了一下
发现在Unity中实现贝塞尔曲线还是很容易的。
贝塞尔曲线二阶的原理:
p0到p1的点(红色0到1),与p1到p2的点(黄色0到1)连接成的线(蓝色0到1),这条线经过的轨迹就是贝塞尔曲线。
先上动图:
代码如下:
/// <summary> /// 曲线圆滑度 /// </summary> public int nultiple = 5; public List<Vector3> allPoints = new List<Vector3>(); public RectTransform p1; public RectTransform p2; public RectTransform p3; private void Update() { CreatTwoBezierCurve(p1.position, p2.position, p3.position); for (int i = 1; i < allPoints.Count; i++) { Debug.DrawLine(allPoints[i - 1], allPoints[i], Color.blue); } } /// <summary> ///二阶贝塞尔 /// </summary> /// <param name="startPoint"></param> /// <param name="endPoint"></param> /// <param name="middlePoint"></param> public void CreatTwoBezierCurve(Vector3 startPoint, Vector3 endPoint, Vector3 middlePoint) { allPoints.Clear(); for (int i = 0; i < nultiple; i++) { float tempPercent = (float)i / (float)nultiple; float dis1 = Vector3.Distance(startPoint, middlePoint); Vector3 point1 = startPoint + Vector3.Normalize(middlePoint - startPoint) * dis1 * tempPercent; float dis2 = Vector3.Distance(middlePoint, endPoint); Vector3 point2 = middlePoint + Vector3.Normalize(endPoint - middlePoint) * dis2 * tempPercent; float dis3 = Vector3.Distance(point1, point2); Vector3 linePoint = point1 + Vector3.Normalize(point2 - point1) * dis3 * tempPercent; allPoints.Add(linePoint); } allPoints.Add(endPoint); }
其中p1是起点,p2是终点,p3是中间控制点。
三阶原理跟二阶相同:
先上动图:
再上代码:
/// <summary> /// 曲线圆滑度 /// </summary> public int nultiple = 5; public List<Vector3> allPoints = new List<Vector3>(); public RectTransform p1; public RectTransform p2; public RectTransform p3; public RectTransform p4; private void Update() { // CreatTwoBezierCurve(p1.position, p2.position, p3.position); CreatThreeBezierCurve(p1.position, p2.position, p3.position, p4.position); for (int i = 1; i < allPoints.Count; i++) { Debug.DrawLine(allPoints[i - 1], allPoints[i], Color.blue); } } /// <summary> /// 三阶贝塞尔 /// </summary> /// <param name="startPoint"></param> /// <param name="endPoint"></param> /// <param name="middlePoint1"></param> public void CreatThreeBezierCurve(Vector3 startPoint, Vector3 endPoint, Vector3 middlePoint1, Vector3 middlePoint2) { allPoints.Clear(); for (int i = 0; i < nultiple; i++) { float tempPercent = (float)i / (float)nultiple; float dis1 = Vector3.Distance(startPoint, middlePoint1); Vector3 pointL1 = startPoint + Vector3.Normalize(middlePoint1 - startPoint) * dis1 * tempPercent; float dis2 = Vector3.Distance(middlePoint1, middlePoint2); Vector3 pointL2 = middlePoint1 + Vector3.Normalize(middlePoint2 - middlePoint1) * dis2 * tempPercent; float dis3 = Vector3.Distance(pointL1, pointL2); Vector3 pointLeft = pointL1 + Vector3.Normalize(pointL2 - pointL1) * dis3 * tempPercent; float dis4 = Vector3.Distance(middlePoint2, endPoint); Vector3 pointR1 = middlePoint2 + Vector3.Normalize(endPoint - middlePoint2) * dis4 * tempPercent; float dis5 = Vector3.Distance(pointL2, pointR1); Vector3 pointRight = pointL2 + Vector3.Normalize(pointR1 - pointL2) * dis5 * tempPercent; float disLeftAndRight = Vector3.Distance(pointLeft, pointRight); Vector3 linePoint = pointLeft + Vector3.Normalize(pointRight - pointLeft) * disLeftAndRight * tempPercent; allPoints.Add(linePoint); } allPoints.Add(endPoint); }
就这样。拜拜~