Я рисую плоский диск, используя gluDisk()
в своей сцене. gluDisk()
рисует диск, обращенный к положительной оси Z, но я хочу, чтобы он был обращен к какой-то произвольной нормали, которая у меня есть.
Очевидно, что мне нужно использовать glRotate()
, чтобы правильно расположить диск, но каким должен быть поворот? Я помню, что это можно рассчитать с помощью кватернионов, но я не могу вспомнить математику.
Кватернионная математика для вращения?
Ответы (3)
Решение должно быть довольно простым и не должно требовать четвертей.
Ось вращения для перехода от нормали1 к нормали2 должна быть ортогональна обеим, поэтому просто возьмите их векторное векторное произведение.
Величину ротации легко получить из их скалярного произведения. Это значение равно |A|.|B|.cos(theta), но поскольку два вектора нормали должны быть нормализованы, это даст cos(theta), поэтому просто возьмите арккосинус, чтобы получить величину вращения.
Результирующий вектор и угол являются необходимыми параметрами для glRotate()
— нет необходимости вычислять реальную матрицу поворота самостоятельно.
p.s. не забывайте, что glRotate()
нужен угол в градусах, но обычные триггерные функции C работают в радианах.
glRotate
, но в целом я ничего не понимаю). Если они параллельны, векторным произведением является нулевой вектор, вокруг которого нельзя вращаться. Если два вектора параллельны и указывают в одном направлении, ничего не поделаешь. Если два вектора параллельны и указывают в противоположных направлениях, вы можете повернуть «Normal1» 2 * PI вокруг любой оси, которая не параллельна «Normal1», чтобы получить «Normal2», но, возможно, это может повернуть другие оси матрицы. нежелательным образом.. (не полностью учтено)
- person Bjarke; 15.04.2018
Вращение вокруг произвольной оси: при заданном угле r в радианах и единичном векторе u = ai + bj + ck или [a,b,c] определите:
q0 = cos(r/2)
q1 = sin(r/2) a
q2 = sin(r/2) b
q3 = sin(r/2) c
и построим из этих значений матрицу поворота:
( q0^2+q1^2 - q2^2 - q3^2 | 2*(q1*q2 - q0*q3) | 2*(q1*q3 + q0*q2) )
Q =( 2*(q2*q1 + q0*q3) | (q0^2 - q1^2 + q2^2 - q3^2) | 2*(q2*q3 - q0*q1) )
( 2*(q3*q1 - q0*q2) | 2*(q3*q2 + q0*q1) | q0^2 - q1^2 - q2^2 + q3^2 )
Чтобы найти поворот, который вам нужно сделать, вы можете вычислить векторное произведение между текущим вектором и целевым вектором. Вы получите ортогональный вектор (который будет вашим вектором вращения для создания кватерниона), а длина этого вектора является грехом угла, который вы должны компенсировать, чтобы начальный и целевой вектор перекрывались.
Кватернионы описывают вращение вокруг оси. <w,x,y,z>
будет вращаться вокруг оси <x,y,z>
на некоторую величину в зависимости от баланса между величиной w
и величиной вектора.
<cos θ/2, x*sin θ/2, y*sin θ/2, z*sin θ/2>, where |<x, y, z>| = 1
Например, если вместо этого повернуть его лицом к положительной оси Y, вам нужно повернуть его на 90° вокруг оси X. Вектор будет <0, 1, 0>
, а кватернион будет <cos 90°, 0, sin 90°, 0>
= <0, 0, 1, 0>
.
Чтобы повернуть фигуру от положительной оси Z к вектору <x,y,z>
, вам нужно найти вектор вращения и угол поворота. Чтобы найти ось вращения, вы можете взять векторное произведение текущего вектора и указать, где вы хотите, чтобы он был.
Если он обращен к положительной оси Z, текущий вектор будет <0, 0, 1>
. Если вы хотите, чтобы он смотрел на <x,y,z>
, ось вращения была бы <0, 0, 1> x <x, y, z> = <-y, x, 0>
, а угол был бы arctan(sqrt(x^2+y^2),z)
. Кватернион становится
<cos(θ/2), -y*sin(θ/2), x*sin(θ/2), 0>, where θ = arctan(sqrt(x^2+y^2), z)