Tutorial relacionado con el curso de programación C/C++ LordPakus
Por que programar no es solo hacer juegos si no también programas "serios" os dejo estos links....
Blog de programación enfocado a estudiantes principiantes de C/C++ en español. Dispone de cursos de todos los niveles y para multitud de usos.
Mostrando entradas con la etiqueta math engine. Mostrar todas las entradas
Mostrando entradas con la etiqueta math engine. Mostrar todas las entradas
miércoles, 9 de enero de 2013
sábado, 3 de septiembre de 2011
Math Engine : Capitulo 0. Esquema de un math engine
Hola a todos...
Igual que hice con el game engine aquí os dejo un esquema del math engine para que podais entender y acceder más facilmente a cada una de sus partes.
El LP Math Engine tiene tres clases principales
Vector: La clase vector contiene un vector de floats de tamaño arbitrario y todas las funciones asociadas de intereacción entre vector-vector y vector-escalar. http://lordpakus.blogspot.com/2011/08/math-engine-capitulo-2-clase-lpvector.html
Matriz: La clase matriz contiene un matriz de floats de dimensiones arbiarias y todas las funciones asociadas de interacción entre matriz-matriz, matriz-vector y matriz-escalar.http://lordpakus.blogspot.com/2011/08/math-engine-capitulo-3-clase-lpmatrix.html
Serie de datos: La clase serie de datos contiene un vector de datos de longitud arbitraria que se pueden interpretar como una serie estadistica, una discretización de señal, un muestreo de función matemática,etc.. Incorpora funciones de tratamiento de la señal (FFT por ejemplo), de tratamiento de funciones (derivación e integración) y de tratamiento estadístico (medias, varianzas, modelos estadisticos,rectas de regresión) http://lordpakus.blogspot.com/2011/08/math-engine-capitulo-4-clase-lpdata.html
Aparte de estas clases el math engine tiene dos caracteristicas importantes:
-> Sobrecarga de operadores: Es decir, se basa en esta caracteristica de la POO para facilitar el trabajo al programador de aplicaciones matematicas, escondiendo cientos o miles de lineas de código en operciones sencillas de entender conceptualmente http://lordpakus.blogspot.com/2011/08/math-engine-capitulo-1-sobrecarga-de.html
-> Uso de optimizaciones:
- Ensamblador SSE: El ensamblador SSE es un conjunto de operaciones que tienen la mayoria de procesadores actuales que permiten realizar numerosas operaciones en paralelo. Para más información podeis mirar: http://lordpakus.blogspot.com/2011/08/curso-de-programacion-capitulo-7.html
Ejemplo de SSE en la suma de vectores: http://lordpakus.blogspot.com/2011/09/math-engine-capitulo-5-lpvector-con.html
Ejemplo de SSE en la distancia entre vectores: http://lordpakus.blogspot.com/2011/09/math-engine-capitulo-6-vectordistance.html
- Paralelización multicore: WORKING. En breve tendremos tutoriales de paralelización
Espero que os haya gustado y que os haya ayudado a organizar la información
Nos vemos
viernes, 26 de agosto de 2011
Math Engine : Capitulo 3. Clase LPMatrix
Capítulo perteneciente al math engine LordPakus
Hola a todos,
Bienvenidos a un nuevo capitulo de como crear un math engine. El capitulo de hoy se encargará de mostrar el tipo de variable que seguramente más se usará en las aplicaciones de cálculo, las matrices.
Dado que es totalmente imposible poner todas las funciones que afectan a matrices (solamente con factorizaciones podria llenar miles de lineas de código) este capitulo lo dejaré totalmente abierto (como el del LPVector) para que me vayais proponiendo las funciones que querais que introduzcamos en este módulo.
No obstante, si quereis ir probando código aquí os dejo lo que he implementado hasta el momento:
LPMatrix.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
/**************************************************************************************************/
/**************************************************************************************************/
// LPMatrix.h
/**************************************************************************************************/
#ifndef __LPMatrix__
#define __LPMatrix__
class LPMatrix
{
public:
LPMatrix();
~LPMatrix();
//Funciones anexas.
void Set(int t, int k, float* vector); //Funcion para inicializar una matriz de t*k elementos
void Delete(); //Función para limpiar la variable matriz
void print(); //Función para imprimir la matriz por la consola
//OPERACIONES DE ACUMULACIÓN DE RESULTADO (+=,-=,etc...), devuelven void como norma general
//Operaciones vectoriales
void operator +=(LPMatrix matrix);
void operator -=(LPMatrix matrix);
//Operaciones con escalares ( sumar , restar , etc ... todo una matriz por un escalar)
void operator +=(float scal);
void operator -=(float scal);
void operator *=(float scal);
void operator /=(float scal);
public:
int m,n; //dimensiones de la matriz
float **p; //puntero a memoria dinámica para matrices
};
#endif
LPMatrix.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 "LPMatrix.h"
#include <math.h>
#include <iostream> //Usada para imprimir por consola
using namespace std;
//Constructor
LPMatrix::LPMatrix()
{
n = 0;
m = 0;
p = NULL;
}
//Destructor
LPMatrix::~LPMatrix()
{
}
//Funciones anexas.
void LPMatrix::Set(int t, int k, float* vector) //Funcion para inicializar una matriz de t*k elementos
{
//Inicializamos el número de elementos del vector
n = t;
m = k;
//Creamos un vector de memoria dinámica donde almacenaremos los punteros subsiguientes.
p = (float**) malloc( sizeof(float *) * n );
//Creamos cada una de las filas o columnas (como queramos verlo) de la matriz
for(int i = 0 ; i < n ; ++i )
p[i] = (float*) malloc( sizeof(float) * m );
//Copiamos el vector externo en el vector interno
for(int i = 0 ; i < n*m ; ++i )
p[i/m][i%m] = vector[i];
}
void LPMatrix::Delete() //Función para limpiar la variable matriz
{
for(int i = 0 ; i < n ; ++i )
free(p[i]);
n=0;
m=0;
free(p);
}
void LPMatrix::print() //Función para imprimir la matriz por la consola
{
for(int i = 0 ; i < n*m ; ++i)
{
if(!(i%m))
cout << "\n";
cout << (float) p[i/m][i%m] << " ";
}
}
//OPERACIONES DE ACUMULACIÓN DE RESULTADO (+=,-=,etc...), devuelven void como norma general
//Operaciones vectoriales
void LPMatrix::operator +=(LPMatrix matrix)
{
//Si las dimensiones son diferentes , tenemos un problema grave.
if ( (n != matrix.n) || (m != matrix.m) )
{
cout << "ERROR DIMENSIONAL ENTRE MATRICES\n";
return;
}
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] += matrix.p[i][j];
}
void LPMatrix::operator -=(LPMatrix matrix)
{
//Si las dimensiones son diferentes , tenemos un problema grave.
if ( (n != matrix.n) || (m != matrix.m) )
{
cout << "ERROR DIMENSIONAL ENTRE MATRICES\n";
return;
}
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] -= matrix.p[i][j];
}
//Operaciones con escalares ( sumar , restar , etc ... todo una matriz por un escalar)
void LPMatrix::operator +=(float scal)
{
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] += scal;
}
void LPMatrix::operator -=(float scal)
{
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] -= scal;
}
void LPMatrix::operator *=(float scal)
{
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] *= scal;
}
void LPMatrix::operator /=(float scal)
{
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] /= scal;
}
main.cpp
int main (int argc, char* argv[])
{
LPMatrix m1,m2;
float mat1[15] = { 1.0f ,1.1f ,1.5f , 1.0f ,1.1f ,1.5f , 1.0f ,1.1f ,1.5f , 1.0f ,1.1f ,1.5f , 1.0f ,1.1f ,1.5f };
float mat2[15] = { 3.0f ,4.1f ,0.5f , 3.0f ,4.1f ,0.5f , 3.0f ,4.1f ,0.5f , 3.0f ,4.1f ,0.5f , 3.0f ,4.1f ,0.5f };
m1.Set(3,5,mat1);
m2.Set(3,5,mat2);
cout << "Matriz 1:";
m1.print();
cout << "\n";
cout << "Matriz 2:";
m2.print();
cout << "\n";
cout << "Suma de matrices:";
m2 += m1;
m2.print();
cout << "\n";
//Eliminamos las matrices
m1.Delete();
m2.Delete();
system("PAUSE");
}
Espero que os haya servido y os haya gustado.
Nos vemos
Hola a todos,
Bienvenidos a un nuevo capitulo de como crear un math engine. El capitulo de hoy se encargará de mostrar el tipo de variable que seguramente más se usará en las aplicaciones de cálculo, las matrices.
Dado que es totalmente imposible poner todas las funciones que afectan a matrices (solamente con factorizaciones podria llenar miles de lineas de código) este capitulo lo dejaré totalmente abierto (como el del LPVector) para que me vayais proponiendo las funciones que querais que introduzcamos en este módulo.
No obstante, si quereis ir probando código aquí os dejo lo que he implementado hasta el momento:
LPMatrix.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
/**************************************************************************************************/
/**************************************************************************************************/
// LPMatrix.h
/**************************************************************************************************/
#ifndef __LPMatrix__
#define __LPMatrix__
class LPMatrix
{
public:
LPMatrix();
~LPMatrix();
//Funciones anexas.
void Set(int t, int k, float* vector); //Funcion para inicializar una matriz de t*k elementos
void Delete(); //Función para limpiar la variable matriz
void print(); //Función para imprimir la matriz por la consola
//OPERACIONES DE ACUMULACIÓN DE RESULTADO (+=,-=,etc...), devuelven void como norma general
//Operaciones vectoriales
void operator +=(LPMatrix matrix);
void operator -=(LPMatrix matrix);
//Operaciones con escalares ( sumar , restar , etc ... todo una matriz por un escalar)
void operator +=(float scal);
void operator -=(float scal);
void operator *=(float scal);
void operator /=(float scal);
public:
int m,n; //dimensiones de la matriz
float **p; //puntero a memoria dinámica para matrices
};
#endif
LPMatrix.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 "LPMatrix.h"
#include <math.h>
#include <iostream> //Usada para imprimir por consola
using namespace std;
//Constructor
LPMatrix::LPMatrix()
{
n = 0;
m = 0;
p = NULL;
}
//Destructor
LPMatrix::~LPMatrix()
{
}
//Funciones anexas.
void LPMatrix::Set(int t, int k, float* vector) //Funcion para inicializar una matriz de t*k elementos
{
//Inicializamos el número de elementos del vector
n = t;
m = k;
//Creamos un vector de memoria dinámica donde almacenaremos los punteros subsiguientes.
p = (float**) malloc( sizeof(float *) * n );
//Creamos cada una de las filas o columnas (como queramos verlo) de la matriz
for(int i = 0 ; i < n ; ++i )
p[i] = (float*) malloc( sizeof(float) * m );
//Copiamos el vector externo en el vector interno
for(int i = 0 ; i < n*m ; ++i )
p[i/m][i%m] = vector[i];
}
void LPMatrix::Delete() //Función para limpiar la variable matriz
{
for(int i = 0 ; i < n ; ++i )
free(p[i]);
n=0;
m=0;
free(p);
}
void LPMatrix::print() //Función para imprimir la matriz por la consola
{
for(int i = 0 ; i < n*m ; ++i)
{
if(!(i%m))
cout << "\n";
cout << (float) p[i/m][i%m] << " ";
}
}
//OPERACIONES DE ACUMULACIÓN DE RESULTADO (+=,-=,etc...), devuelven void como norma general
//Operaciones vectoriales
void LPMatrix::operator +=(LPMatrix matrix)
{
//Si las dimensiones son diferentes , tenemos un problema grave.
if ( (n != matrix.n) || (m != matrix.m) )
{
cout << "ERROR DIMENSIONAL ENTRE MATRICES\n";
return;
}
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] += matrix.p[i][j];
}
void LPMatrix::operator -=(LPMatrix matrix)
{
//Si las dimensiones son diferentes , tenemos un problema grave.
if ( (n != matrix.n) || (m != matrix.m) )
{
cout << "ERROR DIMENSIONAL ENTRE MATRICES\n";
return;
}
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] -= matrix.p[i][j];
}
//Operaciones con escalares ( sumar , restar , etc ... todo una matriz por un escalar)
void LPMatrix::operator +=(float scal)
{
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] += scal;
}
void LPMatrix::operator -=(float scal)
{
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] -= scal;
}
void LPMatrix::operator *=(float scal)
{
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] *= scal;
}
void LPMatrix::operator /=(float scal)
{
for(int i = 0 ; i < n ; ++i)
for(int j = 0 ; j < m ; ++j)
p[i][j] /= scal;
}
main.cpp
int main (int argc, char* argv[])
{
LPMatrix m1,m2;
float mat1[15] = { 1.0f ,1.1f ,1.5f , 1.0f ,1.1f ,1.5f , 1.0f ,1.1f ,1.5f , 1.0f ,1.1f ,1.5f , 1.0f ,1.1f ,1.5f };
float mat2[15] = { 3.0f ,4.1f ,0.5f , 3.0f ,4.1f ,0.5f , 3.0f ,4.1f ,0.5f , 3.0f ,4.1f ,0.5f , 3.0f ,4.1f ,0.5f };
m1.Set(3,5,mat1);
m2.Set(3,5,mat2);
cout << "Matriz 1:";
m1.print();
cout << "\n";
cout << "Matriz 2:";
m2.print();
cout << "\n";
cout << "Suma de matrices:";
m2 += m1;
m2.print();
cout << "\n";
//Eliminamos las matrices
m1.Delete();
m2.Delete();
system("PAUSE");
}
Espero que os haya servido y os haya gustado.
Nos vemos
miércoles, 24 de agosto de 2011
Math Engine : Capitulo 2. Clase LPVector
Capítulo perteneciente al math engine LordPakus
Hola a todos,
Bienvenidos a un nuevo capitulo del math engine.
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 opera 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
EDIT:
27-08-2011:Se han añadido las funciones siguientes:
- vector de randoms
- distancia entre vectores
- se deja a la espera el cross product (alguíen tiene el código y me lo quiere pasar??)
Hola a todos,
Bienvenidos a un nuevo capitulo del math engine.
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 opera 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
EDIT:
27-08-2011:Se han añadido las funciones siguientes:
- vector de randoms
- distancia entre vectores
- se deja a la espera el cross product (alguíen tiene el código y me lo quiere pasar??)
Etiquetas:
math engine
,
modulo
,
normalización
,
operaciones vector-escalar
,
operaciones vector-vector
,
producto escalar
,
vectores de tamaño variable
lunes, 22 de agosto de 2011
Math Engine : Capitulo 1. Sobrecarga de operadores
Capítulo perteneciente al math engine LordPakus
Hola a todos (disculpad por el parón, pero el niño me está "robando" algo más de tiempo del que me pensaba :D )
Bienvenidos al primer capitulo del Math Engine. En este capitulo no haremos mucho más que iniciar las bases del proyecto.
Conceptos fundamentales:
1. Todo el código se escribirá en un inicio en C/C++
2. Todo el código se intentará encapsular en clases (aunque en prinicipio no habrá gestores como en el game engine, usease el MathEngine será una colección de funcionalidades matematicas no un motor que correrá de fondo gestionandolo todo).
3. Todas las optimizaciones irán con ifdef (así se podrán hacer diferentes compilaciones optimizadas en función de la arquitectura en que se trabaje : tipo de ensamblador, tipo de procesador, etc...). Las optimizaciones mínimas que se tienen en cuenta ahora mismo son paralelización multicore y ensamblador vectorial SSE.
4. El código que gestione el usuario ha de ser mínimo , claro y sencillo.
5. Habrá 3 grandes bloques de trabajo: operaciones entre vectores, operaciones entre matrices y operaciones vector-matriz.
6. Las operaciones se irán implementado a medida que vosotros las vayais pidiendo así que si os interesa algún función en particular no dudeis en pedirla.
Dicha toda esta parrafada, expondremos el capitulo como tal.
Lo primero será crear el proyecto. Deberiais saber hacerlo pero si no teneis mucha memoria :D, podeis mirar como se creó el proyecto en el game engine (http://lordpakus.blogspot.com/2011/05/gameengine-capitulo-1.html).
Una vez tengais el proyecto creado cread los siguientes archivos y copiad el siguiente código. Vereis que no es más un código muy sencillo de operación entre vectores.
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[])
{
LPVector4 v1,v2;
v1.Set(0.0f,1.0f,2.0f,3.0f);
v2.Set(1.1f,1.2f,1.3f,1.4f);
v1 += v2;
cout << "Vector 1: ";
v1.print();
cout << "\n";
cout << "Vector 2: ";
v2.print();
}
LPMath.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
/**************************************************************************************************/
//Lista de todos los includes necesarios para el math engine.
#include "LPVector4.h"
LPVector4.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 __LPVector4__
#define __LPVector4__
class LPVector4
{
public:
void Set(float x, float y , float z , float t); //Funcion para inicializar un vector de 4 elementos
void print(); //Función para imprimir el vector por la consola
void operator +=(const LPVector4 v); //Sobrecarga de operador +=
public:
float xv,yv,zv,tv;
};
#endif
LPVector4.cp
/**************************************************************************************************/
// 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 "LPVector4.h"
#include <iostream> //Usada para imprimir por consola
using namespace std;
void LPVector4::Set(float x, float y , float z , float t) //Funcion para inicializar un vector de 4 elementos
{
xv = x;
yv = y;
zv = z;
tv = t;
}
//Imprimimos el valor del vector
void LPVector4::print()
{
cout << "x: " << xv << " y: " << yv << " z: " << zv << " t: " << tv;
}
//Sobrecarga operador +=
void LPVector4::operator +=(const LPVector4 v)
{
xv += v.xv;
yv += v.yv;
zv += v.zv;
tv += v.tv;
}
Para probar el ejecutable debereis hacerlo desde una consola para que os permita ver el resultado.
Por ahora lo único que os debe interesar es como se ha hecho la sobrecarga del operador += aplicado a los vectores ya que esta sobrecarga es de lo que más se usara en el MathEngine para hacer que el código quede limpio de cara al usuario.
Sin más, aqui os dejo, espero que os lo hayais pasado bien y hayais aprendido
Nos vemos
Hola a todos (disculpad por el parón, pero el niño me está "robando" algo más de tiempo del que me pensaba :D )
Bienvenidos al primer capitulo del Math Engine. En este capitulo no haremos mucho más que iniciar las bases del proyecto.
Conceptos fundamentales:
1. Todo el código se escribirá en un inicio en C/C++
2. Todo el código se intentará encapsular en clases (aunque en prinicipio no habrá gestores como en el game engine, usease el MathEngine será una colección de funcionalidades matematicas no un motor que correrá de fondo gestionandolo todo).
3. Todas las optimizaciones irán con ifdef (así se podrán hacer diferentes compilaciones optimizadas en función de la arquitectura en que se trabaje : tipo de ensamblador, tipo de procesador, etc...). Las optimizaciones mínimas que se tienen en cuenta ahora mismo son paralelización multicore y ensamblador vectorial SSE.
4. El código que gestione el usuario ha de ser mínimo , claro y sencillo.
5. Habrá 3 grandes bloques de trabajo: operaciones entre vectores, operaciones entre matrices y operaciones vector-matriz.
6. Las operaciones se irán implementado a medida que vosotros las vayais pidiendo así que si os interesa algún función en particular no dudeis en pedirla.
Dicha toda esta parrafada, expondremos el capitulo como tal.
Lo primero será crear el proyecto. Deberiais saber hacerlo pero si no teneis mucha memoria :D, podeis mirar como se creó el proyecto en el game engine (http://lordpakus.blogspot.com/2011/05/gameengine-capitulo-1.html).
Una vez tengais el proyecto creado cread los siguientes archivos y copiad el siguiente código. Vereis que no es más un código muy sencillo de operación entre vectores.
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[])
{
LPVector4 v1,v2;
v1.Set(0.0f,1.0f,2.0f,3.0f);
v2.Set(1.1f,1.2f,1.3f,1.4f);
v1 += v2;
cout << "Vector 1: ";
v1.print();
cout << "\n";
cout << "Vector 2: ";
v2.print();
}
LPMath.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
/**************************************************************************************************/
//Lista de todos los includes necesarios para el math engine.
#include "LPVector4.h"
LPVector4.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 __LPVector4__
#define __LPVector4__
class LPVector4
{
public:
void Set(float x, float y , float z , float t); //Funcion para inicializar un vector de 4 elementos
void print(); //Función para imprimir el vector por la consola
void operator +=(const LPVector4 v); //Sobrecarga de operador +=
public:
float xv,yv,zv,tv;
};
#endif
LPVector4.cp
/**************************************************************************************************/
// 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 "LPVector4.h"
#include <iostream> //Usada para imprimir por consola
using namespace std;
void LPVector4::Set(float x, float y , float z , float t) //Funcion para inicializar un vector de 4 elementos
{
xv = x;
yv = y;
zv = z;
tv = t;
}
//Imprimimos el valor del vector
void LPVector4::print()
{
cout << "x: " << xv << " y: " << yv << " z: " << zv << " t: " << tv;
}
//Sobrecarga operador +=
void LPVector4::operator +=(const LPVector4 v)
{
xv += v.xv;
yv += v.yv;
zv += v.zv;
tv += v.tv;
}
Para probar el ejecutable debereis hacerlo desde una consola para que os permita ver el resultado.
Por ahora lo único que os debe interesar es como se ha hecho la sobrecarga del operador += aplicado a los vectores ya que esta sobrecarga es de lo que más se usara en el MathEngine para hacer que el código quede limpio de cara al usuario.
Sin más, aqui os dejo, espero que os lo hayais pasado bien y hayais aprendido
Nos vemos
Etiquetas:
math engine
,
operaciones matriz-matriz
,
operaciones matriz-vector
,
operaciones vector-matriz
,
operaciones vector-vector
,
sobrecarga de operadores
Entradas populares
-
Una pregunta que me hacen en muchas ocasiones es ¿¿qué significa %2?? La respuesta tiene dos acepciones en función de si lo estamos u...
-
<< Ejemplo anterior Artículos Relacionados Ejemplo siguiente >> Hola a todos, ASCII Art es el hecho de hacer di...
-
Hola a todos... En muchas ocasiones un programador ve frustrado un proyecto al faltarle un artista de audio y/o imagen que le complemente ...
-
<< Gurú anterior Gurús de la programación John Carmack Robert C. Martin (Uncle Bob) Kent Beck Martín Fowler Ward C...
-
<< Gurú anterior Gurús de la programación John Carmack Robert C. Martin (Uncle Bob) Kent Beck Martín Fowler Ward C...
-
<< Gurú anterior Gurús de la programación John Carmack Robert C. Martin (Uncle Bob) Kent Beck Martín Fowler Ward C...
-
<< Gurú anterior Gurús de la programación John Carmack Robert C. Martin (Uncle Bob) Kent Beck Martín Fowler Ward C...
-
<< Gurú anterior Gurús de la programación John Carmack Robert C. Martin (Uncle Bob) Kent Beck Martín Fowler Ward C...
-
<< Gurú anterior Gurús de la programación John Carmack Robert C. Martin (Uncle Bob) Kent Beck Martín Fowler Ward C...
-
Articulo perteneciente a : Referencias de programación Hola a todos Os pongo una aportación que a más de uno le irá bien, un resumen de ...