daily pastebin goal
11%
SHARE
TWEET

PHP 3D Cube

a guest Aug 31st, 2011 500 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. /**
  3.  * This script draws and outputs a Cube.
  4.  *
  5.  * The GD library is used to draw the cube and output it as a
  6.  * PNG image.
  7.  *
  8.  * Developed by Leonel Machava <leonelmachava@gmail.com>
  9.  * http://codentronix.com
  10.  * http://codentronix.com/2011/06/06/how-to-draw-a-cube-using-php/
  11.  *
  12.  * This code is released under the "MIT License" available at
  13.  * http://www.opensource.org/licenses/mit-license.php
  14.  * http://codentronix.com/2011/06/06/how-to-draw-a-cube-using-php/
  15.  */
  16.  
  17. /* Represents points in 3D space. */
  18. class Point3D {
  19.   public $x;
  20.   public $y;
  21.   public $z;
  22.  
  23.   public function __construct($x,$y,$z) {
  24.     $this->x = $x;
  25.     $this->y = $y;
  26.     $this->z = $z;
  27.   }
  28.  
  29.   public function rotateX($angle) {
  30.     $rad = $angle * M_PI / 180;
  31.     $cosa = cos($rad);
  32.     $sina = sin($rad);
  33.     $y = $this->y * $cosa - $this->z * $sina;
  34.     $z = $this->y * $sina + $this->z * $cosa;
  35.     return new Point3D($this->x, $y, $z);
  36.   }
  37.  
  38.   public function rotateY($angle) {
  39.     $rad = $angle * M_PI / 180;
  40.     $cosa = cos($rad);
  41.     $sina = sin($rad);
  42.     $z = $this->z * $cosa - $this->x * $sina;
  43.     $x = $this->z * $sina + $this->x * $cosa;
  44.     return new Point3D($x, $this->y, $z);
  45.   }
  46.  
  47.   public function rotateZ($angle) {
  48.     $rad = $angle * M_PI / 180;
  49.     $cosa = cos($rad);
  50.     $sina = sin($rad);
  51.     $x = $this->x * $cosa - $this->y * $sina;
  52.     $y = $this->x * $sina + $this->y * $cosa;
  53.     return new Point3D($x, $y, $this->z);
  54.   }
  55.  
  56.   public function project($width,$height,$fov,$viewerDistance) {
  57.     $factor = (float)($fov) / ($viewerDistance + $this->z);
  58.     $x = $this->x * $factor + $width / 2;
  59.     $y = -$this->y * $factor + $height / 2;
  60.     return new Point3D($x,$y,$this->z);
  61.   }
  62. }
  63. class Cube3DImage{
  64.   public function __construct($width,$height,$depth){
  65.                 $this->width=$width;
  66.                 $this->height=$height;
  67.                 $this->depth=$depth;
  68.  
  69.                 $this->rotate_x=0;
  70.                 $this->rotate_y=0;
  71.                 $this->rotate_z=0;
  72.  
  73.                 $this->image_width=90;
  74.                 $this->image_height=90;
  75.                 $this->fov=256;
  76.                 $this->view_distance=4;
  77.  
  78.                 $this->x_color=array(140,140,140);
  79.                 $this->y_color=array(192,192,192);
  80.                 $this->z_color=array(220,220,220);
  81.                 $this->bg_color=array(249, 249, 249);
  82.         }
  83.         function rotate($axis,$val){
  84.                 if($axis=='x'){$this->rotate_x=strtolower($val);}
  85.                 else if($axis=='y'){$this->rotate_y=strtolower($val);}
  86.                 else if($axis=='z'){$this->rotate_z=strtolower($val);}
  87.         }
  88.         function image(){
  89. /*
  90.                                         Z (+1z)
  91.                                         .    
  92. g.  .  , h                              |      
  93.  :  f_ _._ e                            .    
  94.  ,  |    ,|                             |      
  95. c; ,| .  ;|<-d                          .    
  96.  ` ,|_ _ _|                             |      
  97.     b     a                             .    
  98.                                         |      
  99.                                         .    
  100.                                         |      
  101.                                         .    
  102.                                         |      
  103.                                         .    
  104.                                         |      
  105.                                         ,      
  106.                                  .   /  *  \   ,
  107.                        ,    /                      ` .
  108.                  /                                      `  \ .  
  109.          /   `                                                 `  \ .
  110. (+1x) X                                                               Y (+1y)
  111.  
  112.  
  113. */
  114.                 $vertices = array(
  115.                         'a'=>new Point3D((abs($this->width/2)*(-1)), (abs($this->depth/2)), (abs($this->height/2)*(-1))),                                       //a -> 0 = right, front, bottom
  116.                         'b'=>new Point3D((abs($this->width/2)),  (abs($this->depth/2)), (abs($this->height/2)*(-1))),                                                   //b -> 1 = left, front, bottom
  117.                         'c'=>new Point3D((abs($this->width/2)), (abs($this->depth/2)*(-1)),  (abs($this->height/2)*(-1))),                              //c -> 2 = left, back, bottom
  118.                         'd'=>new Point3D((abs($this->width/2)*(-1)), (abs($this->depth/2)*(-1)),  (abs($this->height/2)*(-1))),         //d -> 3 = right, back, bottom
  119.                         'e'=>new Point3D((abs($this->width/2)*(-1)), (abs($this->depth/2)), (abs($this->height/2))),                                                    //e -> 4 = right, front, top
  120.                         'f'=>new Point3D((abs($this->width/2)), (abs($this->depth/2)), (abs($this->height/2))),                                                                         //f -> 5 = left, front, top
  121.                         'g'=>new Point3D((abs($this->width/2)), (abs($this->depth/2)*(-1)), (abs($this->height/2))),                                                    //g -> 6 = left, back, top
  122.                         'h'=>new Point3D((abs($this->width/2)*(-1)), (abs($this->depth/2)*(-1)), (abs($this->height/2)))                                        //h -> 7 = right, back, top
  123.                 );
  124.                 $faces = array(
  125.                         'bottom'=>array('a', 'b', 'c', 'd'),// BOTTOM SIDE (a,b,c,d)
  126.                         'left'=>array('b', 'f', 'g', 'c'),// LEFT SIDE (b,f,g,c)
  127.                         'top'=>array('f', 'e', 'h', 'g'),// TOP SIDE (f,e,h,g)
  128.                         'right'=>array('e','a', 'd', 'h'),// RIGHT SIDE (e,a,d,h)
  129.                         'front'=>array('a', 'e', 'f', 'b'),// FRONT SIDE (a,e,f,b)
  130.                         'back'=>array( 'd', 'c', 'g', 'h') // BACK SIDE (d,c,g,h)
  131.                 );
  132.  
  133.                 $im = imagecreatetruecolor($this->image_width, $this->image_height);
  134.                 imagefill($im , 0, 0, imagecolorallocate($im, $this->bg_color[0], $this->bg_color[1], $this->bg_color[2]));//background color
  135.                 $colors = array(
  136.                         'bottom'=>$this->z_color,
  137.                         'left'=>$this->x_color,
  138.                         'top'=>$this->z_color,
  139.                         'right'=>$this->x_color,
  140.                         'front'=>$this->y_color,
  141.                         'back'=>$this->y_color
  142.                 );
  143.                 foreach($colors as $k => $v){
  144.                         $im_colors[$k] = imagecolorallocate($im,$v[0],$v[1],$v[2]);
  145.                 }
  146.                 /* It will store transformed vertices. */
  147.                 $transform = array();
  148.                 foreach($vertices as $k => $v){
  149.                         $transform[$k] = $v->rotateX($this->rotate_x)->rotateY($this->rotate_y)->rotateZ($this->rotate_z)->project($this->image_width, $this->image_height, $this->fov, $this->view_distance);/* Transform all the vertices. */
  150.                 }
  151.                 $avgZ = array();
  152.                 /* Calculate the average Z value of each face. */
  153.                 //$faces['bottom'] $faces['left'] $faces['top'] $faces['right'] $faces['front'] $faces['back']
  154.                 foreach($faces as $k => $v){// as $k => $v
  155.                         $avgZ[$k] = ($transform[$v[0]]->z + $transform[$v[1]]->z + $transform[$v[2]]->z + $transform[$v[3]]->z) / $this->view_distance;//8/30/2011 ADJUSTED??!?
  156.                 }
  157.                 arsort($avgZ);
  158.  
  159.                 foreach($avgZ as $k => $v){/* Draw the faces from back to front. */
  160.                         $_face = $faces[$k];//'bottom'=>, 'left'=>, 'top'=>, 'right'=>, 'front'=>, 'back'=>
  161.                         $points = array(
  162.                                 $transform[$_face[0]]->x, $transform[$_face[0]]->y, // 0,1 => x1, y1
  163.                                 $transform[$_face[1]]->x, $transform[$_face[1]]->y, // 2,3 => x2, y2
  164.                                 $transform[$_face[2]]->x, $transform[$_face[2]]->y, // 4,5 => x3, y3
  165.                                 $transform[$_face[3]]->x, $transform[$_face[3]]->y  // 6,7 => x4, y4
  166.                         );
  167.                         imagefilledpolygon($im,$points,4,$im_colors[$k]);
  168.                 }
  169.  
  170.                 header("Content-Type: image/png");/* Tell the browser/client we are outputing a PNG image. */
  171.                 imagepng($im);/* Output the image. */
  172.         }
  173. }
  174. $dim = array();
  175. $dim['width']=14;//x cord
  176. $dim['height']=14;//z cord
  177. $dim['depth']=36;//y cord
  178. $cubeOBJ=new Cube3DImage($dim['width'],$dim['height'],$dim['depth']);
  179. $cubeOBJ->image_width=960;
  180. $cubeOBJ->image_height=960;
  181. $cubeOBJ->fov=256;
  182. $cubeOBJ->view_distance=4;
  183. if(@array_key_exists('fov',$_GET)){$cubeOBJ->fov=intVal($_GET['fov']);}
  184. if(@array_key_exists('dist',$_GET)){$cubeOBJ->view_distance=intVal($_GET['dist']);}
  185.  
  186.  
  187. /* Assign random values for the angles that describe the cube orientation. */
  188. $angleX = 40;// up and down horizontally
  189. $angleZ = 0;// side to side horizontally
  190. $angleY = 20;// tilt (tip/roll)
  191.  
  192. $cubeOBJ->rotate('x', $angleX);
  193. $cubeOBJ->rotate('y', $angleY);
  194. $cubeOBJ->rotate('z', $angleZ);
  195.  
  196. $cubeOBJ->image();
RAW Paste Data
Top