两点直线补间
/// <summary>
/// 两点之间直线的坐标计算.
/// </summary>
/// <returns>The line paht help.</returns>
/// <param name="startPoint">起点.</param>
/// <param name="endPoint">终点.</param>
/// <param name="per">从起点到终点每间隔几米划分一个点.</param>
public static List<Vector3> ToLinePahtHelp(Vector3 startPoint, Vector3 endPoint, float per = 0.27f)
{
List<Vector3> pointList = new List<Vector3>(777);
Vector3 dir = (endPoint - startPoint).normalized;
Vector3 currentPoint = Vector3.zero; ;
float distance = Vector3.Distance(endPoint, startPoint);
int number = (int)(distance / per);
for (int i = 1; i < number + 1; i++)
{
currentPoint = startPoint + dir * (float)(i * per);
pointList.Add(currentPoint);
}
return pointList;
}
多点之间曲线补间
using System;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class Test_05 : MonoBehaviour
{
Transform a, b,c,d;
// Start is called before the first frame update
void Start()
{
a =GameObject.Find("Cube_A").transform;
b = GameObject.Find("Cube_B").transform;
c = GameObject.Find("Cube_C").transform;
d = GameObject.Find("Cube_D").transform;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
var pointList = new List<Transform>(777);
pointList.Add(a);
pointList.Add(b);
DebugDrawPath(CaulaterPath(pointList.Select(x => x.position).ToArray()), Color.red, 10f);
}
if (Input.GetKeyDown(KeyCode.Mouse1))
{
var pointList = new List<Transform>(777);
pointList.Add(a);
pointList.Add(b);
pointList.Add(c);
pointList.Add(d);
DebugDrawPath(CaulaterPath(pointList.Select(x=>x.position).ToArray()), Color.yellow, 10f);
}
}
/// <summary>
/// 多点之间曲线补间,计算出这些点曲线间隔
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static Vector3[] CaulaterPath(Vector3[] path)
{
Vector3[] vector3s = PathControlPointGenerator(path);
int SmoothAmount = path.Length * 20;
var points = new Vector3[SmoothAmount+1];
points[0] = Interp(vector3s, 0);
for (int i = 1; i <= SmoothAmount; i++)
{
float pm = (float)i / SmoothAmount;
Vector3 currPt = Interp(vector3s, pm);
points[i]=currPt;
}
return points;
}
/// <summary>
/// 绘制多点线段
/// </summary>
/// <param name="path"></param>
/// <param name="color"></param>
/// <param name="duration"></param>
public void DebugDrawPath(Vector3[] path, Color color = default(Color), float duration = 0.1f)
{
var length = path.Length;
for (int i = 0; i < length; i++)
{
var curr = path[i];
//最后一个点
if (i == length - 1)
{
var forwardPos = path[i - 1];
Debug.DrawLine(curr, forwardPos, color, duration);
}
else
{
var nextPos = path[i + 1];
Debug.DrawLine(curr, nextPos, color, duration);
}
}
}
private static Vector3[] PathControlPointGenerator(Vector3[] path)
{
Vector3[] suppliedPath;
Vector3[] vector3s;
//create and store path points:
suppliedPath = path;
//populate calculate path;
int offset = 2;
vector3s = new Vector3[suppliedPath.Length + offset];
Array.Copy(suppliedPath, 0, vector3s, 1, suppliedPath.Length);
vector3s[0] = vector3s[1] + (vector3s[1] - vector3s[2]);
vector3s[vector3s.Length - 1] = vector3s[vector3s.Length - 2] + (vector3s[vector3s.Length - 2] - vector3s[vector3s.Length - 3]);
//is this a closed, continuous loop? yes? well then so let's make a continuous Catmull-Rom spline!
if (vector3s[1] == vector3s[vector3s.Length - 2])
{
Vector3[] tmpLoopSpline = new Vector3[vector3s.Length];
Array.Copy(vector3s, tmpLoopSpline, vector3s.Length);
tmpLoopSpline[0] = tmpLoopSpline[tmpLoopSpline.Length - 3];
tmpLoopSpline[tmpLoopSpline.Length - 1] = tmpLoopSpline[2];
vector3s = new Vector3[tmpLoopSpline.Length];
Array.Copy(tmpLoopSpline, vector3s, tmpLoopSpline.Length);
}
return vector3s;
}
private static Vector3 Interp(Vector3[] pts, float t)
{
int numSections = pts.Length - 3;
int currPt = Mathf.Min(Mathf.FloorToInt(t * (float)numSections), numSections - 1);
float u = t * (float)numSections - (float)currPt;
Vector3 a = pts[currPt];
Vector3 b = pts[currPt + 1];
Vector3 c = pts[currPt + 2];
Vector3 d = pts[currPt + 3];
return .5f * (
(-a + 3f * b - 3f * c + d) * (u * u * u)
+ (2f * a - 5f * b + 4f * c - d) * (u * u)
+ (-a + c) * u
+ 2f * b);
}
}