当前位置:网站首页>Creation of unity Bezier curve
Creation of unity Bezier curve
2022-07-25 17:51:00 【Xiaosheng yunmu】
Unity Creation of Bezier curve
effect


Bezier curve principle
Commonly used Bezier curve , It is the mathematical curve of two-dimensional graphics application . Curve definition : The starting point 、 Termination point 、 The control points . By adjusting the control points , The shape of the Bezier curve changes .
First order straight line
How to put C C C The point is within the set time , from A A A Point to move to B B B spot ? Set a time here t , t ∈ ( 0 , 1 ) t ,t \in(0,1) t,t∈(0,1),

Set up t t t Within time O A ⃗ \vec{OA} OA It is reduced to O E ⃗ \vec{OE} OE, O B ⃗ \vec{OB} OB The unit vector of is extended to O F ⃗ \vec{OF} OF.
O E ⃗ = O A ⃗ ( 1 − t ) \vec{OE}=\vec{OA}(1-t) OE=OA(1−t)
O F ⃗ = O B ⃗ × t \vec{OF}=\vec{OB}\times t OF=OB×t
O C ⃗ = O A ⃗ ( 1 − t ) + O B ⃗ × t \vec{OC}=\vec{OA}(1-t)+\vec{OB}\times t OC=OA(1−t)+OB×t
So you can get C C C The point is within the set time , from A A A Point to move to B B B Interpolation of points .
Vector3 AB = (1 - t) * OA + t * OB;
Second order curve

The second-order algorithm is based on the first-order Algorithm , That is to deal with... Separately A B ⃗ \vec{AB} AB and B C ⃗ \vec{BC} BC
Vector3 AB = (1 - t) * OA + t * OB;
Vector3 BC = (1 - t) * OB + t * OC;
then A B ⃗ \vec{AB} AB and B C ⃗ \vec{BC} BC It also performs first-order algorithm processing
Vector3 ABC = (1 - t) * AB + t * BC;
Third order curve
Third order is similar to bivalent , Keep accumulating .
Vector3 AB = (1 - t) * OA + t * OB;
Vector3 BC = (1 - t) * OB + t * OC;
Vector3 CD = (1 - t) * OC + t * OD;
Vector3 ABC = (1 - t) * AB + t * BC;
Vector3 BCD = (1 - t) * BC + t * CD;
result = (1 - t) * ABC + t * BCD;
The next four high-level are similar . Commonly used in daily life is the third order , That is, four points determine a curve .
stay unity Application in
The aim is to pass the Bessel curve , Get the point on the curve , In order to establish motion path data .
Through the editing extension tool of the interface , Build Bessel tools .


