eXorithm – Execute Algorithm: View / Run Algorithm render_polygons

Logo Beta

function render_polygons ($polygons$vertex_color$face_color$wireframe$dashes$image_size$scale
{
  foreach ($polygons as $polygon) {
    if (!is_array$polygon)) {
      throw new Exception'Each polygon must be a list.');
    } else if ((count$polygon)%3)!=0) {
      throw new Exception'Each polygon must be a list like x1, y1, z1, x2, y2, z2, etc. The number of points therefore must be divisible by three.');
    }
  }
  
  if (is_array$vertex_color)) {
    if (count$vertex_color) != count$polygons)) {
      throw new Exception'If vertex colors is an array, it must contain the same number of colors as the number of polygons.');
    }
  }
  
  if (is_array$face_color)) {
    if (count$face_color) != count$polygons)) {
      throw new Exception'If face colors is an array, it must contain the same number of colors as the number of polygons.');
    }
  }
  
  // if scale=0 then we auto-scale
  if ($scale==0) {
    $max = 0;
    for ($i=0; $icount$polygons); $i++) {
      for ($j=0; $jcount$polygons$i]); $j$j+3) {  
        if (abs$polygons$i][$j])>$max
          $max = abs$polygons$i][$j]);
        if (abs$polygons$i][$j+1])>$max
          $max = abs$polygons$i][$j+1]);
      }
    }
    if ($max>0)
      $scale = ($image_size-2)/($max*2);
  }
  
  // the polygon arrays (x,y,z) must be converted into shapes (x,y)
  $shapes = array();
  $z_max = array();
  
  for ($i=0; $icount$polygons); $i++) {
    $max = $polygons$i][2];
    for ($j=0; $jcount$polygons$i]); $j$j+3) {  
      $x = $polygons$i][$j];
      $y = $polygons$i][$j+1];
      
      // map each x,y coord to a screen position
      $x = round$image_size/2 + $x$scale);
      $y = round$image_size/2 - $y$scale);
      
      $shapes$i][$j] = $x
      $shapes$i][$j+1] = $y
      
      // keep track of the maximum z-value for each shape
      if ($polygons$i][$j+2]>$max
        $max = $polygons$i][$j+2];
    }
    $shapes$i] = array_values$shapes$i]);
    $z_max$i] = $max
  }
  
  // create a blank image
  $image = image_create_alpha$image_size$image_size);
  
  // create the colors
  if (!is_array$vertex_color))
    $vertex_color = array_fill(0, count$polygons), $vertex_color);
  if (!is_array$face_color))
    $face_color = array_fill(0, count$polygons), $face_color);
  
  // painter's algorithm - draw farther polygons first
  array_multisort$z_max, SORT_DESC, $shapes$face_color$vertex_color);
  
  // draw the polygons
  for ($i=0; $icount$shapes); $i++) {
    $v_color = allocate_color$image$vertex_color$i]);
    $f_color = allocate_color$image$face_color$i]);
    if (!$wireframe) {
      imagefilledpolygon$image$shapes$i], count$shapes$i])/2, $f_color);
    }
    imagepolygon$image$shapes$i], count$shapes$i])/2, $v_color);
  }
  
  // draw dashes - BUGGY
  if ($dashes) {
    for ($i=0; $icount$shapes); $i++) {
      $v_color = allocate_color$image$vertex_color$i]);
      $style = array$v_color, IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT, IMG_COLOR_TRANSPARENT);
      imagesetstyle$image$style);
      imagepolygon$image$shapes$i], count$shapes$i])/2, IMG_COLOR_STYLED);
    }
  }
  
  return $image