问题描述
我已经想出了如何使用起点和角度绘制3D轨迹的方法。 但是,我正在尝试从起点,终点和高度开始绘制轨迹。
我尝试在3D空间中的2D平面上采用抛物线的方法。我计算了Prabola的A,B和C值以及在抛物线上给定3个点的平面。 但是,我在进行此类计算时遇到了一些麻烦,我认为这与无法正确计算没有平面的Z轴有关,但我无法分辨。
除了平面上的2D抛物线外,谷歌没有提供其他可能的答案,而3D轨迹使用起点,角度和乘数产生了公式。
- 是否可以通过给定起点,终点和高度来计算3D轨迹?
感谢您的帮助
修改:
我的代码使用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);
仅在2轴而不是3轴上时,结果看起来还可以。 这是2张图片进行演示:
解决方法
看第二张图片,抛物线除了缩放比例不正确外,似乎是正确的。让我们看看您的代码。
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);
}
我在这里做了很多假设,但似乎x
的含义是从0.0到1.0的值,分别代表抛物线的起点和终点。如果是这样,则仅基于角度和x
的正弦/余弦确定该点的X和Z坐标。这意味着值xs
和zs
只能在-1和1之间,将自己限制在单位圆的范围内。
值xs
和zs
似乎需要按因数s
进行缩放,该因数是通过投影到XZ平面上时测量起点和终点的2D距离来计算的。这应该使抛物线刚好伸展到终点。
我找到了答案,但这是一种解决方法。
在3D中使用Parabolas之前,我在3D中使用线性方程组。 与抛物线不同,线即使在3D中也具有定义的方程式( Pn = P0 + t x V )(包含XYZ的Pn向量,包含XYZ的P0初始点,t float,V Vector3)
此外,即使在3D模式下,也只有一个线穿过2点。
我用它来制作一条由2个点和一个高度组成的轨迹。 我在这两个点的中心创建了一个新点,并将高度值添加到这些点的最高Y值,从而创建了Apex。
然后我使用与以前相同的计算方法来计算A,B和C值, 具有这3点的抛物线就可以了。
我制作了一种方法,该方法接受X值并返回包含该X在线性方程式上的点的Vector3,但改为根据抛物线方程式更改向量的Y值。
实际上创建了一条高架线,我制作了看起来和行为完全像3D抛物线的东西。
修复!
在Linear的GetX(float x)方法中。 应该是:
public Vector3 GetX(float x) => => r0 + (x - r0.x)/v.x * v;
我在计算中犯了一个小错误,我立即注意到并进行了更改。