[Unity数学]2点間の放物線移動

2663 ワード

いちじげんにじほうていしき
 
一、基本知識
一般式:y=a*x^2+b*x+c(a!=0)であり、a>0放物線開口が上向きであり、a<0放物線開口が下向きである.|a|大きいほど口が小さくなる.
頂点式:y=a*(x-h)^2+k点(h,k)は放物線の頂点です.h=-b/2a,k=(4ac-b^2)/4a
焦点式:y=a*(x-x 1)*(x-x 2).(x 1,0)(x 2,0)は放物線とX軸の交点であり、Δ=b^2-4 ac,ルート式x 1,x 2=[-b±√Δ]/2a
 
二、問題分析
放物線は主に高度の問題を解決すればいい.
直角座標系では、y軸を高さ、x軸を時間、
既知Δ>0,2点pointA,pointBは方程式の2つのルートx 1,x 2である
 
pointAが原点であればc=0
この場合、2つのパラメータが必要です.1つはaで、放物線の開口の向きと大きさを制御します.
もう1つは速度speed,2点間の距離dis/速度speed=時間timeである.
x軸は時間軸deltaTime、頂点式h=-b/2 a=time/2なのでb=-a*time
⑪aはパラメータ、b=-a*(dis/speed)、c=0
∴ y = a*x^2 + b*x + c = a*deltaTime*deltaTime - a*(dis/speed)*deltaTime
三、コード実装
using UnityEngine;

public class Parabola : MonoBehaviour
{
    public Transform tr1;
    public Transform tr2;
    public GameObject go;

    public float speed = 10;
    public float a = 10;

    void Start()
    {
        Reset();
        InvokeRepeating("Reset", 2, 5);
    }

    float deltaTime = 0;
    void Update()
    {
        a = -Mathf.Abs(a);
        speed = Mathf.Abs(speed);
        deltaTime += Time.deltaTime;
        
        Vector3 vec = (tr2.position - tr1.position).normalized;
        float dis = Vector3.Distance(tr1.position, tr2.position);

        float x = deltaTime * speed;
        float y = a * deltaTime * deltaTime -a * (dis / speed) * deltaTime;
        go.transform.position = vec * x + Vector3.up * y;
    }

    void Reset()
    {
        deltaTime = 0;
        go.transform.position = tr1.position;
    }
}

 
3 D放物線
    void Update()
    {
        start = sTr.position;
        end = eTr.position;

        Vector4 y = new Vector4(0, 1, 0, 0);
        Vector4 x = (end - start).normalized;
        Vector4 z = Vector3.Cross(x, y);
        Matrix4x4 planeToWorld = new Matrix4x4(x, y, z, new Vector4(start.x, start.y, start.z, 1));

        Vector3 startPlane = planeToWorld.inverse.MultiplyPoint3x4(start);
        Vector3 endPlane = planeToWorld.inverse.MultiplyPoint3x4(end);
        //   
        Vector3 highestPos = (endPlane + startPlane) / 2.0f + Vector3.up * h;
        float p = Mathf.Pow(startPlane.x - highestPos.x, 2) / (-2 * (startPlane.y - highestPos.y));
        for (int i = 0; i < density; i++)
        {
            float posX = startPlane.x + (endPlane.x - startPlane.x) * (i / (float)density);
            float posY = Mathf.Pow(posX - highestPos.x, 2) / (-2 * p) + highestPos.y;
            Vector3 worldPos = planeToWorld.MultiplyPoint3x4(new Vector3(posX, posY, 0));
            line.SetPosition(i, worldPos);
        }
    }