当前位置:网站首页>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;
}
}
边栏推荐
- 双向链表的基本操作
- MySQL数据库常用命令
- Redistemplate solves the problem of oversold inventory in the seckill system with high speed - redis transaction + optimistic lock mechanism
- Trooper
- Thesis reading_ Multi task learning_ MMoE
- Postman get started quickly
- 约瑟夫环问题
- Product life cycle to be considered in making intelligent hardware
- go defer与recover简单笔记
- 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?
猜你喜欢

2022/7/23

Redistemplate solves the problem of oversold inventory in the seckill system with high speed - redis transaction + optimistic lock mechanism

论文阅读_多任务学习_MMoE

Lwip之内存与包缓冲管理

Memory and packet buffer management of LwIP

WPF 实现用户头像选择器

I2C communication - sequence diagram

我也是醉了,Eureka 延迟注册还有这个坑!

对灰度图像的三维函数显示

Drawing PDF tables (I) drawing excel table styles in PDF and downloading them through iText (supporting Chinese fonts)
随机推荐
Principle and implementation of UDP penetration NAT in P2P
Cross validation (CV) learning notes
Calculation date or date formatting
SDLC 软件开发生命周期及模型
Mock service Moco series (I) - introduction, first demo, get request, post request
关于flickr的数据集笔记
Go channel simple notes
EDI docking commercehub orderstream
PHP解决并发问题的几种实现
【硬件工程师】元器件选型都不会?
【Cadence Allegro PCB设计】error: Possible pin type conflict GND/VCC Power Connected to Output
go channel简单笔记
双向链表的基本操作
食品安全 | 八问八答带你重新认识小龙虾!这样吃才对!
MySQL数据库常用命令
Is it safe to open a futures account online? How to apply for a low handling fee?
【硬件工程师】DC-DC隔离式开关电源模块为什么会用到变压器?
基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用
SLA 、SLO & SLI
吴恩达机器学习编程作业无法暂停pause问题解决