Como remplazar caracteres en una string()

Diciembre 17, 2008

Hola

Siguiendo con las funciones interesantes y útiles de las STL y sus objetos. Imaginaros que necesitáis substituir unos caracteres por otros en una cadena.

Pues bien, utilizando una string como contenedor de la cadena es relativamente sencillo hacerlo.

std::replace(str.begin(),str.end(), '*','-');

Lo que hacemos es utilizar una función estándar de las STD para indicar que queremos substituir los asteriscos (*) de la cadena por guiones (-). Evidentemente necesitamos indicar de donde a donde irá ese cambio, es decir, unos límites. En el ejemplo que he puesto, y normalmente el más usado en la mayoría de los casos, es todo el tamaño de la cadena, desde su inicio hasta su fin.

Un saludo


Sistema de encriptación AES

Diciembre 15, 2008

Hola

Hoy os traigo algo que aunque no sea directamente relacionado con el mundo 3D, sí que lo está con el mundo de la programación y nos puede ser de utilidad.

Estoy hablando de del sistema de encriptación de datos AES en formato C++, listo para ser agregado a nuestros proyectos, sin ningún tipo de licencia y totalmente libre.

En la siguiente web podéis encontrar los dos ficheros, el *.h y el *.cpp para poder usar este sistema en vuestro proyecto para lo que queráis.

Link: AQUI

Un saludo


Parser XML para C++

Noviembre 6, 2008

Hola

Hoy os traigo uno de los descubrimientos alrededor de los ficheros XML más grandes que he hecho yo durante los últimos años.

El descubrimiento es un parser de XML para C++ que ocupa solo 2 ficheros, un *.h y un *.cpp. Puede leer cualquier tipo de fichero XML y va de fabula para todos aquellos proyectos que necesiten leer entradas o escribir salidas en formato XML.

Link de la Web

Yo concretamente lo llevo usando desde hace más de un año y estoy muy feliz con él. Es pequeño, fácil de usar y fácil de integrar.

Nota: Os recomiendo que incluíais primero la librería “tchar.h” antes que la “strsafe.h” porque si no os lo pedirá el propio código. Es una necesidad del código.

Un saludo


String to Tokens

Noviembre 3, 2008

Hola

Hoy os traigo un trozo de código que he necesitado este fin de semana y que es extremadamente útil para todas aquellas personas que estén parseando o separando strings en sub-strings.

La función en cuestión pasa de una cadena de caracteres (string) con unas palabras en su interior y unos separadores, a un vector de sub-strings en la que cada sub-string es una de las palabras de la string anterior.

Ejemplo:

String entrante: “Hola esto es una prueba 1-2-3-4”

Separadores deseados: “ “ y “-“ (espacio y guión)

Resultado:

“Hola”
“esto”
“es”
“una”
“prueba”
“1”
“2”
“3”
“4”

Aquí tenéis el código, tened en cuenta de que el código funciona con wstrings, esas strings con caracteres mas anchos de lo normal, para que funcione con strings normales debéis cambiar cada ‘wstring’ que aparece en el código por ‘string’ y ya está.

void WstringTokensToVector(const wstring& wstr,const wstring& delimiters, vector<wstring> *outVector, unsigned int inCount)
{
	outVector->clear();
	outVector->reserve(inCount);

	// skip delimiters at beginning.
    unsigned int lastPos = (unsigned int)wstr.find_first_not_of(delimiters, 0);

	// find first "non-delimiter".
    	unsigned int pos = (unsigned int)wstr.find_first_of(delimiters, lastPos);

    	while (wstring::npos != pos || wstring::npos != lastPos)
    	{
        	// found a token, add it to the vector.
        	outVector->push_back(wstr.substr(lastPos, pos - lastPos));

        	// skip delimiters.  Note the "not_of"
        	lastPos = (unsigned int)wstr.find_first_not_of(delimiters, pos);

        	// find next "non-delimiter"
        	pos = (unsigned int)wstr.find_first_of(delimiters, lastPos);
    	}
}

P.D: La variable iCount sirve solo para hacer un reserve, si quereis no estais obligados a ponerla

Un saludo


Plano 3D a partir de un vector y un punto

Octubre 28, 2008

Hola

Continuando con la información de los planos, hoy os traigo la manera de crear planos mediante un punto y un vector.

Para hacer un plano mediante un punto (x1,y1,z1) y un vector (x2,y2,z2), es necesario aplicar la fórmula del plano, y darle valor a las 4 letras (A,B,C,D) de la ecuación Ax+By+Cz+D=0.

Hemos de tener en cuenta que el vector que elijamos, será considerado como el vector director del plano, es decir, un vector perpendicular al plano (90º grados).

Por lo tanto tenemos que:

A = x2;
B = y2;
C = z2;

Y para obtener D, aislamos la D de la ecuación donde tendremos:

D = -((x2 * x1) + (y2 * y1) + (z2 * z1));

Fijémonos que el punto es multiplicado por las constantes del plano (A,B,C) que ya han sido substituidas por el vector director del plano.

Una vez tenemos A,B,C,D ya podemos, por ejemplo, comprobar con el método de ayer si un punto está por encima o por debajo del propio plano.

Un saludo


Punto 3D por encima o por debajo de un plano

Octubre 27, 2008

Hola

Hoy os traigo algo que parece y es muy sencillo. ¿Cómo podemos saber si un punto (x,y,z) está por encima o por debajo de un Plano 3D?

