Topic: Simple 3D rotation - z-axis rotation goes weird? Pages that link to <a href="https://ozoneasylum.com/backlink?for=28406" title="Pages that link to Topic: Simple 3D rotation - z-axis rotation goes weird?" rel="nofollow" >Topic: Simple 3D rotation - z-axis rotation goes weird?\

 
Author Thread
BillyRayPreachersSon
Bipolar (III) Inmate

From: London
Insane since: Jul 2004

IP logged posted posted 09-09-2006 19:02 Edit Quote

Hi all,

I've toying around with some simple 3D rotation code I picked up from the old Hornet demo archive (it was written in 1993, so there might be better ways of doing this now - I'm open to suggestions!).

If I choose to rotate around the z-axis with my y-axis at 0 degrees, all looks fine as expected (the dots rotate anti-clockwise, around the z-axis). However, if I set the y-axis to 110 degrees (in the setup function), the dots do not rotate as I would expect them to. I would expect the dots to appear to be travelling away from me, but what actually happens is that the dots appear to be rotating almost as if they were rotating around the x-axis.

Am I missing something obvious here, or is this really what it should look like?

code:
<html>
<head>
	<title>Dots</title>

	<style type="text/css">
	body {
		background-color: #000000;
		overflow: hidden;
	}
	.dot {
		position: absolute;
		width: 5px;
		height: 5px;
		background-color: #FFFFFF;
		overflow: hidden;
	}
	</style>

	<script type="text/javascript">
	<!--
		var sinTable = new Array(360);
		var cosTable = new Array(360);

		var numDots = 20;
		var radius = 50;
		var angleSpacing = 360 / numDots;

		var xAngle, yAngle, zAngle;
		var array3D = [];
		var dots = [];
		var rotationSpeed = 80;		// msecs between increments
		var rotationIncrement = 3;	// degrees to increment each time

		function setup() {
			// create lookup tables
			for (var angle=0; angle<360; angle++) {
				sinTable[angle] = Math.sin(angle / 180.0 * Math.PI);
				cosTable[angle] = 0 - Math.cos(angle / 180.0 * Math.PI);
			}

			// setup initial angles
			xAngle = 0;
			yAngle = 0;
			zAngle = 0;

			// create dot positions
			for (var loop=0; loop<numDots; loop++) {
				var angle = loop * angleSpacing;
				var tempX = radius * cosTable[angle];
				var tempY = radius * sinTable[angle];
				array3D[loop] = { x:tempY, y:tempX, z:0 };
			}

			// create dots
			for (var loop=0; loop<numDots; loop++) {
				dots[loop] = document.createElement('div');
				dots[loop].className = 'dot';
				document.getElementsByTagName('body')[0].appendChild(dots[loop]);
			}

			// start animation
			animateDots();
		}


		function animateDots() {
			var array2D = [];

			// convert 3D to 2D co-ords
			for (loop=0; loop<numDots; loop++) {
				x = array3D[loop].x;
				y = array3D[loop].y;
				z = array3D[loop].z;

				var cosX = cosTable[xAngle];
				var cosY = cosTable[yAngle];
				var cosZ = cosTable[zAngle];
				var sinX = sinTable[xAngle];
				var sinY = sinTable[yAngle];
				var sinZ = sinTable[zAngle];

				yTemp = y * cosX - z * sinX;
				zTemp = y * sinX + z * cosX;
				y = yTemp;
				z = zTemp;
				xTemp = x * cosY - z * sinY;
				zTemp = x * sinY + z * cosY;
				x = xTemp;
				z = zTemp;
				xTemp = x * cosZ - y * sinZ;
				yTemp = x * sinZ + y * cosZ;

// add perspective (using perspective projection)
//				xTemp = 160 + xTemp * 100 / (zTemp - 100);
//				yTemp = 100 + yTemp * 100 / (zTemp - 100);

				// update dot positions
				array2D[loop] = { x:xTemp, y:yTemp, z:zTemp };
			}
			// do z-sorting & update dot opacity based upon z-index
			for (var loop=0; loop<numDots; loop++) {
				var coords = array2D[loop];
				var zRange = radius * 2;
				var percentageInRange = Math.round((100 / zRange) * (coords.z + radius));
				var opacity = percentageInRange / 100;

				var dot = dots[loop].style;
				dot.MozOpacity = opacity;
				dot.zIndex = Math.round(coords.z) + radius;
				dot.left = Math.round(coords.x) + 150 + 'px';
				dot.top = Math.round(coords.y) + 150 + 'px';
			}

//			xAngle += rotationIncrement;
//			yAngle += rotationIncrement;
			zAngle += rotationIncrement;

			if (xAngle > 359) xAngle -= 359;
			if (yAngle > 359) yAngle -= 359;
			if (zAngle > 359) zAngle -= 359;

			setTimeout('animateDots();', rotationSpeed);
		}
	//-->
	</script>
</head>

<body onload="setup();">
</body>

</html>



Thanks!

Dan

BillyRayPreachersSon
Bipolar (III) Inmate

From: London
Insane since: Jul 2004

IP logged posted posted 09-10-2006 17:10 Edit Quote

Given that I know pretty much nil about how all this maths stuff works, I finally found the answer after trawling Google for many hours today.

My brain is pretty much fried , and I think I'll scream if I have to use the words "matrix" and "multiplication" in the same sentence ever again

But anyway - I found the answer here:

http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q35

It talks about the ordering of the X, Y, Z calculations, and says that if you want to model things from a camera viewpoint, you need to reverse the ordering to Z, Y, X. I do this, and all is exactly as I expect.

Dan



Post Reply
 
Your User Name:
Your Password:
Login Options:
 
Your Text:
Loading...
Options:


« BackwardsOnwards »

Show Forum Drop Down Menu