Skip to content

Instantly share code, notes, and snippets.

@N-Carter
Created June 16, 2011 23:02
Show Gist options
  • Save N-Carter/1030522 to your computer and use it in GitHub Desktop.
Save N-Carter/1030522 to your computer and use it in GitHub Desktop.
Various experiments in spline interpolation
using UnityEngine;
using System.Collections;
[AddComponentMenu("Paths/Path Test")]
public class PathTest : MonoBehaviour
{
public Transform[] m_Transforms;
public int m_Divisions;
public float m_Tension;
public float m_Bias;
protected void OnDrawGizmos()
{
if(m_Transforms != null && m_Transforms.Length < 4)
return;
foreach(var t in m_Transforms)
{
if(t == null)
return;
Gizmos.DrawSphere(t.position, 0.1f);
}
for(int segment = 0; segment < m_Transforms.Length - 3; ++segment)
{
// Vector3[] vertices = EvaluateBezierSpline(
Vector3[] vertices = EvaluateHermiteSpline(
m_Transforms[segment].position,
m_Transforms[segment + 1].position,
m_Transforms[segment + 2].position,
m_Transforms[segment + 3].position,
m_Tension, m_Bias,
m_Divisions);
for(int i = 0; i < vertices.Length - 1; ++i)
Gizmos.DrawLine(vertices[i], vertices[i + 1]);
}
}
public Vector3[] EvaluateBezierSpline(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, int divisions)
{
Vector3 v0 = (-p0 + p1 * 3 - p2 * 3 + p3) / 6.0f;
Vector3 v1 = (p0 * 3 - p1 * 6 + p2 * 3) / 6.0f;
Vector3 v2 = (p0 * -3 + p2 * 3) / 6.0f;
Vector3 v3 = (p0 + p1 * 4 + p2) / 6.0f;
var vertices = new Vector3[divisions + 1];
vertices[0] = v3;
for(int i = 1; i <= divisions; i++)
{
float t = (float)i / divisions;
vertices[i] = v3 + t * (v2 + t * (v1 + t * v0));
}
return vertices;
}
public Vector3[] EvaluateCubicSpline(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, int divisions)
{
var vertices = new Vector3[divisions + 1];
vertices[0] = p3;
for(int i = 1; i <= divisions; i++)
{
float t = (float)i / divisions;
float oneMinusT = 1.0f - t;
Vector3 t0 = p0 * t * t * t;
Vector3 t1 = p1 * 3.0f * oneMinusT * t * t;
Vector3 t2 = p2 * 3.0f * oneMinusT * oneMinusT * t;
Vector3 t3 = p3 * oneMinusT * oneMinusT * oneMinusT;
vertices[i] = t0 + t1 + t2 + t3;
}
return vertices;
}
public Vector3[] EvaluateCatmullRomSpline(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, int divisions)
{
var vertices = new Vector3[divisions + 1];
for(int i = 0; i <= divisions; i++)
{
float t = (float)i / divisions;
Vector3 t0 = p0 * ((-t + 2) * t - 1) * t * 0.5f;
Vector3 t1 = p1 * (((3 * t - 5) * t) * t + 2) * 0.5f;
Vector3 t2 = p2 * ((-3 * t + 4) * t + 1) * t * 0.5f;
Vector3 t3 = p3 * ((t - 1) * t * t) * 0.5f;
vertices[i] = t0 + t1 + t2 + t3;
}
return vertices;
}
public Vector3[] EvaluateHermiteSpline(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float tension, float bias, int divisions)
{
var vertices = new Vector3[divisions + 1];
for(int i = 0; i <= divisions; i++)
{
float t = (float)i / divisions;
float t2 = t * t;
float t3 = t2 * t;
Vector3 m0 = (p1 - p0) * (1 + bias) * (1 - tension) / 2 + (p2 - p1) * (1 - bias) * (1 - tension) / 2;
Vector3 m1 = (p2 - p1) * (1 + bias) * (1 - tension) / 2 + (p3 - p2) * (1 - bias) * (1 - tension) / 2;
float a0 = 2 * t3 - 3 * t2 + 1;
float a1 = t3 - 2 * t2 + t;
float a2 = t3 - t2;
float a3 = -2 * t3 + 3 * t2;
vertices[i] = a0 * p1 + a1 * m0 + a2 * m1 + a3 * p2;
}
return vertices;
}
public Vector3[] EvaluateQuadraticBezierSpline(Vector3 p0, Vector3 p1, Vector3 p2, int divisions)
{
var vertices = new Vector3[divisions + 1];
for(int i = 0; i <= divisions; i++)
{
float t = (float)i / divisions;
float oneMinusT = 1.0f - t;
vertices[i] = oneMinusT * oneMinusT * p0 + 2 * oneMinusT * t * p1 + t * t * p2;
}
return vertices;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment