Рисование самолета - PullRequest
       20

Рисование самолета

1 голос
/ 25 января 2011

Я хочу нарисовать плоскость, которая задается уравнением: Ax + By + Cz + D = 0.Сначала я попытался нарисовать его, установив x, y, а затем получить z из уравнения.это не сработало нормально, потому что есть некоторые плоскости, такие как 0x + 0y + z + 0 = 0 и т. д. *

мое текущее решение таково: - нарисовать плоскость на плоскости ZY, задав 4 координаты, которые идутдо бесконечности.- выяснить, что нужно сделать для того, чтобы нормаль заданной плоскости (a, b, c) лежала на оси z.- найти перевод, который нужно сделать, чтобы эта плоскость находилась на оси х.- сделать совершенно противоположное преобразование к этому вращению и к этому переводу, следовательно, я получу плоскость
на его месте.

ок

это здорово, но я могу сделать правильныйматематические вычисления (многократно ...) с точечным произведением и т. д. ...

Может кто-нибудь помочь мне понять, как именно это должно быть сделано, ИЛИ дать мне формулу, в которой я будупоставить ABCD и получить правильное преобразование?

Ответы [ 2 ]

1 голос
/ 25 января 2011

Вам понадобится следующая матрица преобразования:

    [ x0_x y0_x z0_x o_x ]
M = [ x0_y y0_y z0_y o_y ]
    [ x0_z y0_z z0_z o_z ]
    [    0    0    0   1 ]

Здесь z0 - нормаль вашей плоскости, а o - начало вашей плоскости, а x0 и y0 - два вектора в вашей плоскости, ортогональные z0, которые определяют поворот и наклон вашей проекции.

Тогда любая точка (x, y) на вашей плоскости XY может быть спроецирована на точку (p_x, p_y, p_z) вашей новой плоскости следующим образом:

(p_x, p_y, p_z, w) = M * (x, y, 0, 1)

Теперь z0 в вашей матрице преобразования прост, это норма вашей плоскости, и это просто n = normalize(a,b,c).

В выборе отдыха у вас, однако, заметно больше свободы. Для начала координат вы можете взять точку, в которой плоскость пересекает ось Z, если, конечно, плоскость не параллельна оси Z, в этом случае вам нужно что-то еще.

Так, например,

if (c != 0) { //plane intersects Z axis
  o_x = 0;
  o_y = 0;
  o_z = -d/c;
}
else if (b != 0) { // plane intersects Y axis
  o_x = 0;
  o_y = -d/b;
  o_z = 0;
}
else { // plane must intersect the X axis
  o_x = -d/a;
  o_y = 0;
  o_z = 0;
}

На практике вы можете предпочесть другой тест, чем (c != 0), потому что с этим тестом он будет успешным, даже если c очень очень маленький, но просто отличается от нуля, что приводит к тому, что ваш источник будет, скажем, x=0, y=0, z=10e100, что вероятно не было бы желательно. Поэтому какой-то тест, например (abs(c) > threshold), вероятно, предпочтительнее. Однако вы можете, конечно, взять совершенно другую точку на плоскости, чтобы поместить начало координат, возможно, точку, ближайшую к исходной точке вашей исходной системы координат, которая будет:

o = n * (d / sqrt(a^2 + b^2 + c^2))

Тогда, наконец, нам нужно вычислить x0 и y0. Это могут быть любые два линейно независимых вектора, ортогональных z0.

Итак, давайте сначала выберем вектор в плоскости XY для нашего вектора x0:

x0 = normalize(z0_y, -z0_x, 0)

Теперь это не работает, если ваш z0 имеет вид (0, 0, z0_z), поэтому для этого нам нужен особый случай:

if (z0_x == 0 && z0_y == 0) {
  x0 = (1, 0, 0)
}
else {
  x0 = normalize(z0_y, -z0_x, 0)
}

В заключение, скажем, мы не хотим, чтобы уклон был, и выберем y0 как ортогональное как к x0, так и к y0, затем, используя перекрестный продукт

