【问题标题】:3D Interpolation with 3 given points (equidistant)具有 3 个给定点的 3D 插值(等距)
【发布时间】:2012-05-17 19:07:00
【问题描述】:

我正在开发一个 3D 国际象棋游戏,我需要能够计算轨迹的 X、Y、Z 位置,该轨迹将描述抛物线(用于棋子动画)。

因此对于给定的等距点 p1=(x1,y1,z1), p2=(x2,y2,z2) 和 p3(x3,y3,z3),我需要以下公式(或通式):

x=f(y,z)=???  
y=f(x,z)=???   
z=f(x,y)=???

【问题讨论】:

  • p1、p2、p3在抛物线上,p2是顶点?
  • 没错!! p1 是起点,p2 是顶点,p3 是终点。
  • 如果p2 恰好是顶点,则问题过度约束。您只需将它们视为属于抛物线的空间中的三个点。
  • 我认为其他 SO 帖子会为您回答这个问题。 stackoverflow.com/questions/4039039/…
  • 您是指multiple boards at different elevations 中的 3d 国际象棋,例如《星际迷航》中所见?或者它是一个普通的单平板,但以 3d 呈现?如果棋盘是平的,则方程更容易推导出来,例如y1 == y3

标签: math computational-geometry interpolation


【解决方案1】:

对于xyz 的每个分量,考虑由定义的单独抛物线

x(t) = x1 - t*(3*x1-4*x2+x3) + 2*t^2*(x1-2*x2+x3)     //t=0..1
y(t) = y1 - t*(3*y1-4*y2+y3) + 2*t^2*(y1-2*y2+y3)     //t=0..1
z(t) = z1 - t*(3*z1-4*z2+z3) + 2*t^2*(z1-2*z2+z3)     //t=0..1

t=0 然后x=x1t=0.5 然后x=x2t=1 然后x=x2y(t)z(t) 也是如此。

【讨论】:

  • 自从我上一次几何课以来已经有很长时间了,但是......我怀疑(但无法证明)对 x(t) 和 z(t) 使用多项式会稍微扭曲从侧面看的抛物线。我认为您需要 x 和 z 的线性函数来获得实际的抛物线。但是,我认为你的方程仍然会给出一个很好的曲线形状,无论如何都可以满足 OP 的需求。
  • 非常感谢,效果很好。这非常简单明了。它甚至比我预期的还要好,因为我只能通过测试 t 而不是当前点的 X,Y,Z 来停止动画。
【解决方案2】:

如果开始和结束的 y 值相同,您可以使用参数方程来描述抛物线,该方程可以通过几个步骤导出。

给定startingHeight和apexHeight,

y(t) = A(t^2) + B(t) + C
y(0) = startingHeight
y(0.5) = apexHeight
y(1) = startingHeight

y(0) = startingHeight = A*0 + B*0 + C
C = startingHeight
y(t) = A(t^2) + B(t) + startingHeight

y(1) = startingHeight = A + B + startingHeight
0 = A+B
A = -B
y(t) = -B(t^2) + B(t) + startingHeight

y(0.5) = apexHeight = -B(0.25) + B(0.5) + startingHeight
apexHeight = B(0.5 - 0.25) + startingHeight
apexHeight - startingHeight = B(0.25)
B = (apexHeight - startingHeight)/4.0

现在你已经知道了 A、B 和 C,你可以编写 y 的方法:

function y(startingHeight, apexHeight, t){
    B = (apexHeight - startingHeight) / 4;
    A = -B;
    C = startingHeight;
    return A*t*t + B*t + C;
}

x 和 z 更容易,因为它们只是从头到尾线性增加:

x(t) = At + B
x(0) = startX
x(1) = endX

x(0) = startX = A*0 + B
B = startX
x(t) = At + startX

x(1) = endX = A*1 + startX
A = endX - startX

x(t) = (endX - startX) * t + startX

(z 有一个与 x 相同的公式 - 只需将所有 x 替换为 z)

function x(start, end, t){
    A = (end - start);
    B = start;
    return A*t + B;
}

function z(start, end, t){
    A = (end - start);
    B = start;
    return A*t + B;
}

现在你可以找到棋子在时间 t 的 3d 位置:

function parabola(xBegin, xEnd, zBegin, zEnd, yStart, yApex, t){
    return [x(xBegin,xEnd,t), y(yStart,yApex,t), z(zBegin,zEnd,t)];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    相关资源
    最近更新 更多