#if UNITY_EDITOR
public class BesselPathCreat : ScriptableWizard
{
public string Name = "Path";
// The radius of the point
public float radius = 1;
// Density of curve points
public int densityCurve = 1;
/// <summary>
/// Draw curve control points -- Sub objects of this script
/// </summary>
public List<GameObject> PathPointList = new List<GameObject>();
DrawGizmosLine drawGizmosLint;
GameObject game;
[MenuItem("FrameWorkSong//FrameWork/3. Create Bessel path ", false, 3)]
static void CreateBasselPath()
{
ScriptableWizard.DisplayWizard<BesselPathCreat>("CreateBasselPath", " establish ", " Add some ");
}
/// <summary>
/// Create button trigger
/// </summary>
void OnWizardCreate()
{
if (PathPointList.Count > 4)
{
var level = ScriptableObject.CreateInstance<BasselPathTemplet>();
level.BasselPathPoints = drawGizmosLint.CurvePoints;
AssetDatabase.CreateAsset(level, @"Assets/FrameWorkSong/Data/" + Name + ".asset");// Create resources in the incoming path
AssetDatabase.SaveAssets(); // Storage resources
AssetDatabase.Refresh(); // Refresh
}
DestroyObject();
}
/// <summary>
/// Turn off the trigger
/// </summary>
void DestroyObject()
{
if (game)
{
DestroyImmediate(game);
}
for (int i = 0; i < PathPointList.Count; i++)
{
DestroyImmediate(PathPointList[i]);
}
}
void OnWizardUpdate()
{
}
/// <summary>
/// Add a button to trigger
/// </summary>
// When the user presses the "Apply" button OnWizardOtherButton is called.
void OnWizardOtherButton()
{
if (PathPointList.Count == 0)
{
game = new GameObject();
drawGizmosLint = game.AddComponent<DrawGizmosLine>();
}
BasselPath basselPath = new BasselPath();
DrawGizmosPointLine drawGizmos = basselPath.MianPiont.AddComponent<DrawGizmosPointLine>();
PathPointList.Add(basselPath.FrontPiont);
PathPointList.Add(basselPath.MianPiont);
PathPointList.Add(basselPath.BackePiont);
drawGizmos.SelfPoint = basselPath.Piont;
drawGizmosLint.SelfPoint = PathPointList;
drawGizmosLint.densityCurve = densityCurve;
drawGizmosLint.radius = radius;
}
void OnDestroy()
{
DestroyObject();
}
}
#endif
It's used here , Class to create editor wizards . Details can be found in the official website api https://docs.unity3d.com/cn/current/ScriptReference/ScriptableWizard.html
Bessel's creation method
public class BasselPath
{
List<GameObject> piont = new List<GameObject>();
GameObject mianPiont;
GameObject frontPiont;
GameObject backePiont;
public BasselPath()
{
mianPiont = new GameObject();
mianPiont.transform.position = Vector3.zero;
frontPiont = new GameObject();
frontPiont.transform.position = Vector3.zero + (Vector3.right * 5);
backePiont = new GameObject();
backePiont.transform.position = Vector3.zero + (Vector3.left * 5);
piont.Add(frontPiont);
piont.Add(mianPiont);
piont.Add(backePiont);
backePiont.transform.SetParent(mianPiont.transform);
frontPiont.transform.SetParent(mianPiont.transform);
mianPiont.AddComponent<DrawGizmosPoint>();
frontPiont.AddComponent<DrawGizmosPoint>();
backePiont.AddComponent<DrawGizmosPoint>();
}
public GameObject MianPiont { get => mianPiont; set => mianPiont = value; }
public GameObject FrontPiont { get => frontPiont; }
public GameObject BackePiont { get => backePiont; }
public List<GameObject> Piont { get => piont; }
}
/// <summary>
/// Draw nodes
/// </summary>
public class DrawGizmosPoint : MonoBehaviour
{
public float radius = 1;
private void OnDrawGizmos()
{
// Draw points
Gizmos.color = Color.blue;
Gizmos.DrawSphere(transform.position, radius * 0.5f);
}
}
/// <summary>
/// Draw nodal lines
/// </summary>
public class DrawGizmosPointLine : MonoBehaviour
{
public float radius = 1;
public List<GameObject> SelfPoint = new List<GameObject>();
private void OnDrawGizmos()
{
List<Vector3> controlPointPos = SelfPoint.Select(point => point.transform.position).ToList();
// Draw the curve control point line
Gizmos.color = Color.red;
for (int i = 0; i < controlPointPos.Count - 1; i += 3)
{
Gizmos.DrawLine(controlPointPos[i], controlPointPos[i + 1]);
Gizmos.DrawLine(controlPointPos[i + 1], controlPointPos[i + 2]);
}
}
}
/// <summary>
/// draw a curve
/// </summary>
public class DrawGizmosLine : MonoBehaviour
{
public float radius;
public int densityCurve;
public List<GameObject> SelfPoint;
public List<Vector3> CurvePoints;
private void OnDrawGizmos()
{
List<Vector3> controlPointPos = SelfPoint.Select(point => point.transform.position).ToList();
if (controlPointPos != null)
{
CurvePoints = GetDrawingPoints(controlPointPos, densityCurve);
}
// draw a curve
if (CurvePoints.Count >= 4)
{
Gizmos.color = Color.green;
// Point density
foreach (var item in CurvePoints)
{
Gizmos.DrawSphere(item, radius * 0.5f);
}
// curve
for (int i = 0; i < CurvePoints.Count - 1; i++)
{
Gizmos.DrawLine(CurvePoints[i], CurvePoints[i + 1]);
}
}
}
/// <summary>
/// Get drawing points
/// </summary>
/// <param name="controlPoints"></param>
/// <param name="segmentsPerCurve"></param>
/// <returns></returns>
public List<Vector3> GetDrawingPoints(List<Vector3> controlPoints, int segmentsPerCurve)
{
List<Vector3> points = new List<Vector3>();
// The starting point of the next paragraph and the ending point of the upper paragraph are the same , So it is i+=3
for (int i = 1; i < controlPoints.Count - 4; i += 3)
{
var p0 = controlPoints[i];
var p1 = controlPoints[i + 1];
var p2 = controlPoints[i + 2];
var p3 = controlPoints[i + 3];
float dis = Vector3.Distance(p0, p3);
int count = Mathf.CeilToInt(segmentsPerCurve * dis);
if (count < segmentsPerCurve)
{
count = segmentsPerCurve;
}
for (int j = 0; j <= count; j++)
{
var t = j / (float)count;
points.Add(CalculateBezierPoint(t, p0, p1, p2, p3));
}
}
return points;
}
// Third order formula
Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
{
Vector3 result;
Vector3 p0p1 = (1 - t) * p0 + t * p1;
Vector3 p1p2 = (1 - t) * p1 + t * p2;
Vector3 p2p3 = (1 - t) * p2 + t * p3;
Vector3 p0p1p2 = (1 - t) * p0p1 + t * p1p2;
Vector3 p1p2p3 = (1 - t) * p1p2 + t * p2p3;
result = (1 - t) * p0p1p2 + t * p1p2p3;
return result;
}
}
边栏推荐
- Nineteen year old summary
- Redis source code and design analysis -- 18. Analysis of redis network connection Library
- 世界各地的标志性建筑物
- How to rectify the unqualified EMC of electronic products?
- UFT(QTP)-总结点与自动化测试框架
- Product life cycle to be considered in making intelligent hardware
- New and malloc
- 面试官:说说 log.Fatal 和 panic 的区别
- Excel表格 / WPS表格中怎么在下拉滚动时让第一行标题固定住?
- 【解决方案】Microsoft Edge 浏览器 出现“无法访问该页面”问题
猜你喜欢
随机推荐
mysql case when
11、照相机与透镜
I'm also drunk. Eureka delayed registration and this pit!
After consulting about how to deal with DDL in Flink SQL client, how to add fields and jobs to the mapping table in Fink SQL?
SLA 、SLO & SLI
Is it safe to open a futures account online? How to apply for a low handling fee?
电子产品“使用”和“放置”哪个寿命更长??
New and malloc
Redis源码与设计剖析 -- 15.RDB持久化机制
TME2022校园招聘后台开发/运营开发/业务运维/应用开发笔试(I)编程题的一点自我分析
Cross validation (CV) learning notes
交友活动记录
Calculation date or date formatting
OSPF --- open shortest priority path protocol
Lwip之内存与包缓冲管理
Several implementations of PHP to solve concurrency problems
Excel表格 / WPS表格中怎么在下拉滚动时让第一行标题固定住?
RedisTemplate解决高并发下秒杀系统库存超卖方案 — Redis事务+乐观锁机制
十九岁的总结
计算日期或日期格式化








