Geometría Analítica en Videojuegos - Math And Unity

¿Hay que saber matemáticas para aprender a programar?

¿Se necesita saber matemática avanzada para programar?

¿Qué nivel de matemáticas se necesita para programar?


La respuesta a si es que necesitas saber matemática, es SI.
Lo de que tiene que ser tan avanzada, la verdad no lo creo, más bien, necesitas matemática más especifica, como lo es la "lógica proposicional", nociones numéricas como "la división y el resto", pero la que más me encuentro siempre es "geometría analítica", sobre todo en videojuegos, así que voy a empezar a explicar un poco de que trata esto.


Geometría Analítica

Sucede que un día, un señor con fiebre acostado en su cama, no tenía nada mejor que mirar como una araña que bajaba por su ventana que tenía una rejilla cuadriculada y se le ocurrió una manera "matemática" de describir la posición de la araña, consistía en lo siguiente, describir cuantos barrotes a la derecha estaba desplazada y luego cuantos barrotes hacia arriba estaba, es decir, con esos dos datos o coordenadas podría saber la posición de la araña, a su invento lo llamaron el plano cartesiano y se hizo famoso gracias a que ese señor, era Rene Descartes. Claro, si a mi se me hubiese ocurrido lo mismo mientras estaba acostado ni me hubieran pescado u.u


Las coordenadas pueden representar puntos (x,y) en el espacio, o gráficar funciones (x, f(x)), donde en vez de poner  y ponemos el resultado de aplicar f(x) a x, o incluso podemos dibujar circunferencias x2 + y2 = r2 u otros lugares geométricos cómo las hipérbolas u otros, si quieres jugar con algunas gráficas, te recomiendo este sitio web/ aplicación que es muy útil para ello. Geogebra.


Graficando Funciones en Unity

La primera vez que intente graficar algo, lo hice en Flash 8 y usando curveTo y lineTo, pero ahora le toca el turno a Unity, voy a tratar de hacer las más útiles:

Función Lineal 

y= x
Que te puede servir, por ejemplo para indicar la trayectoria de un objeto al cursor, de un movimiento en diagonal, de una bolita de billar, de un rayo laser, etc, etc, etc.

Función Cuadrática

y=x2
Que te puede servir, principalmente para lanzar misiles como en angry birds, o el saltito del mario bros, etc, etc, etc.


Manos a la Obra

1.    Creamos un proyecto 2D (para empezar y no complicarnos con el 3D, por ahora)
2.    Creamos un objeto vació, que vamos a llamar Main y le añadimos un componente que vamos a llamar Main.cs
3.    Usaremos Gizmos para dibujar, así que añade la vista de "edición" junto con la "juego" (con la distribución 2 by 3 está bien)
4.    Dibujamos un punto, en (2,3) y luego una recta que va de (0,0) a (2,3)


El código queda así:

public class Main : MonoBehaviour
{
    float radio = 0.1f;
    Vector3 p0 = new Vector3(0f, 0f);
    Vector3 p1 = new Vector3(2f, 3f);

    void OnDrawGizmosSelected() {
        Gizmos.color = Color.blue;
        //dibujamos el punto
        Gizmos.DrawSphere(p1, radio);
        //dibujamos la recta
        Gizmos.DrawLine(p0, p1);
    }
}


Ahora que sabemos como hacer lineas y puntos, hay que explicar algo acerca de las gráficas.
Se supone que la gráfica de una función es una colección infinita de puntos, pero como vez, al hacer puntos en Unity quedan muy grandes, y tampoco puedo hacer infinitos puntos, por lo que nos tomaremos algunas licencias:
  1. dibujaremos una cantidad finita de puntos, dentro un rango y con cierta resolución dada, por ejemplo, podemos dibujar los puntos que van de 0 a 1 pero saltando de 0,1 en 0,1 (0,1 es la resolución)
  2. uniremos cada punto con el punto anterior a través de una recta, por lo que las funciones discontinuas podrían verse mal.
Empezare dibujando la función cuadrática, acá el resultado
y acá el código:
public class Main : MonoBehaviour
{
    public float min =-2f;
    public float max = 2f;
    public float resolucion = 0.1f;
    float f(float x) {
        return x*x;
    }

    void OnDrawGizmosSelected() {
        Gizmos.color = Color.blue;
        float x = min;
        float y;
        while (x <= max && resolucion<=0f) {//<--si pongo resolucion negativa 0f se pega
            float x0 = x;
            float y0 = f(x0);
            float x1 = x + resolucion;
            float y1 = f(x1);
            Gizmos.DrawLine(new Vector3(x0, y0), new Vector3(x1, y1));
            x = x + resolucion;
        }
    }
}
Puedo cambiar la función por lo que yo quiera, por ejemplo, puedo poner la función Seno y quedaría:
y solo cambie

 float f(float x) {
        return Mathf.Sin(x);
    }

y también cambie aumente el rango.
Te invito a jugar con la resolución y el rango ya veremos algunas otras cosas mas en la siguiente entrada.


Comentarios