Suponga que está escribiendo un código de matriz que maneja la rotación, la traducción, etc. para el espacio 3d.
Ahora las matrices de transformación tienen que ser 4x4 para encajar el componente de traducción.
Sin embargo, en realidad no necesita almacenar un w
componente en el vector, ¿verdad?
Incluso en la división de perspectiva, puede simplemente calcular y almacenar w
fuera del vector, y dividir la perspectiva antes de regresar del método.
Por ejemplo:
// post multiply vec2=matrix*vector
Vector operator*( const Matrix & a, const Vector& v )
{
Vector r ;
// do matrix mult
r.x = a._11*v.x + a._12*v.y ...
real w = a._41*v.x + a._42*v.y ...
// perspective divide
r /= w ;
return r ;
}
¿Hay algún punto en el almacenamiento w
en la clase Vector?
mathematics
vector
projection
bobobobo
fuente
fuente
r.x = ... + a._14*v.w;
r.y = ... + a._24*v.w;
r.z = ... + a._34*v.w;
r.w = ... + a._44*v.w;
mira mi respuesta para más detallesRespuestas:
Exención de responsabilidad de EDIT : por conveniencia en esta respuesta, los vectores con w == 0 se denominan vectores y con w == 1 se denominan puntos. Aunque, como señaló FxIII, esa no es una terminología matemáticamente correcta. Sin embargo, dado que el punto de la respuesta no es la terminología, sino la necesidad de distinguir ambos tipos de vectores, me atendré a ella. Por razones prácticas, esta convención se usa ampliamente en el desarrollo de juegos.
No es posible distinguir entre vectores y puntos sin un componente 'w'. Es 1 para puntos y 0 para vectores.
Si los vectores se multiplican con una matriz de transformación afín 4x4 que tiene una traducción en su última fila / columna, el vector también se traduciría, lo cual es incorrecto, solo se deben traducir los puntos. El cero en el componente 'w' de un vector se encarga de eso.
Al resaltar esta parte de la multiplicación matriz-vector, queda más claro:
Es decir, sería incorrecto traducir un vector, por ejemplo, un eje de rotación, el resultado es simplemente incorrecto. Al tener su cuarto componente cero, aún puede usar la misma matriz que transforma los puntos para transformar el eje de rotación y el resultado será válido y su longitud se conserva siempre que no haya escala en la matriz. Ese es el comportamiento que desea para los vectores. Sin el cuarto componente, tendría que crear 2 matrices (o 2 funciones de multiplicación diferentes con un cuarto parámetro implícito) y realizar 2 llamadas a funciones diferentes para puntos y vectores.
Para usar los registros vectoriales de las CPU modernas (SSE, Altivec, SPU), debe pasar 4x 32 bits flotantes de todos modos (es un registro de 128 bits), además de tener que ocuparse de la alineación, generalmente 16 bytes. Por lo tanto, no tiene la oportunidad de proteger el espacio para el cuarto componente de todos modos.
EDITAR: la respuesta a la pregunta es básicamente
Uno debe elegir uno de ellos, no es posible almacenar solo {x, y, z} y aún usar solo una función de multiplicación de matriz-vector. XNA, por ejemplo, utiliza el último enfoque al tener 2 funciones de transformación en su clase Vector3 , llamadas
Transform
yTransformNormal
Aquí hay un ejemplo de código que muestra ambos enfoques y demuestra la necesidad de distinguir ambos tipos de vectores en 1 de las 2 formas posibles. Vamos a mover una entidad de juego con una posición y una dirección de mirada en el mundo transformándola con una matriz. Si no usamos el componente 'w', ya no podemos usar la misma multiplicación de matriz-vector, como lo demuestra este ejemplo. Si lo hacemos de todos modos, obtendremos una respuesta incorrecta para el
look_dir
vector transformado :Estado de entidad inicial:
Ahora se aplicará a esta entidad una transformación con una traducción de x + 5 y una rotación de 90 grados alrededor del eje y. La respuesta correcta después de la transformación es:
Solo obtendremos la respuesta correcta si distinguimos los vectores con w == 0 y las posiciones con w == 1 en una de las formas presentadas anteriormente.
fuente
Si está haciendo una clase de Vector, entonces supongo que la clase almacenará la descripción de un vector 3D. Los vectores 3D tienen magnitudes x, y y z. Entonces, a menos que su vector necesite una magnitud w arbitraria, no, no lo almacenará en la clase.
Hay una gran diferencia entre un vector y una matriz de transformación. Dado que DirectX y OpenGL manejan matrices para usted, normalmente no almaceno una matriz 4x4 en mi código; más bien, almaceno las rotaciones de Euler (o Quaternions si lo desea, que casualmente tienen un componente aw) y la traducción x, y, z. La traducción es un vector si lo desea, y la rotación técnicamente también encajaría en un vector, donde cada componente almacenaría la cantidad de rotación alrededor de su eje.
Si quieres sumergirte un poco más en las matemáticas de un vector, un vector euclidiano es solo una dirección y una magnitud. Por lo general, esto se representa mediante un triplete de números, donde cada número es la magnitud a lo largo de un eje; su dirección está implícita en la combinación de estas tres magnitudes, y la magnitud se puede encontrar con la fórmula de distancia euclidiana . O, a veces, realmente se almacena como una dirección (un vector con longitud = 1) y una magnitud (un flotador), si eso es conveniente (por ejemplo, si la magnitud cambia con más frecuencia que la dirección, puede ser más conveniente simplemente cambiar ese número de magnitud que tomar un vector, normalizarlo y multiplicar los componentes por la nueva magnitud).
fuente
La cuarta dimensión en el vector 3D se usa para calcular las transformaciones afines que serán imposibles de calcular usando solo matrices. El espacio sigue siendo tridimensional, por lo que esto significa que el cuarto está mapeado en el espacio 3d de alguna manera.
Mapear una dimensión significa que diferentes vectores 4D indican el mismo punto 3D. El mapa es que si A = [x ', y', z'.w '] y B = [x ", y", z ", w"] representan el mismo punto si x' / x "= y ' / y "= z '/ z" = w' / w "= α, es decir, el componente es proporcional para el mismo coeficiente α.
Dijo que puedes expresar un punto, digamos (1,3,7), de maneras infinitas como (1,3,7,1) o (2,6,14,2) o (131,393,917,131) o en general (α · 1, α · 3, α · 7, α).
Esto significa que puede escalar un vector 4D a otro que represente el mismo punto 3D para que w = 1: la forma (x, y, z, 1) sea la forma canónica.
Cuando aplica una matriz a este vector, puede obtener un vector que no tiene w = 1, pero siempre puede escalar los resultados para almacenarlo en forma canónica. Entonces, la respuesta parece ser "deberías usar vectores 4D cuando hagas matemáticas pero no guardes el cuarto componente" .
Esto es bastante cierto, pero hay algunos puntos que no puedes poner en forma canónica: puntos como (4,2,5,0). Esos puntos son especiales, representan el punto infinito dirigido y se pueden normalizar al vector unitario de manera consistente: puedes ir al infinito de manera segura y regresar (incluso dos veces) sin ser Chuck Norris. Obtendrá una división miserable por cero si intenta forzar esos vectores en forma canónica.
Ahora ya lo sabes, ¡así que la elección es tuya!
fuente
Si tu puedes. Su transformación es incorrecta para algunos tipos de vectores. Puede ver esto en la biblioteca matemática D3DX: tienen dos funciones de multiplicación de vectores de matriz diferentes, una para w = 0 y otra para w = 1.
fuente
Depende de lo que quieras y necesites. :)
Lo almacenaría, b / c ES necesario para transformaciones y demás (no se puede multiplicar un vector 3 con una matriz 4x4), aunque si siempre tiene un aw de 1, supongo que podría simularlo.
fuente