Category Archives: Math

Distance Render

Actionscript:
  1. var verts:Vector.<Number> = new Vector.<Number>();
  2. var pVerts:Vector.<Number> = new Vector.<Number>();
  3. var uvts:Vector.<Number> = new Vector.<Number>();
  4.  
  5. var hs:Number = 2.3;
  6. var step:Number = 0.04;
  7.  
  8. var tVerts:Vector.<Number> = new Vector.<Number>();
  9. var rVerts:Vector.<Number> = new Vector.<Number>();
  10. var matrix:Matrix3D = new Matrix3D();
  11. matrix.identity();
  12. matrix.appendRotation(45,Vector3D.Y_AXIS);
  13. matrix.appendRotation(45,Vector3D.X_AXIS);
  14. var inc:int = 0;
  15. var i:Number, j:Number, k:Number;
  16. i = hs;
  17. while( i> -hs){
  18.     j = hs;
  19.     while(j> -hs){
  20.         k = hs;
  21.         while(k> -hs){
  22.             tVerts[inc] = -i;
  23.             inc++
  24.             tVerts[inc] = -j;
  25.             inc++
  26.             tVerts[inc] = -k;
  27.             inc++
  28.             k -= step;
  29.         }
  30.         j -= step;
  31.     }
  32.     i -= step;
  33. }
  34.  
  35. matrix.transformVectors(tVerts, rVerts);
  36.  
  37. var vinc:int = 0;
  38. inc = 0
  39. var R:Number = 1.5;
  40. var r:Number = .5;
  41. for (i= -hs; i<hs; i+=step){
  42.     for (j = -hs; j<hs; j+=step){
  43.         for (k = -hs; k<hs; k+=step){
  44.             var vx:Number = rVerts[inc] ;
  45.             inc++
  46.             var vy:Number = rVerts[inc]  ;
  47.             inc++
  48.             var vz:Number=  rVerts[inc] ;
  49.             inc++
  50.             var s:Number = Math.pow(vx  * vx  + vy * vy + vz * vz + R*R - r * r, 2) - 4 * (R * R)*(vx * vx + vy * vy);
  51.             if (s <0 && s> -.5){
  52.                 verts[vinc] = (i * 50);
  53.                 vinc++
  54.                 verts[vinc] = (j * 50);
  55.                 vinc++
  56.                 verts[vinc] = (k * 50);
  57.                 vinc++
  58.                   inc += int((hs - k) / step) * 3;
  59.                   k = hs;
  60.              }
  61.         }
  62.     }
  63. }
  64.  
  65. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
  66. addChild(new Bitmap(canvas));
  67. render();
  68. function render():void{
  69.     matrix.identity();
  70.     matrix.appendTranslation(200, 200, 0);
  71.     Utils3D.projectVectors(matrix, verts, pVerts, uvts);
  72.     canvas.lock();
  73.     canvas.fillRect(canvas.rect, 0x000000);
  74.     var inc:int = 2;
  75.     var c:int = 0;
  76.     var r:Rectangle = new Rectangle();
  77.     r.width = r.height = 2;
  78.     for (var i:int = 0; i<pVerts.length; i+=2){
  79.           r.x = pVerts[i];
  80.           r.y = pVerts[i + 1];
  81.           c = Math.max(0,100 - verts[inc]);
  82.           canvas.fillRect(r, c <<16 | c <<8 | c);
  83.           inc += 3;
  84.     }
  85.     canvas.unlock();
  86. }

This snippet uses some of the techniques from the last few posts to create a distance render - this renders the implicit equation for a torus.

Also posted in BitmapData, Vector, color, graphics algorithms, matrix, pixel manipulation | Tagged , | Leave a comment

Parametric UV Surface

Actionscript:
  1. var matrix:Matrix3D = new Matrix3D();
  2. var verts:Vector.<Number> = new Vector.<Number>();
  3. var pVerts:Vector.<Number> = new Vector.<Number>();
  4. var uvts:Vector.<Number> = new Vector.<Number>();
  5. var sqrt2:Number = Math.sqrt(2)
  6. var pi:Number = Math.PI;
  7. var pi23:Number= 2 * Math.PI / 3;
  8. var step:Number= pi / 50;
  9. for (var u:Number = -pi; u<pi; u+=step) {
  10.     for (var v:Number = -pi; v<pi; v+=step) {
  11.         // from here http://local.wasp.uwa.edu.au/~pbourke/geometry/hexatorus/
  12.         var px = Math.sin(u) / Math.abs(sqrt2+ Math.cos(v))
  13.         var py = Math.sin(u+pi23) / Math.abs(sqrt2 +Math.cos(v + pi23))
  14.         var pz = Math.cos(u-pi23) / Math.abs(sqrt2 +Math.cos(v - pi23))
  15.         verts.push(px * 50);
  16.         verts.push(py * 50);
  17.         verts.push(pz * 50);
  18.     }
  19. }
  20. var brush:BitmapData=new BitmapData(3,2,true,0x41FFFFFF);
  21. var canvas:BitmapData=new BitmapData(400,400,false,0x000000);
  22. addChild(new Bitmap(canvas));
  23. var dx:Number=0;
  24. var dy:Number=0;
  25. addEventListener(Event.ENTER_FRAME, onLoop);
  26. function onLoop(evt:Event):void {
  27.     dx += (mouseX - dx)/4;
  28.     dy += (mouseY - dy)/4;
  29.     matrix.identity();
  30.     matrix.appendRotation(dy,Vector3D.X_AXIS);
  31.     matrix.appendRotation(dx,Vector3D.Y_AXIS);
  32.     matrix.appendTranslation(200, 200, 0);
  33.     Utils3D.projectVectors(matrix, verts, pVerts, uvts);
  34.     canvas.lock();
  35.     canvas.fillRect(canvas.rect, 0x000000);
  36.     var p = new Point();
  37.     for (var i:int = 0; i<pVerts.length; i+=2) {
  38.         p.x = pVerts[i];
  39.         p.y = pVerts[i+1];
  40.         canvas.copyPixels(brush, brush.rect, p, null, null, true);
  41.     }
  42.     canvas.unlock();
  43. }

More 3D shapes inspired by (taken from) Paul Bourke's website. I figured I should probably add a parametric 3D surface to this set of posts - so I chose to plot the Triaxial Hexatorus. It's important to note that U and V go from -PI to PI.

I googled Triaxial Hexatorus and stumbled upon a great papervision demo that creates meshes using parametric equations - it also morphs between shapes.

I also noticed that I don't need to populate the uvts or pVerts Vectors with zeros - seems to work fine without doing that.

Also posted in 3D, BitmapData, Vector, graphics algorithms, pixel manipulation | Tagged , | Leave a comment

Wormhole

Actionscript:
  1. var matrix:Matrix3D = new Matrix3D();
  2. var verts:Vector.<Number> = new Vector.<Number>();
  3. var pVerts:Vector.<Number> = new Vector.<Number>();
  4. var uvts:Vector.<Number> = new Vector.<Number>();
  5. for (var i:Number = -10; i<10; i+=.04) {
  6.     for (var j:Number = -5; j<8; j+=.04) {
  7.         for (var k:Number = -10; k<10; k+=.04) {
  8.             var s:Number =  i * i * j + j * k * k;
  9.             if (s <10 && s> 9.95) {
  10.                 verts.push(i * 20);
  11.                 verts.push(j * 20);
  12.                 verts.push(k * 20);
  13.                 pVerts.push(0),pVerts.push(0);
  14.                 uvts.push(0),uvts.push(0),uvts.push(0);
  15.             }
  16.         }
  17.     }
  18. }
  19. var brush:BitmapData=new BitmapData(3,2,true,0x41FFFFFF);
  20. var canvas:BitmapData=new BitmapData(400,400,false,0x000000);
  21. addChild(new Bitmap(canvas));
  22. var dx:Number=0;
  23. var dy:Number=0;
  24. addEventListener(Event.ENTER_FRAME, onLoop);
  25. function onLoop(evt:Event):void {
  26.     dx += (mouseX - dx)/4;
  27.     dy += (mouseY - dy)/4;
  28.     matrix.identity();
  29.     matrix.appendRotation(dy,Vector3D.X_AXIS);
  30.     matrix.appendRotation(dx,Vector3D.Y_AXIS);
  31.     matrix.appendTranslation(200, 200, 0);
  32.     Utils3D.projectVectors(matrix, verts, pVerts, uvts);
  33.     canvas.lock();
  34.     canvas.fillRect(canvas.rect, 0x000000);
  35.     var p = new Point();
  36.     for (var i:int = 0; i<pVerts.length; i+=2) {
  37.         p.x = pVerts[i];
  38.         p.y = pVerts[i+1];
  39.         canvas.copyPixels(brush, brush.rect, p, null, null, true);
  40.     }
  41.     canvas.unlock();
  42. }

