当前位置:网站首页>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;
}
}
边栏推荐
- [cadence Allegro PCB design] permanently modify the shortcut key (customized) ~ it is valid for personal test~
- Brief introduction to clustered index, secondary index, index push down
- itextpdf实现多PDF文件合并为一个PDF文档
- 「数字安全」警惕 NFT的七大骗局
- Redistemplate solves the problem of oversold inventory in the seckill system with high speed - redis transaction + optimistic lock mechanism
- Mock service Moco series (I) - introduction, first demo, get request, post request
- IDEA集成SVN代码管理常用功能
- 简述聚簇索引、二级索引、索引下推
- 2022/7/23
- 我也是醉了,Eureka 延迟注册还有这个坑!
猜你喜欢

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

Calculation date or date formatting

【解决方案】Microsoft Edge 浏览器 出现“无法访问该页面”问题

Installation steps and usage of NVM under windows10 system

绘制pdf表格 (一) 通过itext实现在pdf中绘制excel表格样式并且实现下载(支持中文字体)

精彩记录

EDI 对接CommerceHub OrderStream

window10系统下nvm的安装步骤以及使用方法

Redis source code and design analysis -- 15. RDB persistence mechanism

RedisTemplate解决高并发下秒杀系统库存超卖方案 — Redis事务+乐观锁机制
随机推荐
Mock service Moco series (II) - JSON format, file file, header, cookie, solving Chinese garbled code
OSPF --- open shortest priority path protocol
世界各地的标志性建筑物
go语言context控制函数执行超时返回
简述冒泡排序与快速排序
Take you to a preliminary understanding of multiparty secure computing (MPC)
【解决方案】Microsoft Edge 浏览器 出现“无法访问该页面”问题
电子产品“使用”和“放置”哪个寿命更长??
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?
做智能硬件要考虑的产品生命周期
Ultimate doll 2.0 | cloud native delivery package
有没有什么不起眼却挣钱的副业?
Mock服务moco系列(三)- 重定向、正则表达式、延迟、模板、事件、分模块设计
对灰度图像的三维函数显示
I'm also drunk. Eureka delayed registration and this pit!
P2P 之 UDP穿透NAT的原理与实现
哈夫曼树的构建
EDI docking commercehub orderstream
Summary of knowledge points for final review of server-side architecture design
window10系统下nvm的安装步骤以及使用方法