Example #1
0
/*
 * La procedure "Matrix_to_Position" initialise la position par la matrice.
 * Si M est la matrice, et P la position : M = R.Sid.T, P = (R,Sid,T).
 * On suppose que la matrice de rotation 3x3 de M est unitaire.
 * Entree :
 * m		Matrice de rotation et de translation.
 * pp		Position a initialiser.
 */
void
Matrix_to_Position (Matrix m, AritPosition *pp)
{
	Matrix_to_Rotate (m, &pp->rotate);
	SET_COORD3(pp->scale,1.0,1.0,1.0);
	SET_COORD3(pp->translate,m[3][0],m[3][1],m[3][2]);
}
Example #2
0
/*
 * La procedure "Matrix_to_Rotate" initialise la rotation par la matrice.
 * Si M est la matrice, si R est la matrice de rotation :
 *
 *		 	| m00	m01	m02	0 |
 * M = Rx.Ry.Rz =	| m10	m11	m12	0 |
 *		 	| m20	m21	m22	0 |
 *		 	| 0	0	0	1 |
 *
 * et	m00 = cy.cz		m01 = cy.sz		m02 = -sy
 *	m10 = sx.sy.cz-cx.sz 	m11 = sx.sy.sz+cx.cz	m12 = sx.cy
 *	m20 = cx.sy.cz+sx.sz	m21 = cx.sy.sz-sx.cz	m22 = cx.cy
 * avec	ci = cos Oi et si = sin Oi.
 *
 * R = Rx.Ry.Rz
 * Rx rotation autour de Ox d'angle O1
 * Ry rotation autour de Oy d'angle O2
 * Rz rotation autour de Oz d'angle O3
 *
 * Singularite : si |ry| == 90 degres alors rz = 0,
 * 		 soit une rotation d'axe 0z et d'angle "rx + rz".
 *
 * Entree :
 * m		Matrice contenant la composition des rotations.
 * vp		Rotations par rapport aux axes d'un repere droit en degres.
 */
void
Matrix_to_Rotate (Matrix m, Vector *vp)
{
  float sy = - m[0][2];
  float cy = (float) sqrt (1.0 - (double) (sy * sy));
  float cx, sx;

	if (FABS(cy) > M_EPSILON) {
    float sz = m[0][1] / cy;
    float cz = m[0][0] / cy;

    sx = m[1][2] / cy;
    cx = m[2][2] / cy;

		SET_COORD3(*vp,
			cosin_to_angle (cx, sx),
			cosin_to_angle (cy, sy),
			cosin_to_angle (cz, sz));
	}
	else {	/* RZ = 0 =>  Ry = +/- 90 degres	*/
		sx = m[1][1];
		cx = - m[2][1];
	
		SET_COORD3(*vp,
			cosin_to_angle (cx, sx),
			(sy > (float)0.0) ? (float)M_PI_2 : (float)(- M_PI_2),
			(float)0.0);
	}
	vp->x *= (float)180.0 / (float)M_PI;	/* passage en degres	*/
	vp->y *= (float)180.0 / (float)M_PI;
	vp->z *= (float)180.0 / (float)M_PI;
}
Example #3
0
/* Create a jack shaped object, then put a smaller copy in
   each of the octants defined by the arms of the jack.
   This process is repeated until depth reaches max_depth. */
static void
make_rec_jack(depth, max_depth)
{
    double i, j, k;
    COORD3 scale, trans;
	
    make_jack_obj();
	
    if (depth < max_depth) {
		SET_COORD3(scale, 0.5, 0.5, 0.5);
		for (i=-0.5;i<=0.5;i+=1)
			for (j=-0.5;j<=0.5;j+=1)
				for (k=-0.5;k<=0.5;k+=1) {
					if (depth==1)
						PLATFORM_PROGRESS(0, 4+i*4+j*2+k, 7);
					lib_tx_push();
					SET_COORD3(trans, i, j, k);
					lib_tx_translate(trans);
					lib_tx_scale(scale);
					make_rec_jack(depth+1, max_depth);
					lib_tx_pop();
				}
	}
}
Example #4
0
/* Create a single copy of our recursive object.  The general
   sizing and placement of the object are maintained by the
   recursive routine make_rec_jack.  This routine does the
   actual geometry building */
