Matemáticas y videojuegos (IV)

BasicGeometry-479x620En episodios anteriores (vectores, matrices y quaterniones) hemos tratado los fundamentos básicos del mundo de las tres dimensiones.

Ahora vamos a subir un nivel de abstracción y hablaremos sobre geometría básica.

Líneas.

Dados dos puntos, o vectores, A y B, podemos definir la línea L que pasan por ambos como:

 

L(t) = (1t)A + tB

Donde es el rango de todos los números reales, por lo que puedes deducir que la longitud de L es infinita. Si solo nos interesa el rango entre los puntos A y B (en verde), el segmento esta definido en el rango de t entre 0 y 1.

Segmento-definicion

 

 

Un rayo es como una línea pero con un punto de origen, S, y hasta el infinito y mas allá en la dirección V. Se puede expresar como:

 

R(t) = S + tV

Donde t >= 0. Esta ecuación también es usada para definir lineas, de echo es la misma si S = A y V = BA.

public struct Ray
{
  public Vector3 position;

  public Vector3 direction;
}

Vamos a utilizar nuestros conocimientos en un caso práctico, hallar la distancia de un punto P a una línea, definida por el punto S y su dirección V.

 

Math4_00

 

Si imaginamos una nueva línea que pase por P y que sea perpendicular a la línea original, su longitud será la distancia mínima que queremos calcular. Para esto vamos a imaginar otra línea más, una que una S con P.

 

Todas estas líneas, unidas a formada por la proyección de PS en SV, forman un triángulo:

 

Math4_01

 

Gracias a nuestro amigo Pitágoras y a su famoso teorema, sabemos que:

d2 = (PS)2 – (proj(PS))2

Simplificando un poco para aislar a d:

Math4_02

 

Planos.

Podemos definir un plano como un punto P y vector normal (perpendicular al plano) N. Si el punto P pertenece al plano y es perpendicular a la dirección de N:

Math4_03

 

Entonces cualquier punto Q que pertenezca al plano debe cumplir que N · (QP) = 0. La ecuación con la que se suele representar a un plano es:

 

Ax + By + Cz + D = 0

Donde A, B y C son las componentes del vector N y D = –N·P.

public struct Plane
{
  public double d;

  public Vector3 normal;
}

Como hicimos con las líneas, vamos a ver un caso practico. Vamos calcular la intersección de una línea y un plano, una operación muy común en cualquier motor 3D.

Tenemos una línea P(t) = S + tV y un plano definido por su normal N y la distancia D. Podremos obtener el punto en el que se cruzan, resolviendo la ecuación:

 

N·P(t) + D = 0

Substituyendo P(t) por S + tV, obtenemos:

N·S + (N·V)t + D = 0

Aislando t:

t = -(N·S + D) / (N·V)

Si metemos t en la ecuación de la línea P(t) = S + tV, obtendremos el punto de intersección. Si N·V = 0, la línea es paralera al plano.

Como veremos en el siguiente capítulo (sobre el Frustum… spoiler!) es muy común que regiones de un espacio 3D estén definidas por una serie de planos que lo engloban, cuyos ejes forman un poliedro convexo.

Veamos el caso de tres planos L1 = (N1, D1), L2 = (N2, D2) y L3 = (N3, D3) y si se cruzan en el punto Q.

Secretsharing_3-point.svg_

 Para que ocurra se tiene que cumplir que:

L1·Q = 0

L2·Q = 0

L3·Q = 0

Escrito como una matriz:

Math4_04

Donde la matrix M es:

Math4_05

Asumiendo que M es invertible, obtener el punto Q sería:Math4_06

Si M es una matriz singular (su determinante es igual a cero), entonces los tres planos no compartirían ningún punto.

triangle

 

Con esto acabamos el tema de geometría básica. Como siempre, podéis descargaros el código de esta serie de artículos de nuestro Github.

 

githubLink

¡Hasta el próximo capítulo!

You Might Also Like

No Comments

Leave a Reply