Unity 曲线和弹力算法
主要用来记录一下,也算是笔记,以后回头可以再熟悉下。
所以就直接上代码了。
//二阶曲线算法
public static Vector3 Bezier(Vector3 start, Vector3 end, Vector3 tanPoint, float t)
{
Vector3 p0p1 = (1 - t) * start + t * tanPoint;
Vector3 p1p2 = (1 - t) * tanPoint + t * end;
Vector3 result = (1 - t) * p0p1 + t * p1p2;
return result;
}
//三阶曲线算法
public static Vector3 Interpolate(Vector3 start, Vector3 end, Vector3 tanPoint1, Vector3 tanPoint2, float t)
{
Vector3 position = (2.0f * t * t * t - 3.0f * t * t + 1.0f) * start
+ (t * t * t - 2.0f * t * t + t) * tanPoint1
+ (-2.0f * t * t * t + 3.0f * t * t) * end
+ (t * t * t - t * t) * tanPoint2;
return position;
}
Spring 弹力算法
F=kx 弹力公式
public class Spring
{
// Spring simulation constants
//质量
private float mMass = 1f;
//弹力系数 k
private float mSpringConstant = 0.2f;
//阻尼系数
private float mDampingConstant = 0.92f;
//静止位置
private Vector2 mRestPos;
// Spring simulation variables
//速度
private Vector2 mVelocity;
//加速
private float mAcceleration;
//力
private float mForce;
//-------------------------------变量
//临时位置
public Vector2 mTempPos;
//自身位置
public Vector2 mSelfPos;
/// <summary>
///
/// </summary>
/// <param name="x">x 坐标</param>
/// <param name="y">y 坐标</param>
/// <param name="k">弹力系数</param>
/// <param name="d">阻尼系数</param>
/// <param name="m">质量</param>
public Spring(float x, float y, float k, float d, float m)
{
mSelfPos = mTempPos = mRestPos = new Vector2(x, y);
mSpringConstant = k;
mDampingConstant = d;
mMass = m;
}
public void OnUpdate()
{
mForce = -mSpringConstant * (mTempPos.x - mRestPos.x); // f=-ky 弹力
mAcceleration = mForce / mMass; // Set the acceleration, f=ma == a=f/m 加速度
mVelocity.x = mDampingConstant * (mVelocity.x + mAcceleration); // Set the velocity 速度
mTempPos.x = mTempPos.x + mVelocity.x; // Updated position
mForce = -mSpringConstant * (mTempPos.y - mRestPos.y); // f=-ky 弹力
mAcceleration = mForce / mMass; // Set the acceleration, f=ma == a=f/m 加速度
mVelocity.y = mDampingConstant * (mVelocity.y + mAcceleration); // Set the velocity 速度
mTempPos.y = mTempPos.y + mVelocity.y; // Updated position
}
//根据鼠标移动偏移量 赋值一个x、y方向的弹力
public void SetRestPos(float x, float y)
{
mRestPos = new Vector2(x, y);
}
//鼠标离开区域
public void OnReleased()
{
if (mRestPos == mSelfPos) return;
mRestPos = mSelfPos;
//rest_posy = ypos;
}
}
//根据曲线公式 循环得到一个精度为100个点的曲线
float pointStep = 1.0f / 100;
float t;
for (int i = 0; i < 100; i++)
{
t = i * pointStep;
mLineRenderer.SetPosition(i, BezierTool.Bezier(mStartPos, mEndPos, mControlPos, t));
}