Pregunta

Quiero dibujar un plano que esté dado por la ecuación: Ax+por+CZ+D = 0. Primero intenté dibujarlo estableciendo X, Y y luego obtuve Z de la ecuación. Esto no funcionó bien porque hay algunos planos como 0x+0y+Z+0 = 0 y etc ...

Mi solución actual es esta: - Dibuja el plano en el plano Zy dando 4 coordenadas que van al infinito. - Descubra la rotación que debe hacerse para que la normalidad del plano dado (a, b, c) se coloque en el eje z. - Encuentre la traducción que debe hacerse para que ese plano esté en el eje x. - Haga la transformación exactamente opuesta a esas rotaciones y a esta traducción, por lo tanto, obtendré el
avión en su lugar.

OK

Esto es una gran cosa, pero puedo hacer los cálculos matemáticos adecuados (probado muchas veces ...) con el producto DOT y etc. ....

¿Alguien puede ayudarme a comprender la forma exacta en que se debe hacer o darme una fórmula en la que pondré ABCD y obtendré la transformación correcta?

¿Fue útil?

Solución

¿Es esto lo que estás pidiendo?

Transformar un plano simple como el plano XY en su avión es bastante simple:

Tu plano es ax+por+cz+d = 0

El plano XY es simplemente z = 0. es decir, a = b = d = 0, mientras c = lo que quieras. Diremos 1 por simplicidad.

Cuando tiene un plano en esta forma, la normalidad del plano está definida por el vector (a, b, c)

Entonces desea una rotación que lo lleve de (0,0,1) a (A, B, C)*

*Tenga en cuenta que esto solo funcionará si {A, B, C} es unitario. Por lo tanto, es posible que tenga que dividir AB y C cada uno por SQRT (A^2+B^2+C^2).

Girar alrededor de dos de los ejes puede llevar su dirección a cualquier otra dirección, por lo que elegiremos X e Y;

Aquí están las matrices de rotación para rotaciones por A aproximadamente el eje x, y B alrededor del eje 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]}}

Si hacemos una rotación sobre X, seguido de una rotación sobre y, del vector normal al plano XY, (0,0,1), obtenemos:

Ry.rx. {0,0,1} = {-cos [a] sin [b], sin [a], cos [a] cos [b]}

cuáles son sus valores de ABC.

es decir

A = -cos [a] sin [b

B = sin [a

C = cos [a] cos [b

Desde aquí, es simple.

a = asin [b

Entonces ahora a = -cos [asin [b]] sin [b

Cos [asin [x]] = sqrt (1-x^2) Entonces:

A = -sqrt [1 -b^2] * sin [b

b = asin [-a/sqrt [1-b^2]

a = asin [b] (rotación sobre el eje x)

b = asin [-a/sqrt [1-b^2]] (rotación sobre el eje y)

Así que ahora tenemos los ángulos sobre los ejes X e Y por los que necesitamos rotar.

Después de esto, solo necesita cambiar su avión hacia arriba o hacia abajo hasta que coincida con el que ya tiene.

El plano que tiene en el momento (después de esas dos rotaciones) será AX+por+CZ = 0.

El plano que desea es ax+bx+cz+d = 0. Para averiguar D, veremos dónde cruza el eje Z cruza su plano.

es decir, cz+d = 0 -> z = -d/c

Entonces transformamos su Z en Ax+by+cz = 0 por -d/c para dar:

Ax+por+c (z+d/c) = ax+by+cz+d = 0. ¡Oh, mirarías eso!

Resulta que no tienes que hacer ninguna matemática adicional una vez que tengas los ángulos para rotar.

Los dos ángulos te darán A, B y C. Para obtener D, solo lo copias de lo que tuviste.

Espero que sea de ayuda, no estoy completamente seguro de cómo planeas dibujar el avión ...

Editado para arreglar un formato horrible. Ojalá sea mejor ahora.

Otros consejos

Querrá la siguiente matriz de transformación:

    [ 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 ]

Aquí, Z0 es la normal de su avión, y o es el origen de su avión, y X0 e Y0 son dos vectores dentro de su avión ortogonal a Z0 que definen la rotación y el sesgo de su proyección.

Entonces, cualquier punto (x, y) en su plano XY se puede proyectar a un punto (p_x, p_y, p_z) su nuevo plano con el siguiente:

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

Ahora, Z0 en su matriz de transformación es fácil, esa es la normalidad de su avión y eso es simplemente n = normalize(a,b,c).

Al elegir el resto, sin embargo, tienes claramente más libertad. Para el origen, puede tomar el punto de que el plano se cruza con el eje Z, a menos que, por supuesto, el plano sea paralelo al eje Z, en cuyo caso necesita algo más.

Entonces, por ejemplo

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;
}

En la práctica, es posible que desee preferir una prueba diferente a (c != 0), porque con esa prueba tendrá éxito incluso es que C es muy muy pequeño, pero es diferente de cero, lo que lleva a su origen a ser, por ejemplo, x=0, y=0, z=10e100 que probablemente no sería deseable. Entonces algunos prueban como (abs(c) > threshold) es probablemente preferible. Sin embargo, por supuesto, podría tomar un punto completamente diferente en el avión para poner el origen, tal vez el punto más cercano al origen de su sistema de coordenadas original, que sería:

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

Luego, finalmente, necesitamos descubrir un X0 e Y0. Que podrían ser dos vectores linealmente independientes que son ortogonales a Z0.

Primero, eligamos un vector en el plano XY para nuestro Vector X0:

x0 = normalize(z0_y, -z0_x, 0)

Ahora, esto falla si su Z0 es del formulario (0, 0, Z0_Z), por lo que necesitamos un caso especial para eso:

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

Finalmente, digamos que no queremos sesgar y elegir y0 para ser ortogonal tanto a x0 como a y0, luego, usando el producto cruzado.

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)

Ahora tienes todo para llenar tu matriz de transformación.

Descargo de responsabilidad: se debe tener cuidado apropiado al usar representaciones de puntos flotantes para sus números, las pruebas simples (foo == 0) no son suficientes en esos casos. Lea en matemáticas de punto flotante antes de comenzar a implementar cosas.

EDITAR: renombró algunas variables para mayor claridad

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top