////////////////////////////////////////////////////////////////
// D3 v1.11 : Affiche des objets 3D.
// Copyright (c) 1998-2006 Werner BEROUX
// Tous Droits Réservés.
// 
// Auteur:
//   Werner BEROUX
//   werner@beroux.com
//   http://www.beroux.com
// 
// Licence: Il est interdit de copier, modifier, partiellement
//   ou complètement ce code. Refermez immédiatement ce fichier
//   si vous n'avez pas l'accord de l'auteur.
//   Bon d'accord, vous pouvez quand même regarder.
//
// Note 2006-03-29: J'ai trouvé comment faire des projections
//   en appliquand un pricinpe simple. En fait je n'ai pas
//   copié de code pour faire ce fichier, ni une technique
//   existante de projection.
//   Cependant depuis, j'ai étudié un peu ces techniques et
//   la géométrie projective en math. En utilisant une matrice
//   4x4 on peut grandement améliorer les performance des
//   transformations.
//   Pour plus de détail, autant me contacter.
// 
////////////////////////////////////////////////////////////////

// Variables
var lignes = new Array(
	new Array(4,5), 
	new Array(6,5), 
	new Array(6,7), 
	new Array(7,4), 
	new Array(0,4), 
	new Array(5,1), 
	new Array(6,2), 
	new Array(7,3), 
	new Array(0,1), 
	new Array(2,1), 
	new Array(2,3), 
	new Array(3,0)
);
var rotx = 0;
var roty = 0;
var rotz = 0;
var rotxIncr = 10*Math.PI/180;
var rotyIncr = 7*Math.PI/180;
var rotzIncr = 10*Math.PI/180;
var bRunTest = true;
var jg = 0;

function StartTest(jg)
{
	if (this.jg == 0)
		this.jg = jg;
	bRunTest = true;
	RunTest();
}

function StopTest()
{
	bRunTest = false;
}

function RunTest()
{
	if (!bRunTest)
		return;
		
	var sommets3D = new Array(
		new Array(-100, 100,-100), 
		new Array( 100, 100,-100), 
		new Array( 100,-100,-100), 
		new Array(-100,-100,-100), 
		new Array(-100, 100, 100), 
		new Array( 100, 100, 100), 
		new Array( 100,-100, 100), 
		new Array(-100,-100, 100)
	);

	// Rotations
	rotx += rotxIncr
	roty += rotyIncr
	rotz += rotzIncr
	for (var i=0; i<8; i++) {
		//   x
		var len = Math.sqrt(sommets3D[i][1]*sommets3D[i][1] + sommets3D[i][2]*sommets3D[i][2], 2)
		var angle = Math.atan(sommets3D[i][1]/sommets3D[i][2]) + rotx;
		if (sommets3D[i][1] < 0) angle += Math.PI;
		sommets3D[i][1] = len * Math.cos(angle);
		sommets3D[i][2] = len * Math.sin(angle);
		//   y
		var len = Math.sqrt(sommets3D[i][2]*sommets3D[i][2] + sommets3D[i][0]*sommets3D[i][0], 2)
		var angle = Math.atan(sommets3D[i][0]/sommets3D[i][2]) + roty;
		if (sommets3D[i][2] < 0) angle += Math.PI;
		sommets3D[i][2] = len * Math.cos(angle);
		sommets3D[i][0] = len * Math.sin(angle);
		//   z
		var len = Math.sqrt(sommets3D[i][0]*sommets3D[i][0] + sommets3D[i][1]*sommets3D[i][1], 2)
		var angle = Math.atan(sommets3D[i][1]/sommets3D[i][0]) + rotz;
		if (sommets3D[i][0] < 0) angle += Math.PI;
		sommets3D[i][0] = len * Math.cos(angle);
		sommets3D[i][1] = len * Math.sin(angle);
	}

	// Affiche
	D3_Render(jg, 300/2, 300/2, sommets3D, lignes);

	// Fin
	window.setTimeout("RunTest()", 100);
}

// Anime l'objet 3D
//   jg 		= dc (zone d'affichage)
//   posX, posY	= position où afficher l'objet
//   sommets3D	= positions en x,y,z de tous les sommets à afficher
//   lignes		= lignes sous la forme: (sommet de début, sommet de fin)
function D3_Render(jg, posX, posY, sommets3D, lignes)
{
	var sommets2D = new Array(
		new Array(sommets3D.length),
		new Array(sommets3D.length)
	);
	
	// Projette
	for (var i=0; i<sommets3D.length; i++) {
		sommets2D[0][i] = posX + 300 * sommets3D[i][0] / (sommets3D[i][2]+500);
		sommets2D[1][i] = posY + 300 * sommets3D[i][1] / (sommets3D[i][2]+500);
	}

	// Affiche les lignes
	jg.clear();
	jg.setColor('#003300');
	jg.setStroke(2);
	for (var i=0; i<lignes.length; i++) {
		var nDebut = lignes[i][0];
		var nFin   = lignes[i][1];
		jg.drawLine(sommets2D[0][nDebut],	// x1
					sommets2D[1][nDebut],	// y1
					sommets2D[0][nFin],		// x2
					sommets2D[1][nFin]);	// y2
	}
	jg.paint();

	// Fin
	return true;
}

