已知目的地,高度差,重力
1.根据发射角度,求初速度
推导出V
public static float LaunchSpeed(float distance, float yOffset, float gravity, float angle)
{
float speed = (distance
* Mathf.Sqrt(gravity)
* Mathf.Sqrt(1 / Mathf.Cos(angle)))
/ Mathf.Sqrt(2 * distance * Mathf.Sin(angle) + 2 * yOffset * Mathf.Cos(angle));
return speed;
}
2.根据发射速度,求角度
注意根号不能为负数,也就是初始速度不足以到达目的地
求解会得到两个角度,一般都用小的角度
public static bool LaunchAngle(float speed, float distance, float yOffset, float gravity, out float angle0, out float angle1)
{
angle0 = angle1 = 0;
float speedSquared = speed * speed;
float operandA = Mathf.Pow(speed, 4);
float operandB = gravity * (gravity * (distance * distance) + (2 * yOffset * speedSquared));
// Target is not in range
if (operandB > operandA)
return false;
float root = Mathf.Sqrt(operandA - operandB);
angle0 = Mathf.Atan((speedSquared + root) / (gravity * distance));
angle1 = Mathf.Atan((speedSquared - root) / (gravity * distance));
return true;
}
3.得到飞行总时间
public static float TimeOfFlight(float speed, float angle, float yOffset, float gravity)
{
float ySpeed = speed * Mathf.Sin(angle);
float time = (ySpeed + Mathf.Sqrt((ySpeed * ySpeed) + 2 * gravity * yOffset)) / gravity;
return time;
}
PS:我们需要把先distance投影到平面,注意GIF上的红线和白线
public static Vector3 ProjectVectorOnPlane(Vector3 planeNormal, Vector3 vector)
{
return vector - (Vector3.Dot(vector, planeNormal) * planeNormal);
}
标 准 结 局