Skip to content

Instantly share code, notes, and snippets.

@TouiSoraHe
Created July 5, 2018 06:27
Show Gist options
  • Save TouiSoraHe/cfc407b7408225a09b15b22827f9c1a9 to your computer and use it in GitHub Desktop.
Save TouiSoraHe/cfc407b7408225a09b15b22827f9c1a9 to your computer and use it in GitHub Desktop.
Unity中穿过已经点生成平滑曲线
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