y0 = normalize(x0_y*y0_z-x0_z*y0_y, x0_z*y0_x-x0_z*y0_z, x0_x*y0_y-x0_y*y0_x)

Теперь у вас есть все для заполнения матрицы преобразования.

Отказ от ответственности: При использовании представлений с плавающей запятой для ваших чисел следует проявлять надлежащую осторожность, в таких случаях простых (foo == 0) тестов недостаточно. Читайте о математике с плавающей запятой, прежде чем приступить к реализации.

Редактировать: для ясности переименованы некоторые переменные

0 голосов
/ 25 января 2011

Это то, что вы спрашиваете?

Преобразовать простую плоскость, подобную плоскости xy, в вашу плоскость довольно просто:

ваша плоскость Ax + By + Cz + D = 0

плоскость xy - это просто z = 0.т.е. A = B = D = 0, а C = все, что вы хотите.Для простоты мы скажем 1.

Когда у вас есть плоскость в этой форме, нормаль плоскости определяется вектором (A, B, C)

, так что вы хотитевращение, которое приведет вас от (0,0,1) к (A, B, C) *

* Обратите внимание, что это будет работать, только если {A, B, C} является унитарным.поэтому вам, возможно, придется разделить AB и C на sqrt (A ^ 2 + B ^ 2 + C ^ 2).

вращение вокруг только двух осей может привести вас из любого направления в любое другое направление,поэтому мы выберем x и y;

здесь - матрицы вращения для вращений на a вокруг оси x и b вокруг оси y.

Rx: = {{1, 0, 0}, {0, Cos [a], Sin [a]}, {0, -Sin [a], Cos [a]}}

Ry: = {{Cos [b], 0, -Sin [b]}, {0, 1, 0}, {Sin [b], 0, Cos [b]}}

, если мы делаем вращение вокруг x с последующим вращением вокруг yвектора вектора, нормального к плоскости xy, (0,0,1), получаем:

Ry.Rx. {0,0,1} = {-Cos [a] Sin [b],Sin [a], Cos [a] Cos [b]}

, которые являются вашими значениями ABC.

т.е.

A = -Cos [a] Sin [b]

B = Sin [a]

C = Cos [a] Cos [b]

Отсюда все просто.

a = aSin [B]

, поэтому теперь A = -Cos [aSin [B]] Sin [b]

Cos [aSin [x]] = sqrt (1-x ^ 2) так:

A = -Sqrt [1-B ^ 2] * Sin [b]

b = aSin [-A / sqrt [1-B ^ 2]]

a = aSin [B] (вращение вокруг оси x)

b = aSin [-A / sqrt [1-B ^ 2]] (вращение вокруг оси y)

Итак, мытеперь у нас есть углы вокруг осей x и y, на которые нам нужно повернуться.

После этого вам просто нужно сместить самолет вверх или вниз, пока он не совпадет с тем, который у вас уже есть.

Плоскость, которую вы имеете в данный момент (после этих двух поворотов), будет Ax + By + Cz = 0.

нужная вам плоскость Ax + Bx + Cz + D = 0.Чтобы узнать d, мы увидим, где ось z пересекает вашу плоскость.

т.е. Cz + D = 0 -> z = -D / C

Таким образом, мы преобразуем ваш z в Ax +На + Cz = 0 на -D / C, чтобы получить:

Ax + By + C (z + D / C) = Ax + By + Cz + D = 0.О, если бы вы посмотрели на это!

Оказывается, вам не нужно делать никаких дополнительных вычислений, если у вас есть углы поворота на!

Два угла дадут вам A, Bи C. Чтобы получить D, просто скопируйте его из того, что у вас было.

Надеюсь, что это поможет, хотя я не совсем уверен, как вы планируете на самом деле рисовать самолет, хотя ...

Отредактировано, чтобы исправить ужасное форматирование.надеюсь, теперь лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...