Вопрос

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

мое текущее решение таково:- нарисуйте плоскость на плоскости ZY, задав 4 координаты, уходящие в бесконечность.- Узнайте вращение, которое должно быть сделано для того, чтобы принести нормальную плоскость (A, B, C) лежать на оси Z.- найдите перевод, который нужно сделать, чтобы эта плоскость находилась на оси x.- сделайте прямо противоположное преобразование к этому вращению и к этому переводу, поэтому я получу
самолет на своем месте.

хорошо

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

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

Это было полезно?

Решение

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

Преобразовать простую плоскость, например плоскость 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} унитарно.поэтому вам, возможно, придется разделить A B и 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.

то есть

А = -Cos[a]Sin[b]

Б = Син[а]

C = Cos[a]Cos[b]

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

а = 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+By+Cz=0 на -D/C, чтобы получить:

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

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

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

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

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

Другие советы

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

    [ 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) тесты недостаточно в этих случаях. Прочитайте по математике «Плавающая запя», прежде чем начать реализовывать вещи.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top