В настоящее время я пишу трехмерную реализацию алгоритма boids в P5.js, но у меня возникают проблемы с ориентацией моих boids в соответствии с их направлением (скоростью). Вращения ограничены RotateX(), RotateY() и RotateZ(). Самое простое решение, которое, как мне кажется, должно работать, выглядит следующим образом:
push();
translate(this.pos);
rotateZ(createVector(this.vel.x, this.vel.y).heading());
rotateY(createVector(this.vel.x, this.vel.z).heading());
beginShape();
// Draw Boid Vertices..
endShape();
pop();
Но это не так.
Я написал гораздо меньшую версию программы, которая содержит только ориентацию случайно сгенерированных частиц, движущихся в одном направлении. Он доступен здесь, непосредственно на сайте p5js: https://editor.p5js.org/itsKaspar/sketches/JvypSPGGh Существует элемент управления орбитой по умолчанию, поэтому вы можете масштабировать и перетаскивать мышь, чтобы проверить ориентацию частиц.
Большое спасибо, я уже полдня застрял на этом
В вашей демонстрации компонент z перевернут, и вы можете проверить это, попробовав только одно из вращений за раз. Во-вторых, объединение вращений в 3D таким образом обычно не дает желаемого результата, поскольку вращение меняет вектор «вверх» или «вправо» системы координат, прикрепленной к определенному объекту. Например, вращение вокруг вектора вверх (-y для p5) или угла рыскания приведет к вращению правильного вектора. Затем второе вращение должно быть связано с повернутым правым вектором (теперь шагом), поэтому вы не можете просто использовать rotateX/Y/Z, поскольку они все еще находятся в мировом пространстве, а не в пространстве объекта. Обратите внимание, что я полностью игнорирую крен в этом решении, но если вы посмотрите на боиды спереди и сверху, они должны быть выровнены со скоростями.
var right = p5.Vector(this.vel.x, 0, this.vel.z);
rotate(atan(this.vel.y/ this.vel.x), right);
rotateY(atan2(-this.vel.z, this.vel.x));