如何使对象跟随 3D 图形中的轨迹

How to make an object follow a track in 3D graphics

我设法让我的物体沿着轨道移动,当它从左向右移动时它也面向移动方向,但是在轨道的后半部分,物体向右移动离开它颠倒了,我不知道为什么。

您可以通过克隆 this GitHub repo 并在浏览器中打开 ./samples/truck-on-track.html 文件来查看实际效果。无需安装任何东西或 运行 任何东西,这是一个静态 html 页面。

代码的重要部分是:

const track = [
       0,  -50,    0,
      40,  -65,   10,
      90,  -35,   60,
      10,  -15,  250,
     -60,  -40,  130,
    -120,  -35,   30,
     -20,  -57,    5
];

const actions = [];
const invLinearVelocity = 3;
const invAngularVelocity = 30;
const position = truck.getPosition();
const truckPosition = [0, 15, 0];
for (let iThis = 0; iThis < track.length; iThis += 3) {
    const iNext = iThis + 3 >= track.length ? 0 : iThis + 3;

    const thisTrackLocation = Vector.extract3D(track, iThis);
    const nextTracklocation = Vector.extract3D(track, iNext);

    const vector = Vector.sub(nextTracklocation, thisTrackLocation);
    const angleY = Math.atan2(vector[2], vector[0]);
    const angleZ = Math.atan2(vector[1], vector[0]);
    const nextAngle = [0, angleY, angleZ];

    actions.push(frag.PositionAnimationAction(position)
        .rotateTo(nextAngle, invAngularVelocity));
  
    actions.push(frag.PositionAnimationAction(position)
        .moveTo(Vector.add(nextTracklocation, truckPosition), invLinearVelocity));
}
frag.Animation().sequence(actions, true).start();

我的数学有问题。经过一番研究,我写了这个函数,解决了这个问题。查看 this GitHub repo 以获得完整的解决方案。关键函数是:

eulerAngles: function(directionVector, upVector) {
    const Vector = window.frag.Vector;
    if (!upVector) upVector = [0, 1, 0];

    const dir = Vector.normalize(directionVector);
    const up = Vector.normalize(upVector);

    const pitch = Math.asin(dir[1]);
    const yaw = Math.atan2(dir[0], dir[2]);

    const wingDir = [-dir[2], 0, dir[0]];
    const vertical = Vector.cross(wingDir, dir);
    const roll = Math.atan2(Vector.dot(wingDir, up), Vector.dot(vertical, up));

    return [roll, yaw, pitch];
}