El artículo original lo podeís encontrar aquí
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
Blog spin-off de http://lordpakus.blogspot.com/ donde nos centraremos en la creación y uso de un math engine (motor de cálculo) basado en la paralelización multicore mediante threads y las instrucciones de ensamblador SSE. Los primeros articulos al menos serán reposteos del blog original, espero que os guste.
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/
Mostrando entradas con la etiqueta operaciones matriz-matriz. Mostrar todas las entradas
Mostrando entradas con la etiqueta operaciones matriz-matriz. Mostrar todas las entradas
jueves, 8 de septiembre de 2011
Math Engine : Capitulo 1. Sobrecarga de operadores
El artículo original lo podeís encontrar aqui
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
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
Suscribirse a:
Entradas (Atom)
