Advertisement
Guest User

PHP 3D Cube

a guest
Aug 31st, 2011
601
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.56 KB | None | 0 0
  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();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement