Adicionalmente, si estais interesados en la programación de videojuegos, motores de juegos y matemáticas y demás frikadas podeis echarle un ojo a mi otro blog : http://lordpakus.blogspot.com.es/

jueves, 8 de septiembre de 2011

Math Engine : Capitulo 2. Clase LPVector

El artículo original lo podeís encontrar aquí

El capitulo de hoy trata sobre la clase LPVector que es la que se encarga de almacenar un vector de cualquier tamaño y poder operar con el.

La lista de operaciones que he considerado imprescindibles son las siguientes, todas las que querais que pongamos adicionales las ponemos... a la que tengamos una lista estable de operaciones nos dedicaremos a optimizarlas con SSE.:
//Funciones anexas.
    void Set(int t, float* vector); //Funcion para inicializar un vector de n elementos
    void Delete();                    //Función para limpiar la variable vector
    void print();                    //Función para imprimir el vector por la consola


    //OPERACIONES DE AMULACIÓN DE RESULTADO (+=,-=,etc...), devuelven void como norma general
    //Operaciones vectoriales
    void operator +=(LPVector vector);           
    void operator -=(LPVector vector);           
    void sqrt_vec();                        //Calculamos la raíz cuadrada de todo los elementos del vector
    void normalize();                        //Normaliza el vector (hace que el módulo sea 1)

    //Operaciones con escalares ( sumar , restar , etc ... todo un vector por un escalar)
    void operator +=(float scal);
    void operator -=(float scal);
    void operator *=(float scal);
    void operator /=(float scal);


    //OPERACIONES QUE DEVUELVEN ALGO (NO ACUMULADORES: +,-,*, etc...)
    //Operaciones vectoriales que devuelven escalares
    float operator ^(LPVector vector);            //Operador producto escalar.
    float module();                                //Calcula el módulo del vector

El código se organiza en dos archivos LPVector (.cpp y .h) junto con los cambios del main para demostrar que funcionan:

main.cpp:
/**************************************************************************************************/
//        Código creado por F.Bordas (LordPakus) como ejemplo de creación de un math engine
//        para el blog LordPakus (http://lordpakus.blogspot.com/).
//        Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/

/**************************************************************************************************/
// main.cpp : Main de nuestro MathEngine
/**************************************************************************************************/

//Include del Math engine
#include "LPMath.h"

//Delete console
//#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

#include <iostream>                //Usada para imprimir por consola

using namespace std;

int main (int argc, char* argv[])
{
    LPVector v1,v2;
    float vec1[4] = { 1.0f ,1.1f ,1.5f ,2.5f };
    float vec2[4] = { 3.0f ,4.1f ,0.5f ,0.4f };

    float n;

    //Creamos los vectores
    v1.Set(4,vec1);
    v2.Set(4,vec2);

    cout << "Vector 1: ";
    v1.print();
    cout << "\n";

    cout << "Vector 2: ";
    v2.print();
    cout << "\n";
   
    n = v1^v2;
    cout << "Producto escalar: " <<    n << "\n";

    n = v1.module();
    cout << "Modulo vector 1: " <<    n << "\n";

    n = v2.module();
    cout << "Modulo vector 2: " <<    n << "\n";

    v1.normalize();
    n = v1.module();
    cout << "Modulo vector 1 normalizado: " <<    n << "\n";

    v2.normalize();
    n = v2.module();
    cout << "Modulo vector 2 normalizado: " <<    n << "\n";

    v2 += v1;
    cout << "Suma de vectores: ";
    v2.print();
    cout << "\n";

    n = v2.module();
    cout << "Modulo de suma de vectores: " <<    n << "\n";

    v2.normalize();
    n = v2.module();
    cout << "Modulo de suma de vectores normalizado: " <<    n << "\n";


    //Eliminamos los vectores
    v1.Delete();
    v2.Delete();

    system("PAUSE");
}

LPVector.cpp
/**************************************************************************************************/
//        Código creado por F.Bordas (LordPakus) como ejemplo de creación de un math engine
//        para el blog LordPakus (http://lordpakus.blogspot.com/).
//        Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/

#include "LPVector.h"
#include <math.h>
#include <iostream>                //Usada para imprimir por consola

using namespace std;

//Constructor
LPVector::LPVector()
{
    n = 0;
    v = NULL;
}

//Destructor
LPVector::~LPVector()
{
    //if (n)
    //{
    //    if( v != NULL )
    //        free(v);
    //}
}

//Funcion para inicializar un vector de n elementos
void LPVector::Set(int t, float* vector)
{
    n = t; //Inicializamos el número de elementos del vector

    //Creamos un vector de memoria dinámica.
    v = (float*) malloc( sizeof(float) * n );

    //Copiamos el vector externo en el vector interno
    memcpy(v,vector,sizeof(float) * n );
}

//Función para limpiar la variable vector
void LPVector::Delete()
{
    n=0;
    free(v);
}

//Imprimimos el valor del vector
void LPVector::print()
{
    for(int i = 0 ; i < n ; ++i)
    {
        cout << (float) v[i] << " ";
    }
}

void LPVector::random(int t, float min, float max)
{
    n = t; //Inicializamos el número de elementos del vector

    //Creamos un vector de memoria dinámica.
    v = (float*) malloc( sizeof(float) * n );

    for(int i = 0 ; i < n ; ++i)
        v[i] = (float)(rand()%(int)(max*1000 - min*1000))/1000 + min;

}

void LPVector::cross(LPVector vector)
{
    //POR IMPLEMENTAR
}

