简体   繁体   中英

Calculate a 3D trajectory by start point, end point and height

I've already figured out how to make a 3D trajectory using a start point and an angle. However, I am trying to make a trajectory from a start point, an end point, and a height.

I tried taking the approach of a parabola on a 2D plane in a 3D space. I calculated the Prabola's A, B, and C values as well as the plane it's on given 3 points on the Parabola. However, I've had a few complications with this sort of calculation, I assume it has to do with the inability to properly calculate a Z-axis without a plane but I cannot tell.

Other than a 2D parabola on a plane google did not provide another possible answer and a 3D trajectory yields a formula using a start point, an angle, and a power multiplier.

  • Is there any way to calculate a 3D trajectory given the start point, end point, and height?

Appreciating your help

Edit :

My code to calculate a parabola using 3 points (in case someone would like to know how I've done that and perhaps fix what I've done wrong)

public Parabola(Vector3 pa, Vector3 pb, Vector3 pc)
        {
            this.pa = pa;
            this.pc = pc;
            float a1 = -pa.x * pa.x + pb.x * pb.x, b1 = -pa.x + pb.x, c1 = -pa.y + pb.y;
            float a2 = -pb.x * pb.x + pc.x * pc.x, b2 = -pb.x + pc.x, c2 = -pb.y + pc.y;
            float bm = -(b2 / b1), a3 = bm * a1 + a2, c3 = bm * c1 + c2;
            float a = c3 / a3, b = (c1 - a1 * a) / b1, c = pa.y - a * pa.x * pa.x - b * pa.x;
            this.a = a; this.b = b; this.c = c;
            plane = Vector3.Cross(pb - pa, pc - pa);
        }

public Vector3 GetPoint(float x) 
        {
            float angle = Mathf.Atan2(pc.z - pa.z, pc.x - pa.x) * Mathf.Rad2Deg;
            float xs = Mathf.Cos(angle * Mathf.Deg2Rad) * x, zs = Mathf.Sin(angle * Mathf.Deg2Rad) * x;
            return new Vector3(xs, a * x * x + b * x + c, zs); 
        }

public Vector3 ProjectOn(float x) => Vector3.ProjectOnPlane(GetPoint(x), plane);

The result looks ok when it's only on 2 Axis, but not 3. here are 2 images for demonstration: 正确的但仅在 2 轴上(起点和终点的 Z 值相等) 不正确,现在在 3 轴上(Z 值不相等)

Looking at the second image, the parabola seems to be correct aside from being scaled incorrectly. Let's take a look at your code.

public Vector3 GetPoint(float x) 
    {
        float angle = Mathf.Atan2(pc.z - pa.z, pc.x - pa.x) * Mathf.Rad2Deg;
        float xs = Mathf.Cos(angle * Mathf.Deg2Rad) * x, zs = Mathf.Sin(angle * Mathf.Deg2Rad) * x;
        return new Vector3(xs, a * x * x + b * x + c, zs); 
    }

I'm making a lot of assumptions here, but it seems like x is meant as a value that goes from 0.0 to 1.0, representing the start and end of the parabola, respectively. If so, you are determining the X and Z coordinates of this point based exclusively on the sine/cosine of the angle and x . This means that the values xs and zs should only ever be able to be between -1 and 1, limiting yourself to the confines of the unit circle.

The values xs and zs look like they need to be scaled by a factor s calculated by measuring the 2D distance of the start and end points when projected onto the XZ plane. This should stretch the parabola just enough to reach the end point.

I found an answer, but it's kinda a workaround.

Before messing around with Parabolas in 3D, I messed around with linear equations in 3D. Unlike parabolas, lines have a defined equation even in 3D( Pn = P0 + tx V )(Pn vector containing XYZ, P0 initial point containing XYZ, t float, V Vector3)

In addition, there's only ONE line that goes through 2 points, even in 3D.

I used that to make a trajectory that's made out of 2 points and a height. I make a new point in the center of those two points and add the height value to the highest Y value of the points, thus creating an Apex.

then I use the same calculations as before to calculate the A, B, and C values that a parabola with those 3 points would have had.

I made a method that takes in an X value and returns a Vector3 containing the point this X is on a linear equation, but instead, changing the vector's Y value based on the parabola's equation.

Practically creating an elevated line, I made something that looks and behaves perfectly like a 3D parabola.

If you're in C#, here is the code(images): 线性

弹道

FIX!!

in the Linear's GetX(float x) method. it should be:

public Vector3 GetX(float x) => => r0 + (x - r0.x)/v.x * v;

I made a slight mistake in the calculations which I noticed immediately and changed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM