By Zevan | January 2, 2009
Actionscript:
-
var centerX:Number=stage.stageWidth/2;
-
var centerY:Number=stage.stageHeight/2;
-
// 1 to 2 ratio
-
// try others 1 / 1.5 etc...
-
var theta:Number = Math.atan(1 / 2);
-
-
var cosX:Number=Math.cos(theta);
-
var sinX:Number=Math.sin(theta);
-
var pnt:Point = new Point();
-
-
function iso3D(x:Number, y:Number, z:Number):Point {
-
pnt.x = centerX + (x-z) * cosX;
-
pnt.y = centerY - (x+z) * sinX - y;
-
return pnt;
-
}
-
-
var p:Point = iso3D(0,0,0);
-
-
graphics.beginFill(0x000000);
-
graphics.drawCircle(p.x, p.y, 2);
-
-
// x axis positive
-
trace("x = red");
-
for (var i:int = 1; i<10; i++){
-
graphics.beginFill(0xFF0000);
-
p = iso3D(i*10, 0, 0);
-
graphics.drawCircle(p.x, p.y, 2);
-
}
-
-
// y axis positive
-
trace("y = green");
-
for (i= 1; i<10; i++){
-
graphics.beginFill(0x00FF00);
-
p = iso3D(0, i * 10, 0);
-
graphics.drawCircle(p.x, p.y, 2);
-
}
-
-
// z axis positive
-
trace("z = blue");
-
for (i= 1; i<10; i++){
-
graphics.beginFill(0x0000FF);
-
p = iso3D(0, 0, i * 10);
-
graphics.drawCircle(p.x, p.y, 2);
-
}
The above code demos a conversion from isometric coordinates to cartesian coordinates. It draws out part of the x, y and z axis using the iso3D() function.
I've always faked isometric conversion by just tweaking numbers. A few years ago I created some strange isometric engines (here's another example). The other day when I wrote the isometric voxels snippet I just created the iso3D() function with a little trial and error. As you'll see it's not exactly the same as the one here. This new conversion is the result of some googling. The updated conversion is pretty close to the one that I wrote for the voxel post, but has one less multiplication... and a clearer place to control the scale ratio ...
Posted in 3D, misc | Also tagged actionscript, flash |
By Zevan | December 28, 2008
Actionscript:
-
// isometric conversion
-
var centerX:Number=stage.stageWidth/2;
-
var centerY:Number=stage.stageHeight/2;
-
var theta:Number=Math.PI/4;// 45 degrees;
-
var cosX:Number=Math.cos(theta);
-
var sinX:Number=Math.sin(theta);
-
var pnt:Point = new Point();
-
function iso3D(x:Number, y:Number, z:Number):Point {
-
pnt.x = centerX + (x-z) * cosX
-
pnt.y = centerY - (x+z) * 0.5 * sinX - y;
-
return pnt;
-
}
-
// example:
-
var canvas:BitmapData=new BitmapData(stage.stageWidth,stage.stageHeight,true,0xFF000000);
-
addChild(new Bitmap(canvas,"auto",true));
-
var size:int=100;
-
var hs:int=size / 2;
-
var pen:Point = new Point();
-
var vect:Vector3D = new Vector3D();
-
// draw a few shapes with offset:
-
for (var dist:int = 10; dist <= 80; dist *= 2) {
-
// voxel space:
-
for (var i:int = 0; i<size; i++) {
-
for (var j:int = 0; j<size; j++) {
-
for (var k:int = 0; k<size; k++) {
-
vect.x=j-hs;
-
vect.y=i-hs;
-
vect.z=k-hs;
-
pen = iso3D(vect.x,vect.y,vect.z);
-
if (Math.sqrt((vect.x * vect.x) + (vect.y * vect.y) + (vect.z * vect.z)) <dist) {
-
// using Vector3D.distance() is very slow compared to above
-
// a few types of coloring:
-
var xp:Number = pen.x + (dist <<2) - 200;
-
canvas.setPixel(xp, pen.y-100, (i <<16 | j <<8 | k) <<1);
-
canvas.setPixel(xp, pen.y+100, (k <<16 | k <<8 | k+j) );
-
}
-
}
-
}
-
}
-
}
The above will draw this:
You can read more about voxels here.
This isn't the speediest way to do voxels (especially if you want to animate). This was just the first thing that came to mind.
By Zevan | November 30, 2008
Actionscript:
-
stage.frameRate = 30;
-
-
for (var i:int = 0; i<100; i++){
-
makeBoxSegment(200, 200 - i, i * 2);
-
}
-
-
function makeBoxSegment(xp:Number, yp:Number, col:uint):Sprite {
-
var isoBox:Sprite = Sprite(addChild(new Sprite()));
-
with (isoBox) scaleY = .5, y = yp, x = xp;
-
var box:Shape = Shape(isoBox.addChild(new Shape()));
-
box.rotation = 45;
-
with (box.graphics) beginFill(col), drawRect(-50,-50,100,100);
-
isoBox.addEventListener(Event.ENTER_FRAME, onRotate);
-
return isoBox;
-
}
-
-
function onRotate(evt:Event):void {
-
evt.currentTarget.getChildAt(0).rotation = mouseX;
-
}
An isometric box that rotates with the mouseX.