void LPVector::sqrt_vec()
{
    for(int i = 0 ; i < n ; ++i)
        v[i] = sqrt(v[i]);
}

void LPVector::normalize()
{
    //Dividimos cada componente por el módulo
    *this /= this->module();
}

//Sobrecarga operador +=
void LPVector::operator +=(LPVector vector)
{
    //Si las dimensiones son diferentes , tenemos un problema grave.
    if (n != vector.n)
    {
        cout << "ERROR DIMENSIONAL ENTRE VECTORES\n";
        return;
    }

    for(int i = 0 ; i < n ; ++i)
        v[i] += vector.v[i];
  
}

//Sobrecarga operador -=
void LPVector::operator -=(LPVector vector)
{
    //Si las dimensiones son diferentes , tenemos un problema grave.
    if (n != vector.n)
    {
        cout << "ERROR DIMENSIONAL ENTRE VECTORES\n";
        return;
    }

    for(int i = 0 ; i < n ; ++i)
        v[i] -= vector.v[i];
}

//Sobrecarga operador +=
void LPVector::operator +=(float scal)
{
    for(int i = 0 ; i < n ; ++i)
        v[i] += scal;
}

//Sobrecarga operador -=
void LPVector::operator -=(float scal)
{
    for(int i = 0 ; i < n ; ++i)
        v[i] -= scal;
}

//Sobrecarga operador *=
void LPVector::operator *=(float scal)
{
    for(int i = 0 ; i < n ; ++i)
        v[i] *= scal;
  
}

//Sobrecarga operador /=
void LPVector::operator /=(float scal)
{
    for(int i = 0 ; i < n ; ++i)
        v[i] /= scal;
  
}
//Sobrecarga operador *= //Este operador es el que nos devolverá matrices como resultado del producto de una columna por un fila.
                         //Es decir, es el producto vectorial. Ya lo veremos a su momento
/*void LPVector::operator *=(LPVector vector)
{
    //Si las dimensiones son diferentes , tenemos un problema grave.
    if (n != vector.n)
    {
        cout << "ERROR DIMENSIONAL ENTRE VECTORES\n";
        return;
    }

    for(int i = 0 ; i < n ; ++i)
        v[i] += vector.v[i];
}
*/

//Sobrecarga operador ^ A partir de ahora se entederá que es el producto escalar.
float LPVector::operator ^(LPVector vector)
{
    float a = 0.0;

    //Si las dimensiones son diferentes , tenemos un problema grave.
    if (n != vector.n)
    {
        cout << "ERROR DIMENSIONAL ENTRE VECTORES\n";
        return 0.0;
    }

    for(int i = 0 ; i < n ; ++i)
        a += v[i] * vector.v[i];

    return a;
}

float LPVector::module()
{
    float a = 0.0;

    for(int i = 0 ; i < n ; ++i)
        a += v[i] * v[i];

    return sqrt(a);
}

float LPVector::distance(LPVector vector)
{
    float a = 0.0;
    float temp = 0.0;

    //Si las dimensiones son diferentes , tenemos un problema grave.
    if (n != vector.n)
    {
        cout << "ERROR DIMENSIONAL ENTRE VECTORES\n";
        return (-1.0);
    }

    for(int i = 0 ; i < n ; ++i)
    {
        temp = (v[i] - vector.v[i]);
        a+=temp*temp;
    }

    return sqrt(a);
}


LPVector.h
/**************************************************************************************************/
//        Código creado por F.Bordas (LordPakus) como ejemplo de creación de un math engine
//        para el blog LordPakus (http://lordpakus.blogspot.com/).
//        Prohibida la distribución fuera de este blog sin el permiso expreso del autor
/**************************************************************************************************/


/**************************************************************************************************/
// LPVector.h
/**************************************************************************************************/

#ifndef __LPVector__
#define __LPVector__

class LPVector
{
public:
    LPVector();
    ~LPVector();

    //Funciones anexas.
    void Set(int t, float* vector); //Funcion para inicializar un vector de n elementos
    void Delete();                    //Función para limpiar la variable vector
    void print();                    //Función para imprimir el vector por la consola
    void random(int t,float min, float max);                //Función para rellenar de random un vector de t posiciones

    //OPERACIONES DE AMULACIÓN DE RESULTADO (+=,-=,etc...), devuelven void como norma general
    //Operaciones vectoriales
    void operator +=(LPVector vector);          
    void operator -=(LPVector vector);  
    void cross(LPVector vector);            //Calculamos el producto vectorial (cross) POR HACER
    void sqrt_vec();                        //Calculamos la raíz cuadrada de todo los elementos del vector
    void normalize();                        //Normaliza el vector (hace que el módulo sea 1)
          

    //Operaciones con escalares ( sumar , restar , etc ... todo un vector por un escalar)
    void operator +=(float scal);
    void operator -=(float scal);
    void operator *=(float scal);
    void operator /=(float scal);


    //OPERACIONES QUE DEVUELVEN ALGO (NO ACUMULADORES: +,-,*, etc...)
    //Operaciones vectoriales que devuelven escalares
    float operator ^(LPVector vector);            //Operador producto escalar.
    float module();                                //Calcula el módulo del vector
    float distance(LPVector vector);

public:
    int n;         //número de elementos del vector
    float *v;    //puntero a memoria dinámica
};

#endif
Cualquier otra cosa que se os ocurra que le pongamos o cualquier fallo que veais, hacedmelo llegar

Espero que os haya gustado,

Nos vemos

No hay comentarios:

Publicar un comentario