Yet another variation on the post from the last two days. This one plots something resembling a wormhole - I was randomly tweaking the equation for a sphere and stumbled upon this...

Also posted in 3D, BitmapData, Vector, graphics algorithms, pixel manipulation | Tagged , | Leave a comment

Implicit 3D Plot

Actionscript:
  1. var matrix:Matrix3D = new Matrix3D();
  2. var verts:Vector.<Number> = new Vector.<Number>();
  3. var pVerts:Vector.<Number> = new Vector.<Number>();
  4. var uvts:Vector.<Number> = new Vector.<Number>();
  5. for (var i:Number = -2; i<2; i+=.04) {
  6.     for (var j:Number = -2; j<2; j+=.04) {
  7.         for (var k:Number = -2; k<2; k+=.04) {
  8.             // blobby, from here www.iiit.net/techreports/ImplicitTR.pdf
  9. var s:Number=i*i+j*j+k*k+Math.sin(4*i)-Math.cos(4*j)+Math.sin(4*k)-1;
  10.             if (s<0&&s>-.2) {
  11.                 verts.push(i * 60);
  12.                 verts.push(j * 60);
  13.                 verts.push(k * 60);
  14.                 pVerts.push(0),pVerts.push(0);
  15.                 uvts.push(0),uvts.push(0),uvts.push(0);
  16.             }
  17.         }
  18.     }
  19. }
  20. var brush:BitmapData=new BitmapData(3,2,true,0x41FFFFFF);
  21. var canvas:BitmapData=new BitmapData(400,400,false,0x000000);
  22. addChild(new Bitmap(canvas));
  23. var dx:Number=0;
  24. var dy:Number=0;
  25. addEventListener(Event.ENTER_FRAME, onLoop);
  26. function onLoop(evt:Event):void {
  27.     dx += (mouseX - dx)/4;
  28.     dy += (mouseY - dy)/4;
  29.     matrix.identity();
  30.     matrix.appendRotation(dy,Vector3D.X_AXIS);
  31.     matrix.appendRotation(dx,Vector3D.Y_AXIS);
  32.     matrix.appendTranslation(200, 200, 0);
  33.     Utils3D.projectVectors(matrix, verts, pVerts, uvts);
  34.     canvas.lock();
  35.     canvas.fillRect(canvas.rect, 0x000000);
  36.     var p = new Point();
  37.     for (var i:int = 0; i<pVerts.length; i+=2) {
  38.         p.x = pVerts[i];
  39.         p.y = pVerts[i+1];
  40.         canvas.copyPixels(brush, brush.rect, p, null, null, true);
  41.     }
  42.     canvas.unlock();
  43. }

I was looking at some equations for implicit 3D surfaces in this pdf about raytracing... anyway, I realized I could just modify the Utils3D.projectVectors() code (that I wrote a little while ago) to easily render any of the implicit equations mentioned in the pdf. I also did some experimentation with fake lighting and distance rendering which I may post in the future.

(check out the swf on wonderfl.net)

Here are some stills of the above snippet:

Also posted in 3D, BitmapData, Vector, graphics algorithms, pixel manipulation, strings | Tagged , | Leave a comment