简体   繁体   English

通过起点、终点和高度计算 3D 轨迹

[英]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.我已经想出了如何使用起点和角度制作 3D 轨迹。 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.我尝试在 3D 空间中的 2D 平面上采用抛物线的方法。 I calculated the Prabola's A, B, and C values as well as the plane it's on given 3 points on the Parabola.我计算了 Prabola 的 A、B 和 C 值以及它在抛物线上给定 3 个点所在的平面。 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.但是,我在进行这种计算时遇到了一些复杂情况,我认为这与无法在没有平面的情况下正确计算 Z 轴有关,但我无法判断。

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.除了平面上的 2D 抛物线之外,谷歌没有提供另一个可能的答案,3D 轨迹使用起点、角度和功率乘数产生一个公式。

  • Is there any way to calculate a 3D trajectory given the start point, end point, and height?有没有办法计算给定起点、终点和高度的 3D 轨迹?

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)我使用 3 个点计算抛物线的代码(以防有人想知道我是如何做到的,也许可以纠正我做错了什么)

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 轴而不是 3 轴上时,结果看起来不错。这里有 2 张图像用于演示: 正确的但仅在 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.我在这里做了很多假设,但似乎x是一个从 0.0 到 1.0 的值,分别代表抛物线的起点和终点。 If so, you are determining the X and Z coordinates of this point based exclusively on the sine/cosine of the angle and x .如果是这样,您将完全根据角度和x的正弦/余弦来确定该点的 X 和 Z 坐标。 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.这意味着xszs值应该只能在 -1 和 1 之间,从而将自己限制在单位圆的范围内。

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.xszs看起来需要按系数s进行缩放,该系数s通过测量投影到 XZ 平面时起点和终点的二维距离计算得出的。 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.在搞乱 3D 抛物线之前,我搞乱了 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)与抛物线不同,即使在 3D 中,直线也具有定义的方程( Pn = P0 + tx V )(Pn 向量包含 XYZ,P0 初始点包含 XYZ,t float,V Vector3)

In addition, there's only ONE line that goes through 2 points, even in 3D.此外,这里只有一条线,通过2点进入,即使在3D。

I used that to make a trajectory that's made out of 2 points and a height.我用它来制作由 2 个点和一个高度组成的轨迹。 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.我在这两个点的中心创建一个新点,并将高度值添加到这些点的最高 Y 值上,从而创建一个 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.然后我使用与之前相同的计算来计算具有这 3 个点的抛物线将具有的 A、B 和 C 值。

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.我做了一个方法,它接受一个 X 值并返回一个 Vector3,其中包含这个 X 在线性方程上的点,而是根据抛物线方程改变向量的 Y 值。

Practically creating an elevated line, I made something that looks and behaves perfectly like a 3D parabola.实际上创建了一条高架线,我制作了一些看起来和行为都非常像 3D 抛物线的东西。

If you're in C#, here is the code(images):如果您使用 C#,这里是代码(图片): 线性

弹道

FIX!!使固定!!

in the Linear's GetX(float x) method.在 Linear 的 GetX(float x) 方法中。 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.我在计算中犯了一个小错误,我立即注意到并进行了更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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