Created
July 13, 2017 12:44
-
-
Save rzfarrell/3a9e5046dcfd6bd2d2f4bfa1a34b21ef to your computer and use it in GitHub Desktop.
Translate 3D object onto 2D space
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function RotatePoint($sin,$cos,$x,$y) { | |
return array($x*$cos - $y*$sin, $y*$cos + $x*$sin); | |
} | |
function draw_boxes($image_name, $image_size, $boxes) | |
{ | |
$image = imagecreatetruecolor($image_size, $image_size); | |
imageantialias($image, true); | |
$white = imagecolorallocate($image, 255, 255, 255); | |
imagefilledrectangle($image, 0, 0, $image_size, $image_size, $white); | |
$brown = imagecolorallocate($image, 120, 53, 31); | |
$green = imagecolorallocate($image, 23, 255, 65); | |
$blue = imagecolorallocate($image, 31, 23, 255); | |
$orange = imagecolorallocate($image, 255, 185, 23); | |
$camx = 0; | |
$camy = 0; | |
$camz = 0; | |
$yaw = deg2rad(-25); | |
$pitch = deg2rad(55); | |
$sy = sin(-$yaw); $cy = cos(-$yaw); $sp = sin(-$pitch); $cp = cos(-$pitch); | |
$scale = 1; | |
$x_adjustment = ($image_size-20)/2; | |
$z_adjustment = ($image_size-20)/2; | |
$boxes[0]['color'] = $brown; | |
$boxes[] = $boxes[0]; | |
$temp_boxes = array(); | |
foreach ($boxes as $box_num => $box) | |
{ | |
$temp_boxes[] = $box; | |
if (isset($box['fill']) && $box['fill'] === true) | |
{ | |
$box['fill'] = false; | |
$box['color'] = imagecolorallocate($image, 70, 70, 70); | |
$temp_boxes[] = $box; | |
} | |
} | |
$boxes = $temp_boxes; | |
foreach ($boxes as $box_num => $box) | |
{ | |
$width = $box['width']; | |
$length = $box['length']; | |
$height = $box['height']; | |
$start_x = $box['start'][0]; | |
$start_y = $box['start'][1]; | |
$start_z = $box['start'][2]; | |
$faces = array(); | |
// Draw 6 faces | |
for ($i = 0; $i < 6; $i++) | |
{ | |
switch ($i) | |
{ | |
case 0: | |
$face = array( | |
array($start_x, $start_y, $start_z), | |
array($start_x+$width, $start_y, $start_z), | |
array($start_x+$width, $start_y, $start_z+$height), | |
array($start_x, $start_y, $start_z+$height) | |
); | |
break; | |
case 1: | |
$face = array( | |
array($start_x, $start_y+$length, $start_z), | |
array($start_x+$width, $start_y+$length, $start_z), | |
array($start_x+$width, $start_y+$length, $start_z+$height), | |
array($start_x, $start_y+$length, $start_z+$height) | |
); | |
break; | |
case 2: | |
$face = array( | |
array($start_x, $start_y, $start_z), | |
array($start_x, $start_y+$length, $start_z), | |
array($start_x, $start_y+$length, $start_z+$height), | |
array($start_x, $start_y, $start_z+$height) | |
); | |
break; | |
case 3: | |
$face = array( | |
array($start_x+$width, $start_y, $start_z), | |
array($start_x+$width, $start_y+$length, $start_z), | |
array($start_x+$width, $start_y+$length, $start_z+$height), | |
array($start_x+$width, $start_y, $start_z+$height) | |
); | |
break; | |
case 4: | |
$face = array( | |
array($start_x, $start_y, $start_z+$height), | |
array($start_x+$width, $start_y, $start_z+$height), | |
array($start_x+$width, $start_y+$length, $start_z+$height), | |
array($start_x, $start_y+$length, $start_z+$height) | |
); | |
break; | |
case 5: | |
$face = array( | |
array($start_x, $start_y, $start_z), | |
array($start_x+$width, $start_y, $start_z), | |
array($start_x+$width, $start_y+$length, $start_z), | |
array($start_x, $start_y+$length, $start_z) | |
); | |
break; | |
} | |
foreach ($face as $key => $point) | |
{ | |
$x = $point[0] - $camx; | |
$y = $point[1] - $camy; | |
$z = $point[2] - $camz; | |
$rot = RotatePoint($sy,$cy,$x,$y); | |
$face[$key]['x'] = $rot[0]; | |
$face[$key]['y'] = $rot[1]; | |
$rot = RotatePoint($sp,$cp,$z,$face[$key]['y']); | |
$face[$key]['z'] = $rot[0]; | |
$face[$key]['y'] = $rot[1]; | |
} | |
$faces[] = $face; | |
} | |
// BOX 0 SHOULD BE THE LARGEST SO WE CAN FIND THE BOUNDRIES AND SET THE SCALE AND ADJUSTMENTS TO CENTER THE IMAGE | |
if ($box_num == 0) | |
{ | |
$min_x = 100000; | |
$max_x = -100000; | |
$min_z = 100000; | |
$max_z = -100000; | |
foreach ($faces as $face) | |
{ | |
foreach ($face as $point) | |
{ | |
if ($point['x'] < $min_x) $min_x = $point['x']; | |
if ($point['x'] > $max_x) $max_x = $point['x']; | |
if ($point['z'] < $min_z) $min_z = $point['z']; | |
if ($point['z'] > $max_z) $max_z = $point['z']; | |
} | |
} | |
$diff_x = $max_x - $min_x; | |
$diff_z = $max_z - $min_z; | |
$scale = ($image_size-20)/max(array($diff_x, $diff_z)); | |
$min_x = $min_x*$scale; | |
$min_z = $min_z*$scale; | |
$max_x = $max_x*$scale; | |
$max_z = $max_z*$scale; | |
$diff_x = $max_x - $min_x; | |
$diff_z = $max_z - $min_z; | |
$x_adjustment = abs($min_x)+10+((($image_size-20)-$diff_x)/2); | |
$z_adjustment = abs($max_z)+10+((($image_size-20)-$diff_z)/2); | |
} | |
foreach ($faces as $face) | |
{ | |
$polygon = array(); | |
foreach ($face as $point) | |
{ | |
$x = $point['x']; | |
$z = $point['z']; | |
$x = $x*$scale; | |
$z = $z*$scale; | |
$x = ($x+$x_adjustment); | |
$z = ($z_adjustment-$z); | |
$polygon[] = $x; | |
$polygon[] = $z; | |
} | |
if (isset($box['fill']) && $box['fill'] === true) | |
{ | |
imagefilledpolygon($image, $polygon, 4, $orange); | |
} | |
else | |
{ | |
$color = $green; | |
if (isset($box['color'])) $color = $box['color']; | |
imagepolygon($image, $polygon, 4, $color); | |
} | |
} | |
} | |
imagepng($image, './image.png'); | |
imagedestroy($image); | |
return true; | |
} | |
// THE FIRST BOX SHOULD BE YOUR LARGEST. IF ANY ARE FILLED, PUT THOSE NEXT | |
$boxes = array(); | |
$boxes[] = array('start' => array(0, 0, 0), 'width' => 80, 'length' => 55, 'height' => 80); | |
$boxes[] = array('start' => array(40, 0, 0), 'width' => 15, 'length' => 40, 'height' => 80, 'fill' => true); | |
$boxes[] = array('start' => array(0, 0, 0), 'width' => 40, 'length' => 40, 'height' => 40); | |
$boxes[] = array('start' => array(0, 0, 40), 'width' => 30, 'length' => 20, 'height' => 40); | |
// THE FUNCTION ADDS A 20 PIXEL PADDING TO THE IMAGE SO THE TRUE SIZE IS 400 | |
draw_boxes('./image.png', 420, $boxes); | |
?> | |
<img src="image.png"> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment