Recorrido sobre un árbol de Jerarquías en SQL Server
Necesitarás la estructura de la tabla y unos cuantos datos de prueba que puedes copiar de aquí, lo he tomado de la página Recursive Queries Using Common Table Expressions del msdn.
CREATE TABLE dbo.MyEmployees
(
EmployeeID smallint NOT NULL,
FirstName nvarchar(30) NOT NULL,
LastName nvarchar(40) NOT NULL,
Title nvarchar(50) NOT NULL,
DeptID smallint NOT NULL,
ManagerID int NULL,
CONSTRAINT PK_EmployeeID PRIMARY KEY CLUSTERED (EmployeeID ASC)
);
-- Populate the table with values.
INSERT INTO dbo.MyEmployees VALUES
(1, N'Ken', N'Sanchez', N'Chief Executive Officer',16,NULL)
,(273, N'Brian', N'Welcker', N'Vice President of Sales',3,1)
,(274, N'Stephen', N'Jiang', N'North American Sales Manager',3,273)
,(275, N'Michael', N'Blythe', N'Sales Representative',3,274)
,(276, N'Linda', N'Mitchell', N'Sales Representative',3,274)
,(285, N'Syed', N'Abbas', N'Pacific Sales Manager',3,273)
,(286, N'Lynn', N'Tsoflias', N'Sales Representative',3,285)
,(16, N'David',N'Bradley', N'Marketing Manager', 4, 273)
,(23, N'Mary', N'Gibson', N'Marketing Specialist', 4, 16);
Tenemos un árbol de jerarquías como este:
-- / | \
--16 274 285
--/ / \ \
--23 275 276 286
¿Como puedo conocer los nodos ancestros del nodo 286?
Este query soluciona el problema, empleando un CTE (Common Table Expression) que entre cosas permite ser autoreferenciado.
AS
(
-- Anchor member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, 0 AS Level
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.EmployeeID AND edh.EndDate IS NULL
WHERE e.EmployeeID IN (1,274,276,275) --COMO PARAMETRO LAS HOJAS
UNION ALL
-- Recursive member definition
SELECT e.ManagerID, e.EmployeeID, e.Title, Level + 1
FROM dbo.MyEmployees AS e
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.EmployeeID = edh.EmployeeID AND edh.EndDate IS NULL
INNER JOIN DirectReports AS d
ON e.EmployeeID = d.ManagerID
)
SELECT * FROM MyEmployees
-- Statement that executes the CTE
SELECT DISTINCT ManagerID, EmployeeID--, Title, Level
FROM DirectReports
Cuando el número de nodos se encuentra en el orden de los miles, el tiempo de ejecución toma importancia y es mejor tener una versión iterativa de la solución.
CREATE TABLE #Tree
(
cid INT NOT NULL,
pid INT NULL,
lvl INT NOT NULL,
);
declare @lvl AS int
SET @lvl = 0
--Inserta al conjunto los nodos raíz
INSERT INTO #Tree(lvl,cid, pid)
SELECT @lvl,EmployeeID, ManagerID
FROM dbo.MyEmployees
WHERE EmployeeID IN (1,274,276,275)
-- select * from #Tree
WHILE @@rowcount > 0
BEGIN
SET @lvl = @lvl + 1;
INSERT INTO #Tree(lvl,cid, pid)
SELECT @lvl, C.EmployeeID, C.ManagerID
FROM #Tree AS P
JOIN dbo.MyEmployees AS C
ON P.lvl = @lvl - 1 AND
P.pid = C.EmployeeID;
END
SELECT DISTINCT cid,pid FROM #Tree
Increible tetris en 19 líneas escrito en c

Código ganador del “The International Obfuscated C Code Contest“ del 2007 hecho en México.
¡Completamente inspirador!
=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1,
12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12,
1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12,
12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i]
){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf(
"\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+
n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char*
*V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i<
25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v,
0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+
12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){
for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c
=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G
(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock(
8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=
0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen(
"stty -cbreak echo stop \023;sort -mnr -o HI - HI;cat HI","w");fprintf(d,
"%4d from level %1d by %s\n",w,l,getlogin());pclose(d);}
Para verlo en acción abran una terminal, compilen y ejecuten:
$ gcc tetris.c -o tetris
$ ./tetris
Concurso de Programación ANPA10
El próximo concurso de la ANPA será el 24 de Abril del presente año en León, Guanajuato; no es necesario pertenecer a alguna institución para poder participar y para que se animen a participar, este es uno de los problemas del ANPA07.
Problema: Cajas (ANPA 07 Semifinal)
Autor: Fory
Historia
El encargado de “Empresa productora de cartón” decidió lanzar una línea nueva de cajas. La línea consiste en una colección de cajas cúbicas de diferentes tamaños. Como promoción de lanzamiento se hicieron paquetes de cajas de tal forma que al abrir una puedas encontrar otra y dentro de esta una más y así sucesivamente hasta abrir la caja más pequeña incluida en el paquete. De improviso llega un cliente a la fábrica pidiendo un paquete de lanzamiento; desafortunadamente todos los paquetes ya fueron enviados a las tiendas. Dado que tú eres el responsable de armarlos decides formar uno con el mayor número posible de cajas existentes en la fábrica.
ProblemaHacer un programa que lea el tamaño de cada una de las cajas que hay en la fábrica y escriba el mayor número de cajas que puede tener el paquete. Dentro de una caja de tamaño T puedes meter otra de tamaño t sólo sí t < T.
Entrada
La primer línea de la entrada contendrá un sólo número entero n (1 ≤ n ≤ 100). Dicho número representa el número de casos de prueba para este problema. Cada una de las siguientes n líneas describirá un caso de prueba. En cada caso debes leer primero un entero k (1 ≤ k ≤ 1000) que indica cuantas cajas hay en la fábrica y después leer el tamaño de cada una de las cajas. El tamaño de cada caja será un entero entre 1 y 1000.
Ejemplo:
4
11 1 2 3 4 5 6 7 8 9 10 11
1 10
4 2 2 2 2
5 1 2 2 3 10Salida
Para cada caso de prueba debes escribir una línea de texto con el mensaje “El paquete mayor tiene N cajas.”, siendo N el número de cajas en el paquete más grande. Ejemplo (estas salidas corresponden al ejemplo que se da en Entrada):
El paquete mayor tiene 11 cajas.
El paquete mayor tiene 1 cajas.
El paquete mayor tiene 1 cajas.
El paquete mayor tiene 4 cajas.Nombre del programa
cajas.cpp, cajas.java, cajas.cs, cajas.vb
Como pueden ver, no es nada del otro mundo y la solución se puede escribir en pocas lineas en c++:
#include <cstdio>
#include <set>
using namespace std;
int main(){
int casos, ncajas, tamCaja;
scanf("%d",&casos);
while(casos--){
set<int>cajas_no_repetidas;
scanf("%d",&ncajas);
for(int i=0; i<ncajas;i++){
scanf("%d",&tamCaja);
cajas_no_repetidas.insert(tamCaja);
}
printf("El paquete mayor tiene %d cajas.\n",cajas_no_repetidas.size());
}
}
Les dejo algunos de los problemas aquí para que se terminen de animar.
¿Cómo pasar parámetros por default en C#?
¿Cuántas veces nos encontramos con funciones que por algún ajuste o cambio funcionarían mejor si contarán con otro parámetro más? Esto es muy común cuando tenemos proyectos “grandes” o de tiempo atrás y estamos tratando de realizar una modificación. El problema toma especial importancia si el código que deseamos modificar no fue escrito por nosotros o si no conocemos su funcionamiento del todo.
Un enfoque podría ser sobrecargar la función agregando el segundo parámetro, pero muchos de nosotros (desarrolladores) no nos agrada mucho la idea de repetir código. La solución idonea para mí es pasar el segundo argumento que necesitamos en la misma función y establecer un valor por default que no afecte el comportamiento actual de dicha función.
Es ahí donde entran en juego el uso de parámetros por default, en c++ la sintaxis nos ayuda y la solución se vuelve simple:
using namespace std;
int potencia(int a, int b=2)
{
int factor=1;
for(int i=0; i<b; i++)
factor*=a;
return factor;
}
int main()
{
cout << potencia(2,3) << endl;
cout << potencia(2) << endl;
}
¿Qué pasa si deseamos hacerlo en C#?
Resulta que el lenguaje no soporta esta sintaxis (C# 4.0 sí lo hace), por lo que necesitamos buscar otra manera de hacerlo. La manera sencilla es definiendo el prototipo de la función con una lista de argumentos de longitud variable.
¿cómo hacemos esto?
Podremos “llamar” a nuestra función potencia con uno, dos o cualquier cantidad de parámetros que queramos de tipo entero separados por coma. Al reescribir nuestro programa de ejemplo en C#, nos queda de la siguiente manera:
{
int valor = args[0];
int potencia = 2;
if(args.Length > 0)
potencia = args[1]
int factor=1;
for(int i=0; i<potencia; i++)
factor*=valor;
return factor;
}
Python: Hallar el punto de intersección entre dos segmentos
Este segmento de código devuelve el punto de intersección entre dos rectas, no se consideran el caso de que no exista o exista más de uno (lineas paralelas). Depende del valor de la variable det, si es igual a cero, es necesario verificar que las lineas sean paralelas, si no lo son, entonces nunca se tocan.
#interseccion EN UN UNICO PUNTO entre segmentos
class punto:
def __init__(self,x,y):
self.x = x
self.y = y
def __str__(self):
return "("+str(self.x)+","+str(self.y)+")"
class linea:
def __init__(self, p0, p1):
self.p0 = p0
self.p1 = p1
self.A = p1.x - p0.x
self.B = p1.y - p0.y
self.C = p1.x*p0.y - p0.x*p1.y
def intersecta(self, otro):
det = self.A*otro.B - otro.A*self.B
x = otro.A*self.C-self.A*otro.C
y = otro.B*self.C-self.B*otro.C
return punto(x/det,y/det)
def __str__(self):
return str(self.p0) + "," + str(self.p1)
if __name__=="__main__":
l1 =linea(punto(0,0),punto(10,10))
l2 =linea(punto(10,0),punto(0,10))
print l1,l2
print l1.intersecta(l2)
Python: calcular los n primeros números primos
No conozco otro lenguaje más flexible y fácil que python. Este código te permite obtener los n primos menores que la variable MAX.
#calcula los primos menores que 100
MAX = 100
primos = [2]
for k in range(3, MAX):
for i in range(len(primos)):
if k%primos[i]==0: break
if i==len(primos)-1: #solo si no es multimplo de los actuales primos
primos.append(k)
print primos
Python: Recorridos en un árbol
Una manera muy fácil de representar un árbol binario es utilizando un vector. A partir de esta representación es fácil ejemplificar los recorridos en un árbol: pre-orden, in-orden y post-orden.
arbol = [5,3,7,2,4,6,9]
#como se representa un arbol binario casi-completo con una lista?
# 5 Nos enfocamos en el nodo 7, su indice en la lista es 2,
# / \ el hijo izquierdo esta en la posicion 2*indice + 1
# 3 7 y el hijo derecho esta en la posicion 2*indice + 2
# / \ / \
#2 4 6 9
def postorden(nodo): #id*
if nodo >= len(arbol): #nodo sin hijo
return
else:
postorden(2*nodo+1) #subarbol izquierdo
postorden(2*nodo+2) #subarbol derecho
print arbol[nodo],
def preorden(nodo): #*id
if nodo >= len(arbol): #nodo sin hijo
return
else:
print arbol[nodo],
preorden(2*nodo+1) #subarbol izquierdo
preorden(2*nodo+2) #subarbol derecho
def inorden(nodo): #i*d
if nodo >= len(arbol): #nodo sin hijo
return
else:
inorden(2*nodo+1) #subarbol izquierdo
print arbol[nodo],
inorden(2*nodo+2) #subarbol derecho
if __name__=="__main__":
print "pre-orden:"
preorden(0)
print "\nin-orden:"
inorden(0)
print "\npost-orden:"
postorden(0)
Salida desde la terminal
5 3 2 4 7 6 9
in-orden:
2 3 4 5 6 7 9
post-orden:
2 4 3 6 9 7 5
Animación orgánica con Context Free
Me quedé con la curiosidad de cómo generar una animación del programa en Context Free sin la interfaz de usuario que existe en otras plataformas como güindous y mac.
Esta es la solución que encontre:
- Suponiendo que el código fuente document.cfdg se encuentra en el directorio_actual, y que tenemos la siguiente estructura de directorios:
directorio_actual
|
+----animation
|
+-----frames - Instalar las herramientas de consola ffmpeg y convert.
- Generar los cuadros de nuestra animación, en mi caso 50, con la siguiente línea:
cfdg -w 500 -h 500 document.cfdg ./animation/art.png -a 500
- Como el cfdg solo genera imágenes png y ffmpeg (que convierte una secuencia de imágenes en video) sólo acepta imágenes jpg, realizamos la conversión de las imágenes con la siguiente línea:
cd animation
convert * ./frames/anima.jpg - Generamos el video con el comando ffmpeg:
cd frames
ffmpeg -f image2 -i anima-%d.jpg video.mpeg
sudo apt-get install ffmpeg
¡Listo!, ya tenemos una animación de nuestro programa.
Cómo escribir programas para tu graficadora TI
En el sitio oficial de TIGCC puedes encontrar todo lo que necesitas para escribir un programa en lenguaje C y compilarlo para generar un ejecutable en ensamblador. Los modelos soportados son TI-89, TI-92 Plus y Voyage200.
¿Qué es lo que hay que hacer?
- Bajar el compilador TIGCC v0.96 Beta 8 que incluye un IDE.
- Bajar el emulador TIEmu que nos permitirá probar nuestros programas antes de descargalo.
- Instalar TI Connect, el software de enlance entre la PC y la graficadora TI, de la página de Texas Instruments.
- Descargar la imagen del ROM (Voyage200_OS209.img) del modelo de tu graficadora o simplemente crear una copia de tu propio ROM.
- Antes de lanzar el emulador, la ventana “Set ROM version” aparecerá y debes añadir la imagen del ROM para que luzca como en la siguiente imagen.

En la página oficial podrás encontrar manuales, tutoriales, ejemplos y demás…
Nota: ¡un conocimiento básico del lenguage C sería de gran ayuda!
Les dejo esta implementación del algoritmo de Floyd para hallar el camino mínimo entre todos los pares de vértices de un grafo ponderado.
#define USE_TI92PLUS // Compile for TI-92 Plus
#define USE_V200 // Compile for V200
#define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization
#define MIN_AMS 100 // Compile for AMS 1.00 or higher
#define SAVE_SCREEN // Save/Restore LCD Contents
#include <tigcclib.h> // Include All Header Files
#define INF 1000
int N;
void print(int (*A)[N],int k){
clrscr();
printf("It: %d\n",k+1);
int i,j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
if (i==j)
printf(" -");
else if( A[i][j] > 500)
printf(" i");
else
printf ("%3d", A[i][j]); // print out the matrix
printf ("\n");
}
}
void _main (void)
{
clrscr ();
printf ("# de nodos: ");
scanf("%d",&N);
printf("\n");
int (*A)[N] = NULL;
int (*S)[N] = NULL;
int i,j,k;
A = calloc (N, sizeof (*A));
S = calloc (N, sizeof (*S));
//inicializacion
for (i = 0; i < N; i++){
for (j = 0; j < N; j++){
S[i][j] = j;
if (i==j)
A[i][j] = INF;
else{
printf("e[%d][%d]?",i,j);
scanf("%d",&A[i][j]);
printf("\n");
if (A[i][j] < 0)
A[i][j] = INF;
}
}
}
for (k=0; k<N; k++){
for(i=0; i<N; i++){
for(j=0; j<N; j++){
if(A[i][k] + A[k][j] < A[i][j]){
A[i][j]= A[i][k] + A[k][j];
S[i][j]= k;
}
}
}
print(A,k);
ngetchx();
}
free (A);
ngetchx();
clrscr();
print(S,-1);
free(S);
ngetchx();
}
Este es el grafo que representa un instancia del problema

D1 representa la matriz de adyacencia del grafo, dónde el símbolo de infinito y el guión indican que no existe una conexión entre el par de nodos Dij. La matriz D4 representa los pesos/distancias mínimas entre cualquier par de nodos.

Así es como se introduce la matriz de adyacencia, los infinitos se representan con -1 y la diagonal simplemente no se solicita.

El programa muestra cada una de las iteraciones del algoritmo, esta es la última de ellas.

Los ejecutables en ensamblador, que se generan en la misma carpeta del proyecto, son estos TI-89, TI-92 Plus y Voyage200.
Nota: Para realizar la sincronización y el lanzamiento del programa deberás consultar el manual de tu graficadora.
OpenGL en Ubuntu
Para compilar programas que utilicen openGL, necesité instalar primero
El build-essential instalará las cosas que necesitas para compilar c++ y usar los makefiles. Por otro lado freeglut3-dev te proporcionará las bibliotecas que necesitas para crear programas openGL.
Inspiración

Este ejemplo crea un humanoide utilizando paralelepipedos que puedes girar y escalar con las letras ‘w’, ‘a’, ’s’ y ‘z’, la combinación de cualquiera de estas letras con la tecla
//#include <Windows.h>
#include <GL/glut.h>
#include <cstdlib>
//sample input:
// {1, 1, -1},{1, 0, -1},{1, 0, 0},{1, 1, 0}
// {0, 1, -1},{0, 0, -1},{0, 0, 0},{1, 0, 0}
// We are using the Standard Template Library namespace
using namespace std;
#define VERTICES 8
#define FACES 6
float angleX = 0.0f;
float angleY = 0.0f;
float angleZ = 0.0f;
float transZ = -10.0f;
float g_fCubeCoords[8][3];
void initGraphics(int argc, char* argv[]);
void startRendering();
void reshape(int w, int h);
void keyboard(unsigned char key, int x, int y);
void display();
void dibujaCubof(float width,float height, float depth){
//calcula 8 vertices
double mid_w= width/2.0, mid_h=height/2.0, mid_d=depth/2.0;
g_fCubeCoords[0][0]= mid_w;g_fCubeCoords[0][1]= mid_h;g_fCubeCoords[0][2]= mid_d;
g_fCubeCoords[1][0]= mid_w;g_fCubeCoords[1][1]= mid_h;g_fCubeCoords[1][2]=-mid_d;
g_fCubeCoords[2][0]= mid_w;g_fCubeCoords[2][1]=-mid_h;g_fCubeCoords[2][2]=-mid_d;
g_fCubeCoords[3][0]= mid_w;g_fCubeCoords[3][1]=-mid_h;g_fCubeCoords[3][2]= mid_d;
g_fCubeCoords[4][0]= -mid_w;g_fCubeCoords[4][1]= mid_h;g_fCubeCoords[4][2]= mid_d;
g_fCubeCoords[5][0]= -mid_w;g_fCubeCoords[5][1]= mid_h;g_fCubeCoords[5][2]=-mid_d;
g_fCubeCoords[6][0]= -mid_w;g_fCubeCoords[6][1]=-mid_h;g_fCubeCoords[6][2]=-mid_d;
g_fCubeCoords[7][0]= -mid_w;g_fCubeCoords[7][1]=-mid_h;g_fCubeCoords[7][2]= mid_d;
glBegin(GL_QUADS);
/// Front face
glVertex3fv(g_fCubeCoords[0]); glVertex3fv(g_fCubeCoords[1]);
glVertex3fv(g_fCubeCoords[2]); glVertex3fv(g_fCubeCoords[3]);
/// Back face
glVertex3fv(g_fCubeCoords[4]); glVertex3fv(g_fCubeCoords[5]);
glVertex3fv(g_fCubeCoords[6]); glVertex3fv(g_fCubeCoords[7]);
/// Left face
glVertex3fv(g_fCubeCoords[0]); glVertex3fv(g_fCubeCoords[3]);
glVertex3fv(g_fCubeCoords[7]); glVertex3fv(g_fCubeCoords[4]);
/// Right face
glVertex3fv(g_fCubeCoords[1]); glVertex3fv(g_fCubeCoords[5]);
glVertex3fv(g_fCubeCoords[6]); glVertex3fv(g_fCubeCoords[2]);
/// Top face
glVertex3fv(g_fCubeCoords[0]); glVertex3fv(g_fCubeCoords[4]);
glVertex3fv(g_fCubeCoords[5]); glVertex3fv(g_fCubeCoords[1]);
/// Bottom face
glVertex3fv(g_fCubeCoords[3]); glVertex3fv(g_fCubeCoords[2]);
glVertex3fv(g_fCubeCoords[6]); glVertex3fv(g_fCubeCoords[7]);
glEnd();
}
int main(int argc, char* argv[])
{
initGraphics(argc, argv);
startRendering();
return 0;
}
void initGraphics(int argc, char* argv[])
{
glutInit( &argc, argv ); // Start GLUT with command line arguments
glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB ); // Set up the display mode
glutInitWindowSize( 500, 500 ); // Set window init size
glutInitWindowPosition( 0, 0 ); // Set window init position
glutCreateWindow( "Humanoide con cubos" ); // Create the window with the string as its name
// GLUT rendering functions
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutDisplayFunc( display ); // Set up pointer functions
}
void startRendering()
{
glEnable(GL_DEPTH_TEST);
// Start rendering
glutMainLoop();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(100.0f, (GLfloat)w/(GLfloat)h, 0.1, 100);
}
void display()
{
static int i = 0;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(0.0f, 0.0f, transZ);
glRotatef(angleX, 1.0f, 0.0f, 0.0f);
glRotatef(angleY, 0.0f, 1.0f, 0.0f);
glRotatef(angleZ, 0.0f, 0.0f, 1.0f);
//torso
glColor3f(.3,.9,0);
dibujaCubof(3,4,1);
//pierna izquierda
glColor3f(0.0f,0.5f,0.1f);
glTranslatef (1,-3.5,0);
dibujaCubof(1,3,1);
//pierna derecha
glTranslatef(-2,0,0);
dibujaCubof(1,3,1);
//espinillas
glTranslatef(0,-3,0);
dibujaCubof(1.5,3.5,1.5);
glTranslatef(2,0,0);
dibujaCubof(1.5,3.5,1.5);
//PIES
glColor3f(1,1,1);
glTranslatef(.25,-2,.25);
dibujaCubof(2,.5,2);
glTranslatef(-2.5,0,0);
dibujaCubof(2,.5,2);
//cabeza
glTranslatef(1.25,11.5,0);
dibujaCubof(2,2,2);
//brazos
glColor3f(0.0f,0.5f,0.1f);
glTranslatef(2.75,-2,-.25);
dibujaCubof(2.5,1,1);
glTranslatef(-5.5,0,0);
dibujaCubof(2.5,1,1);
//codos
glColor3f(1,1,1);
glTranslatef(-1.75,0,0);
dibujaCubof(1,1.4,1.4);
glTranslatef(9,0,0);
dibujaCubof(1,1.4,1.4);
//manos
glColor3f(0.0f,0.5f,0.1f);
glTranslatef(1,0,0);
dibujaCubof(1,1,1);
glTranslatef(-11,0,0);
dibujaCubof(1,1,1);
glPopMatrix();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case 27:
exit(0);
case 'w':
angleX += 1.0f;
break;
case 'W':
angleX -= 1.0f;
break;
case 's':
angleZ += 1.0f;
break;
case 'S':
angleZ -= 1.0f;
break;
case 'a':
angleY += 1.0f;
break;
case 'A':
angleY -= 1.0f;
break;
case 'z':
transZ += 0.1f;
break;
case 'Z':
transZ -= 0.1f;
break;
default:
break;
}
glutPostRedisplay();
}
Para compilar y ejecutar el ejemplo ‘humanoide.cpp’ utilizamos este par de línea.
./humanoide