static void
make_jack_obj()
{
	COORD3 scale;
	COORD4 center, base, apex;
	
	/* Save the current transformation */
	lib_tx_push();
	
	/* Scale the object down to prevent overlaps */
	SET_COORD3(scale, 0.75, 0.75, 0.75);
	lib_tx_scale(scale);
	
	/* Now create the object - three intersecting cylinders
	 * with spheres at both ends
	 */
	
	/* Cylinders on each axis */
	SET_COORD4(base, -1, 0, 0, 0.1);
	SET_COORD4(apex,  1, 0, 0, 0.1);
	lib_output_cylcone(base, apex, output_format);
	SET_COORD4(base, 0, -1, 0, 0.1);
	SET_COORD4(apex, 0,  1, 0, 0.1);
	lib_output_cylcone(base, apex, output_format);
	SET_COORD4(base, 0, 0, -1, 0.1);
	SET_COORD4(apex, 0, 0,  1, 0.1);
	lib_output_cylcone(base, apex, output_format);
	
	/* Spheres at the ends of the cylinders */
	SET_COORD4(center, 1, 0, 0, 0.2);
	lib_output_sphere(center, output_format);
	SET_COORD4(center, 0, 1, 0, 0.2);
	lib_output_sphere(center, output_format);
	SET_COORD4(center, 0, 0, 1, 0.2);
	lib_output_sphere(center, output_format);
	SET_COORD4(center,-1, 0, 0, 0.2);
	lib_output_sphere(center, output_format);
	SET_COORD4(center, 0,-1, 0, 0.2);
	lib_output_sphere(center, output_format);
	SET_COORD4(center, 0, 0,-1, 0.2);
	lib_output_sphere(center, output_format);
	
	/* Restore the transform to what it was prior to
	 * entering this routine.
	 */
	lib_tx_pop();
}
Example #5
0
/*
 * La procedure "rotate_vector" transforme le vecteur
 * par la rotation de sens trigonometrique d'angle et d'axe donnes.
 * Entree :
 * vp		Vecteur a transformer.
 * a		Angle de rotation en degres.
 * axis		Vecteur directeur de l'axe de rotation.
 */
void
rotate_vector (Vector *vp, float a, Vector *axis)
{
	Vector		n, u, v, cross;
	float	f;

	a *= (float)M_PI / (float)180.0;	/* passage en radians		*/

	n = *axis;		/* norme le vecteur directeur	*/
	norm_vector (&n);

	/* 
	 * Avant rotation, vp vaut :
	 *   u + v
	 * Apres rotation, vp vaut :
	 *   u + cos(a) * v + sin(a) * (n^vp)
	 * = u + cos(a) * v + sin(a) * (n^v)
	 * avec u = (vp.n) * n, v = vp-u;
	 * ou "u" est la projection de "vp" sur l'axe "axis",
	 * et "v" est la composante de "vp" perpendiculaire a "axis".
	 */
	f = DOT_PRODUCT(*vp, n);
	u = n;
	MUL_COORD3(u,f,f,f);		/* (vp.n) * n		*/

	DIF_COORD3(v,*vp,u);		/* calcule "v"		*/

	f = (float) cos ((double) a);
	MUL_COORD3(v,f,f,f);		/* v * cos(a)		*/

	CROSS_PRODUCT(cross,n,*vp);
	f = (float) sin ((double) a);
	MUL_COORD3(cross,f,f,f);	/* (n^v) * sin(a)	*/

	SET_COORD3(*vp,
		u.x + v.x + cross.x,
		u.y + v.y + cross.y,
		u.z + v.z + cross.z);
}