using UnityEngine;
using System.Collections;
public static class Bezier{
////二阶贝塞尔曲线方程式 插值之后再插值
//public static Vector3 GetPoint(Vector3 p0,Vector3 p1,Vector3 p2,float t)
//{
// t = Mathf.Clamp01(t);
// float oneMinusT = 1f - t;
// return
// oneMinusT * oneMinusT * p0 +
// 2f * oneMinusT * t * p1 +
// t * t * p2;
//}
////求二阶贝塞尔曲线的一阶导数
//public static Vector3 GetFirstDerivative(Vector3 p0,Vector3 p1,Vector3 p2,float t)
//{
// return
// 2f * (1f - t) * (p1 - p0) +
// 2f * t * (p2 - p1);
//}
//三阶贝塞尔曲线方程式 插值之后再插值继续插值
public static Vector3 GetPoint(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
t = Mathf.Clamp01(t);
float oneMinusT = 1f - t;
return
oneMinusT * oneMinusT * oneMinusT * p0 +
3f * oneMinusT * oneMinusT * t * p1 +
3f * oneMinusT * t * t * p2 +
t * t * t * p3;
}
//求三阶贝塞尔曲线的一阶导数
public static Vector3 GetFirstDerivative(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
t = Mathf.Clamp01(t);
float oneMinusT = 1f - t;
return
3f * oneMinusT * oneMinusT * (p1 - p0) +
6f * oneMinusT * t * (p2 - p1) +
3f * t * t * (p3 - p2);
}
}
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(Line))]
public class LineInspector : Editor {
private void OnSceneGUI()
{
Line line = target as Line;
Transform handleTransform = line.transform;
Quaternion handleRotation = Tools.pivotRotation == PivotRotation.Local ?
handleTransform.rotation : Quaternion.identity;
Vector3 p0 = handleTransform.TransformPoint(line.p0);
Vector3 p1 = handleTransform.TransformPoint(line.p1);
Handles.color = Color.white;
Handles.DrawLine(p0, p1);
Handles.DoPositionHandle(p0, handleRotation);
Handles.DoPositionHandle(p1, handleRotation);
EditorGUI.BeginChangeCheck();
p0 = Handles.DoPositionHandle(p0, handleRotation);
if(EditorGUI.EndChangeCheck())
{
Undo.RecordObject(line, "Move Point");
EditorUtility.SetDirty(line);
line.p0 = handleTransform.InverseTransformPoint(p0);
}
EditorGUI.BeginChangeCheck();
p1 = Handles.DoPositionHandle(p1, handleRotation);
if(EditorGUI.EndChangeCheck())
{
Undo.RecordObject(line, "Move Point");
EditorUtility.SetDirty(line);
line.p1 = handleTransform.InverseTransformPoint(p1);
}
}
}
using UnityEngine;
using UnityEditor;
using System.Collections;
[CustomEditor(typeof(BezierCurve))]
public class BezierCurveInspector : Editor
{
private BezierCurve curve;
private Transform handleTransform;
private Quaternion handleRotation;
private const int lineSteps = 10;
private const float directionScale = 0.5f;
private void OnSceneGUI()
{
curve = target as BezierCurve;
handleTransform = curve.transform;
handleRotation = Tools.pivotRotation == PivotRotation.Local ?
handleTransform.rotation : Quaternion.identity;
Vector3 p0 = ShowPoint(0);
Vector3 p1 = ShowPoint(1);
Vector3 p2 = ShowPoint(2);
Vector3 p3 = ShowPoint(3);
Handles.color = Color.gray;
Handles.DrawLine(p0, p1);
Handles.DrawLine(p2, p3);
ShowDirections();
Handles.DrawBezier(p0, p3, p1, p2, Color.white, null, 2f);
}
private Vector3 ShowPoint(int index)
{
Vector3 point = handleTransform.TransformPoint(curve.points[index]);
EditorGUI.BeginChangeCheck();
point = Handles.DoPositionHandle(point, handleRotation);
if(EditorGUI.EndChangeCheck())
{
Undo.RecordObject(curve, "Move Point");
EditorUtility.SetDirty(curve);
curve.points[index] = handleTransform.InverseTransformPoint(point);
}
return point;
}
private void ShowDirections()
{
Handles.color = Color.green;
Vector3 point = curve.GetPoint(0f);
Handles.DrawLine(point, point + curve.GetDirection(0f) * directionScale);
for (int i = 1; i <= lineSteps; i++)
{
point = curve.GetPoint(i / (float)lineSteps);
Handles.DrawLine(point, point + curve.GetDirection(i / (float)lineSteps) * directionScale);
}
}
}
using UnityEngine;
using System.Collections;
public class BezierCurve : MonoBehaviour {
public Vector3[] points;
public void Reset()
{
points = new Vector3[]{
new Vector3(1,0,0),
new Vector3(2,0,0),
new Vector3(3,0,0),
new Vector4(4,0,0)
};
}
public Vector3 GetPoint(float t)
{
return transform.TransformPoint(Bezier.GetPoint(points[0],points[1],points[2],points[3],t));
}
//一阶倒数表示曲线的弯曲程度
public Vector3 GetVelocity(float t)
{
return transform.TransformPoint(Bezier.GetPoint(points[0], points[1], points[2], points[3], t)) -
transform.position;
}
//切线向量归一化
public Vector3 GetDirection(float t)
{
return GetVelocity(t).normalized;
}
}
using UnityEngine;
using System.Collections;
public class Line : MonoBehaviour {
public Vector3 p0, p1;
}
贝塞尔曲线
最新推荐文章于 2025-01-13 22:37:24 发布