Created
July 5, 2018 06:27
-
-
Save TouiSoraHe/cfc407b7408225a09b15b22827f9c1a9 to your computer and use it in GitHub Desktop.
Unity中穿过已经点生成平滑曲线
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class BezierCurve { | |
private static float scale = 0f; | |
/// <summary> | |
/// 缩放系数[0,1],0代表曲线,1代表原始线条 | |
/// </summary> | |
public static float Scale | |
{ | |
get | |
{ | |
return scale; | |
} | |
set | |
{ | |
scale = value; | |
} | |
} | |
public static List<Vector3> CreateCurve(List<Vector3> originPoint) | |
{ | |
int originCount = originPoint.Count; | |
List<Vector3> midpoints = new List<Vector3>(); | |
//生成中点 | |
for (int i = 0; i < originCount; i++) | |
{ | |
int nextI = (i + 1) % originCount; | |
float midpointsX = (originPoint[i].x + originPoint[nextI].x) / 2.0f; | |
float midpointsY = (originPoint[i].y + originPoint[nextI].y) / 2.0f; | |
midpoints.Add(new Vector3(midpointsX, midpointsY)); | |
} | |
//平移中点,index与originCount一一对应 | |
List<Vector3[]> extrapoints = new List<Vector3[]>(); | |
for (int i = 0; i < midpoints.Count; i++) | |
{ | |
int firstIndex = (midpoints.Count - 1 + i) % midpoints.Count; | |
int nextIndex = (midpoints.Count + i) % midpoints.Count; | |
Vector3 midPoint = new Vector3(); | |
midPoint.x = (midpoints[firstIndex].x + midpoints[nextIndex].x) / 2.0f; | |
midPoint.y = (midpoints[firstIndex].y + midpoints[nextIndex].y) / 2.0f; | |
Vector3 destPoint = originPoint[i]; | |
float offsetX = destPoint.x - midPoint.x; | |
float offsetY = destPoint.y - midPoint.y; | |
Vector3 point1 = new Vector3(midpoints[firstIndex].x + offsetX, midpoints[firstIndex].y + offsetY); | |
Vector3 point2 = new Vector3(midpoints[nextIndex].x + offsetX, midpoints[nextIndex].y + offsetY); | |
point1 -= (point1 - destPoint) * Scale; | |
point2 -= (point2 - destPoint) * Scale; | |
extrapoints.Add(new Vector3[]{point1,point2}); | |
} | |
//生成曲线 | |
List<Vector3> curvePoint = new List<Vector3>(); | |
{ | |
Vector3 p0 = originPoint[0]; | |
Vector3 p1 = extrapoints[1][0]; | |
Vector3 p2 = originPoint[1]; | |
List<Vector3> temp = GetBezier(p0, p1, p2); | |
temp.RemoveAt(temp.Count - 1); | |
curvePoint.AddRange(temp); | |
} | |
for (int i = 1; i < originPoint.Count - 2; i++) | |
{ | |
Vector3 p0 = originPoint[i]; | |
Vector3 p1 = extrapoints[i][1]; | |
Vector3 p2 = extrapoints[i + 1][0]; | |
Vector3 p3 = originPoint[i + 1]; | |
List<Vector3> temp = GetBezier(p0, p1, p2, p3); | |
temp.RemoveAt(temp.Count - 1); | |
curvePoint.AddRange(temp); | |
} | |
{ | |
Vector3 p0 = originPoint[originPoint.Count - 2]; | |
Vector3 p1 = extrapoints[originPoint.Count - 2][1]; | |
Vector3 p2 = originPoint[originPoint.Count - 1]; | |
List<Vector3> temp = GetBezier(p0, p1, p2); | |
temp.RemoveAt(temp.Count - 1); | |
curvePoint.AddRange(temp); | |
} | |
curvePoint.Add( | |
originPoint[originPoint.Count - 1] | |
); | |
return curvePoint; | |
} | |
//贝塞尔曲线 | |
public static List<Vector3> GetBezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, int pointCount = 10) | |
{ | |
List<Vector3> ret = new List<Vector3>(); | |
float delta = 1.0f / (pointCount - 1.0f); | |
for (int i = 0; i < pointCount; i++) | |
{ | |
ret.Add(Bezier(p0, p1, p2, p3, i * delta)); | |
} | |
return ret; | |
} | |
//贝塞尔曲线 | |
public static List<Vector3> GetBezier(Vector3 p0, Vector3 p1, Vector3 p2, int pointCount = 10) | |
{ | |
List<Vector3> ret = new List<Vector3>(); | |
float delta = 1.0f / (pointCount - 1.0f); | |
for (int i = 0; i < pointCount; i++) | |
{ | |
ret.Add(Bezier(p0, p1, p2, i * delta)); | |
} | |
return ret; | |
} | |
//三阶贝塞尔曲线 | |
private static Vector3 Bezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) | |
{ | |
return p0 * Mathf.Pow(1 - t, 3) + 3 * p1 * t * Mathf.Pow(1 - t, 2) + 3 * p2 * t * t * (1 - t) + p3 * t * t * t; | |
} | |
private static Vector3 Bezier(Vector3 p0, Vector3 p1, Vector3 p2, float t) | |
{ | |
return p0 * Mathf.Pow(1 - t, 2) + 2 * t * (1 - t) * p1 + t * t * p2; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment