Transformacion Transformacion::scale(float sx,float sy,float sz, Punto centro)
//Acumula el escalado sobre un punto generico
{
	Matriz s;
	translation(centro);
	s.setelem(0,0,sx); s.setelem(1,1,sy); s.setelem(2,2,sz);
	append(s);
	return translation(centro.negated());
}
Transformacion Transformacion::rotZ(float ang)
//en Z
{
	Matriz g;
	g.setelem(0,0,(float)cos(DEG2RAD(ang)));
    g.setelem(0,1,(float)-sin(DEG2RAD(ang)));
	g.setelem(1,0,-g.elem(0,1));
	g.setelem(1,1,g.elem(0,0));

	return append(g);
}
Transformacion Transformacion::rotY(float ang)
//en Y
{
	Matriz g;
	g.setelem(0,0,(float)cos(DEG2RAD(ang)));
    g.setelem(0,2,(float)sin(DEG2RAD(ang)));
	g.setelem(2,0,-g.elem(0,2));
	g.setelem(2,2,g.elem(0,0));

	return append(g);
}
Transformacion Transformacion::rotX(float ang)
//en X
{
	Matriz g;
	g.setelem(1,1,(float)cos(DEG2RAD(ang)));
    g.setelem(1,2,(float)-sin(DEG2RAD(ang)));
	g.setelem(2,1,-g.elem(1,2));
	g.setelem(2,2,g.elem(1,1));

	return append(g);
}
Matriz Bloque::layer(int k)const
//Devuelve la capa k como una matriz
{
	Matriz m;
	for(int i=0; i<4; i++)
		for(int j=0; j<4; j++) m.setelem(i,j,e[i][j][k]);
	return m;
}
Transformacion Transformacion::translation(Real4 d)
//Acumula la traslacion propuesta
{
	Matriz t;
	int i;
	for (i=0;i<3;i++) t.setelem(i,3,d.elem(i));
	return append(t);
}
Matriz Matriz::operator *(float k)const
//Producto por un escalar (M*k). Devuelve una nueva matriz
{
	int i,j;
	Matriz pr;

	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			pr.setelem(i,j,e[i][j]*k);

	return pr;
}
Matriz Matriz::operator !()const
//Devuelve la traspuesta en una nueva matriz. 
//Usar parentesis para asegurar precedencia (!M)
{
	int i,j;
	Matriz t;

	for(i=0;i<4;i++)
		for(j=0;j<4;j++)
			t.setelem(i,j,e[j][i]);

	return t;
}