Muy sencillo, todo plano nos viene dado por la ecuación Ax+By+Cz+D = 0, esto quiere decir que en nuestro código tendremos los valores (A,B,C,D), los cuales nos definirán el plano en cuestión.

Solo necesitamos substituir las coordenadas (x,y,z) del punto en la ecuación del plano y comprobar el signo del resultado. Si el resultado da un número positivo, entonces el punto está por encima del plano. Si el resultado es un número negativo, el punto está por debajo del plano.

Un saludo


Distancia de un punto a un vector

Octubre 23, 2008

Hola

¿Cómo podemos calcular la distancia mínima entre un punto y un vector? Pues de una forma relativamente sencilla utilizando el producto escalar definido para los vectores.

¿Qué es el producto escalar? Una operación que nos da como resultado un número, este número nos indica, una vez proyectado un vector encima del otro, cuantos vectores mide esa proyección.

Por ejemplo, imaginemos que el resultado es 1.5, entonces eso quiere decir que la proyección del vector mide 1.5 veces el vector al cual se ha proyectado el anterior vector.

Como una imagen vale más que mil palabras, vamos a observarla y a explicarlo un poco.

Tenemos inicialmente un vector (x1 -> x2), y el punto x0 con los cuales queremos obtener la distancia MINIMA entre ese vector y ese punto.

La estrategia es usar el producto escalar para proyectar un vector encima de otro, por lo tanto, tenemos el vector original (x1 -> x2) y ahora creamos un nuevo que será el que proyectaremos.

Con lo cual, tenemos los vectores (x1 -> x2) y (x1 -> x0). Si hacemos el producto escalar entre ellos, obtendremos el número de veces que mide la sección entre x1 y el punto ‘p’. Es decir, la proyección de la línea azul (vector x1 -> x0) encima del vector original.

Una vez tenemos ese factor de multiplicación, solo tenemos que multiplicar el vector original por ese factor y sabiendo la primera componente que es x1, sabremos automáticamente cual es el punto (x,y,z) que hay en ‘p’.

Una vez sabido ‘p’, solo nos queda hacer la distancia entre ‘p’ y x0. Para eso creamos el vector (p -> x0) y calculamos su distancia.

El codigo siguiente calcula el punto ‘p’ y luego en otra funcion calcula la distancia.

vector3 ClosestPointOnSegment(vector3 p, vector3 p1, vector3 p2)
{
    vector3 diff = p-p1;
    vector3 dir = p2-p1;
    float t = dot(diff,dir)/dot(dir,dir);
    if (t <= 0.0f)
    {
        return p1;
    }
    else if (t >= 1.0f)
    {
        return p2;
    }
    else
    {
        return p1 + t * dir;
    }
}
//The distance from the point to the segment is then:
float distance = length(p - ClosestPointOnSegment(p,p1,p2));

NOTA: Existen dos variantes, la que calcula esta distancia del punto x0 a la línea definida por el vector (x1 -> x2) y la que calcula la distancia del punto x0 al vector LIMITADO (x1 -> x2). Si queréis la primera, necesitáis eliminar las dos primeras condiciones del anterior código, sino, dejad el código tal cual.

Un saludo


Pregunta de examen

Octubre 20, 2008

Holas

Esta pregunta me la encontre en un examen que se me realizó en una entrevista de trabajo. Que pensais vosotros ?

Suerte :)

RESPUESTA: La respuesta correcta es la 2, int B = A & 0×000F, pues esta operacion nos da lo que ’sobra’ de la division por 16, que coincide con el valor hexadecimal 0×000F.

Un saludo


strings y substr()

Octubre 15, 2008

Hola

Más conocimiento interesante de C++ y las strings de las STL. Hace poco postee un escrito comentando una manera de cómo cambiar un trozo de una string.

Ahora vengo con otra manera que, aunque en este caso valdrían las dos, puede no ser válida en todos los casos y asi tenemos más formas de solucionar los problemas.

Lo que vamos a hacer es invocar una función de las strings para poder conseguir una sub-string de esa string para poder operar con ella.

#include <string>

{
   string sFileName("Fichero.txt");

   unsigned int iPointPos = (unsigned int)sFileName.find_first_of(L".");
   sFileName = sFileName.substr(0,iPointPos)  + ".xml";
}

Como podemos ver, buscamos el punto, y una vez tenemos la posición pedimos que nos devuelvan una sub-string desde el primer carácter hasta el carácter del punto.

Por lo demás ya podemos operar como siempre.

Un saludo


string, find_first_of() y remove()

Octubre 13, 2008

Si continuamos con el conocimiento de C++ y el tratamiento de sus strings podremos ver cosas relativamente útiles que en mi caso, he utilizado recientemente.

Imaginemos que tenemos una cadena con un nombre de fichero, y como no, queremos cambiar la extensión de ese fichero. Concretamente “Fichero.txt” a “Fichero.xml”

#include <string>

{
   string sFileName("Fichero.txt");

   unsigned int iPointPos = (unsigned int)sFileName.find_first_of(L".");
   unsigned int iFinalPos = (unsigned int)sFileName.size();
   sFileName.erase(iPointPos,iFinalPos - iPointPos);
   sFileName = sFileName + ".xml";
}

Como podemos observar en el código anterior, es una forma rápida y sencilla siempre y cuando partamos de la base de que la string solo contendrá un punto.

Los pasos son, buscamos la posición del primer punto, obtenemos la distancia total de la cadena, borramos desde el punto hasta el final y concatenamos la extensión que queramos.

NOTA: Otra opción es ir a buscar no el primer punto sino el último.

Un saludo