Вычислить вращение, необходимое для преобразования плоскости

В настоящее время я пытаюсь визуализировать полигональную сетку в изометрии (контекст html5 canvas 2d).
Моя работа почти завершена, за исключением того, что я не могу найти правильный расчет/алгоритм для определения вращения плоскости.

В примере у меня есть плоскости A и B, определенные двумя векторами Ox, Oy

var planeA = {
    Ox: {
        x: 1,
        y: -2,
        x: 1,
    }, Oy: {
        x: 1,
        y: -1,
        z: 0,
    }
}

var planeB = {
    Ox: {
        x: 0,
        y: 1,
        x: 0,
    }, Oy: {
        x: 0,
        y: 0,
        z: -1,
    }
}

Я хочу найти альфу (вращение вокруг Ox), бета (вращение вокруг Oy) и гамму (вращение вокруг Oz), чтобы применить их к плоскости A, чтобы сделать плоскость A одинаковой с плоскостью B.


person hope_is_grim    schedule 14.11.2012    source источник
comment
Планируете ли вы применять повороты в таком порядке? Кроме того, вам нужно всего два оборота, а не три, так что вы предпочитаете эффективность или четкость?   -  person Beta    schedule 14.11.2012
comment
Имеет ли значение порядок (я не очень силен в математике...)? И если мне нужно только два поворота, я могу оставить один ноль :D Просто нужен способ вычислить это программно.   -  person hope_is_grim    schedule 14.11.2012
comment
Я ошибся: нужно три. Пишем ответ...   -  person Beta    schedule 15.11.2012
comment
А угол от Ox до Oy всегда равен 90 градусов.   -  person hope_is_grim    schedule 15.11.2012


Ответы (1)


Сначала найдите нормали, взяв векторное произведение векторов, а затем нормализовав их.

Чтобы взять векторное произведение двух векторов, A и B, используйте следующую формулу:

Cx = Ay*Bz - Az*By< br> Cy = -Ax*Bz + Az*Bx
Cz = Ax*By - Ay*Bx

(Обратите внимание, что порядок имеет значение. Как правило, AxBBxA.)

Итак, для ваших двух плоскостей перекрестные произведения равны (1,1,1) и (-1,0,0).

Чтобы нормализовать вектор, разделите его на его величину. Таким образом, нормальные векторы ваших плоскостей равны (1/sqrt(3))(1,1,1) и (-1,0,0).

Теперь, чтобы повернуть вектор в другой (я предполагаю, что у вас есть atan2(), и что у вас есть правило правой руки в холодном состоянии):

<б>1. Поверните вокруг Ox: чтобы поместить A в плоскость XZ, поверните на atan2(Ay, Az ).
2. Поверните вокруг Oy:, чтобы получить правильный фи (угол от Oz)). PhiB равно atan2(sqrt(Bx2+By2) , Bz), поэтому поверните на atan2(sqrt(Bx2+By2 ), Bz) - atan2(Ax, Az)
3. Поверните вокруг Oz: чтобы получить правильную "долготу", поверните на atan2(By, Bx) - atan2(Ay, Ax).

Таким образом, в вашем примере вы должны повернуть A вокруг Ox на π/4, чтобы получить (sqrt(2/3), 0, sqrt (1/3)), затем около Oy на π/2 - atan(sqrt(2)) для получения (1,0,0), затем около < b>Oz на π, чтобы получить (-1,0,0).

person Beta    schedule 16.11.2012
comment
и возможно ли заставить Ox, Oy из A иметь одно направление с Ox, Oy из B? - person hope_is_grim; 17.11.2012
comment
@hope_is_grim: Да, конечно, но это меняет проблему. Я предположил, что эти вращения были вокруг фиксированных осей вашей системы координат, а не векторов, встроенных в плоскости; это правильно? Если да, то можете ли вы сделать вращение вокруг произвольного вектора? - person Beta; 17.11.2012