eXorithm – Execute Algorithm: View / Run Algorithm plot_function

function plot_function ($function, $variable, $range_start, $range_end, $width, $height, $pixels_per_plot, $color, $show_grid

{

  // fix the pixels/plot variable

  $pixels_per_plot = floor$pixels_per_plot);

  if ($pixels_per_plot<=0) $pixels_per_plot = 1;

  

  // calculate all our points

  $xy = array();

  for ($ii=0; $ii<($width$pixels_per_plot); $ii$ii$pixels_per_plot) {

    if ($ii>=$width) {

      $x = $range_start + ($range_end - $range_start);

    } else {

      $x = $range_start + $ii$width * ($range_end - $range_start);

    }

    $y = evaluate_for_x$function, $x);

    if (!is_nan$y)) {

      $xy[]=array$x$y);

    }

  }

  

  // find the min and max values of x

  for ($ii=0; $iicount$xy); $ii++) {

    if (is_finite$xy$ii][1])) {

      if ((isset$miny)) && (isset$maxy)))  {

        if ($xy$ii][1]<$miny) $miny = $xy$ii][1];

        if ($xy$ii][1]>$maxy) $maxy = $xy$ii][1];

      } else {

        $maxy = $xy$ii][1];

        $miny = $xy$ii][1];

      }

    }

  }

  if (!isset$maxy)) $maxy = 1;

  if (!isset$miny)) $miny = -1;

  

  // if height is not given, compute it automatically

  if ($height<=0) {

    $height = ceil(($maxy$miny)/($range_end$range_start)*$width);

    if ($height>2000) $height = 2000;

  }

  

  // create blank image

  $image = image_create_alpha$width, $height+1);

  

  // create the colors

  $r  = hexdecsubstr$color, 0, 2));

  $g  = hexdecsubstr$color, 2, 2));

  $b  = hexdecsubstr$color, 4, 2));

  $color = imagecolorallocate$image, $r, $g, $b);

  

  // determine the view port for the y axis (where on the y axis should we focus?)

  $bottom_y = ($maxy$miny)/2 - (($height$width)*($range_end$range_start)/2);

  $top_y = $bottom_y + (($height$width)*($range_end$range_start));

  

  // numbers to shift by so that the graph is focused on the right spot

  $shift_y = $bottom_y*-1;

  $shift_x = $range_start*-1;

  // factor to translate the plotted points to pixel locations

  $mult = $width/($range_end$range_start);

  

  // draw the graph lines

  if ($show_grid) {

    $graph_color = imagecolorallocate$image, 200, 200, 200);

    $minor_color = imagecolorallocate$image, 230, 230, 230);

  

    $line_every = 50/$mult; // lines approximately every 50 pixels

    $places = floorlog$line_every,10))*-1;

    $line_every = round$line_every/5, $places)*5; // try and make the graph lines appear at a nice divisible by 5 number

    if ($line_every==0) $line_every=1; // this shouldn't happen, but just in case don't want to divide by 0

    

    // vertical lines

    $vert_line = floor$range_start$line_every) * $line_every

    while ($vert_line<=$range_end) {

      imageline$image, round(($vert_line$shift_x)*$mult), 0, round(($vert_line$shift_x)*$mult), $height, $minor_color);

      imagestring$image, 1, round(($vert_line$shift_x)*$mult)+1, $height-10, "$vert_line", $graph_color);

      $vert_line = $vert_line$line_every

    }

  

    // horizontal lines

    $horiz_line = floor$bottom_y$line_every) * $line_every

    while ($horiz_line<=$top_y) {

      imageline$image, 0, $heightround(($horiz_line$shift_y)*$mult), $width, $heightround(($horiz_line$shift_y)*$mult), $minor_color);

      imagestring$image, 1, 5, $heightround(($horiz_line$shift_y)*$mult), "$horiz_line", $graph_color);

      $horiz_line = $horiz_line$line_every

    }

    

    // axis lines

    imageline$image, round$shift_x$mult), 0, round$shift_x$mult), $height, $graph_color);

    imageline$image, 0, $heightround$shift_y$mult), $width, $heightround$shift_y$mult), $graph_color);

  }

  

  // draw the line

  for ($ii=0; $iicount$xy)-1; $ii++) {

    

    // infinite number?

    if (is_infinite$xy$ii][1])) {

      if ($xy$ii][1]<0) $xy$ii][1]=$bottom_y-100000;

      else $xy$ii][1]=$top_y+100000;

    }

    

    // translate the plotted values to locations in the image

    $x1 = round(($xy$ii][0]+$shift_x)*$mult);

    $y1 = $heightround(($xy$ii][1]+$shift_y)*$mult);

    $x2 = round(($xy$ii+1][0]+$shift_x)*$mult);

    $y2 = $heightround(($xy$ii+1][1]+$shift_y)*$mult);

    

    // draw the line

    imageline$image, $x1, $y1, $x2, $y2, $color);

  }

  

  return $image

} 

eXorithm – Execute Algorithm: View / Run Algorithm word_counts

function word_counts ($text, $noise

{

  $words = preg_split'/[^A-Za-z]+/', strtolower$text));

  $counts = array();

  

  foreach ($words as $word) {

    if (strlen$word)>1) { // 1-letter words are ignored

      if (array_search$word, $noise)===false) { // noise word?

        if (array_key_exists$word, $counts)) {

          $counts$word] = $counts$word]+1;

        } else {

          $counts$word] = 1;

        }

      }

    }

  }

  

  return $counts

} 

eXorithm – Execute Algorithm: View / Run Algorithm point_in_polygon

function point_in_polygon ($point, $polygon_points

{

  // check points

  if ((count$polygon_points)%2)!=0) {

    throw new Exception'The points must be a list like x1, y1, x2, y2, etc. The number of points therefore must be divisible by two.');

  }

  

  // count the number of times a flat line originating from the point and moving right crosses

  // the edges of the polygon -- even number: outside polygon, odd number: inside polygon

  $ints = 0;

  

  $count = count$polygon_points);

  

  $x = $point[0];

  $y = $point[1];

  

  for ($i=2;$i<=$count$i$i+2) {

    $vertex1x = $polygon_points$i-2]; 

    $vertex1y = $polygon_points$i-1]; 

    $vertex2x = $polygon_points$i % count$polygon_points)];

    $vertex2y = $polygon_points[($i+1) % count$polygon_points)];

    // boundary condition: if the point is one of the vertices then we are inside

    if (($x == $vertex1x) && ($y == $vertex1y)) {

      return true;

    }

    if ($vertex1y == $vertex2y) { // horizontal edge

      // boundary condition: if point is on a horizontal polygon edge then we are inside

      if (($vertex1y == $y) && ($x > min$vertex1x, $vertex2x)) && ($x < max$vertex1x, $vertex2x))) {

        return true;

      }

    } else {

      if (($y > min$vertex1y, $vertex2y)) && ($y <= max$vertex1y, $vertex2y)) && ($x <= max$vertex1x, $vertex2x))) { 

        $xinters = ($y - $vertex1y) * ($vertex2x - $vertex1x) / ($vertex2y - $vertex1y) + $vertex1x; 

        // boundary condition: if point is on the polygon edge then we are inside

        if ($x == $xinters) {

          return true;

        }

        if ($x < $xinters) { 

          $ints++; 

        }

      } 

    } 

  }

  

  // if line crosses edges even number of times, then we are outside polygon

  if (($ints % 2) == 0) {

    return false;

  } else {

    return true;

  }

} 

eXorithm – Execute Algorithm: View / Run Algorithm surface_oblate_spheroid

function surface_oblate_spheroid ($polar_radius$equatorial_radius

{

  $x = acos( $polar_radius / $equatorial_radius );

  $e2 = $equatorial_radius * $equatorial_radius

  $p2 = $polar_radius * $polar_radius

  $abx = $polar_radius * $equatorial_radius * $x

  $area = 2 * pi() * ( ($e2) + ($p2 / sin$x)) * log((1+sin$x))/cos$x)) );

  return $area

} 

eXorithm – Execute Algorithm: View / Run Algorithm constrain_image

function constrain_image ($image, $width, $height, $mode, $border_color, $transparent_border, $never_scale_up

{

  if (!$image

    throw new Exception'Invalid image');

  

  $iwidth = imagesx$image);

  $iheight = imagesy$image);

  

  if ($never_scale_up) {

    if ($width$iwidth && $height$iheight) {

      $mode = 'crop'

    }

    if ($width$iwidth || $height$iheight) {

      if (($mode=='scale') || ($mode=='scale_crop'))

        $mode = 'crop'

    }

  }

  

  // scaling phase

  switch ($mode) {

  

    case 'scale_crop': // scale and crop

      if ($width$iwidth > $height$iheight) {

        $iheight = round$iheight$width$iwidth);

        $iwidth =  $width

      } else {

        $iwidth =  round$iwidth$height$iheight);

        $iheight = $height

      }

      $image2 = image_create_alpha$iwidth, $iheight);

      imagecopyresampled$image2, $image, 0, 0, 0, 0, $iwidth, $iheight, imagesx$image), imagesy$image));

      break

     

    case 'scale_border': // scale and add borders

      if ($width$iwidth < $height$iheight) {

        $iheight = round$iheight$width$iwidth);

        $iwidth =  $width

      } else {

        $iwidth =  round$iwidth$height$iheight);

        $iheight = $height

      }

      $image2 = image_create_alpha$iwidth, $iheight);

      imagecopyresampled$image2, $image, 0, 0, 0, 0, $iwidth, $iheight, imagesx$image), imagesy$image));

      break

      

    case 'scale': // scale

      $image2 = image_create_alpha$width, $height);

      imagecopyresampled$image2, $image, 0, 0, 0, 0, $width, $height, imagesx$image), imagesy$image));

      break

  

    default

      $image2 = $image

  }

  

  // crop / borders phase

  switch ($mode) {

    case 'crop': 

    case 'scale_crop': 

    case 'scale_border': 

      

      $image3 = image_create_alpha$width, $height);

      

      $r  = hexdecsubstr$border_color, 0, 2));

      $g  = hexdecsubstr$border_color, 2, 2));

      $b  = hexdecsubstr$border_color, 4, 2));

      if ($transparent_border

        $border_color = imagecolorallocatealpha$image3, $r, $g, $b, 127);

      else

        $border_color = imagecolorallocatealpha$image3, $r, $g, $b, 0);

      imagefilledrectangle$image3, 0, 0, $width, $height, $border_color);

      

      // x,y to paste to

      $px = ($iwidth$width)   ? round(($width - $iwidth)/2) : 0;

      $py = ($iheight$height) ? round(($height - $iheight)/2) : 0;

      // x,y to start cut from

      $sx = ($iwidth$width)   ? 0 : round(($iwidth - $width)/2);

      $sy = ($iheight$height) ? 0 : round(($iheight - $height)/2);

      // x,y to end cut at

      $ex = ($iwidth$width)   ? $iwidth : $sx$width

      $ey = ($iheight$height) ? $iheight : $sy$height

      imagecopy$image3, $image2, $px, $py, $sx, $sy, $ex, $ey);

      break

      

    default

      $image3 = $image2

  }

  

  return $image3

} 

eXorithm – Execute Algorithm: View / Run Algorithm merge_sort

function merge_sort ($array

{

  if (count$array) <= 1)  

    return $array;  

  

  // sort each half

  $mid = floorcount$array)/2);

  $left = merge_sortarray_slice$array, 0, $mid));  

  $right = merge_sortarray_slice$array, $mid));  

  

  // merge the arrays

  $array = array();

  while (count$left)>0 && count$right)>0) {  

    if ($left[0] <= $right[0]) {  

      array_push$array, array_shift$left));  

    } else {  

      array_push$array, array_shift$right));  

    }  

  }  

  $array = array_merge$array, $left, $right);  

  

  return $array

} 

eXorithm – Execute Algorithm: View / Run Algorithm triangulate

function triangulate ($side1, $side2, $side3, $angle1, $angle2, $angle3, $radians

{

  $sides = array();

  $angles = array();

  

  // get sides

  if ($side1!='') $sides[1] = $side1+0;

  if ($side2!='') $sides[2] = $side2+0;

  if ($side3!='') $sides[3] = $side3+0;

  

  // get angles

  if ($angle1!='') $angles[1] = $angle1+0;

  if ($angle2!='') $angles[2] = $angle2+0;

  if ($angle3!='') $angles[3] = $angle3+0;

  

  // convert to radians if necessary

  if (!$radians) {

    foreach ($angles as $angle => $value) {

      $angles$angle] = deg2rad$value);

    }

  }

  

  // need 3 values and at least one side

  if (((count$sides)+count$angles))!=3) || (count$sides)==0)) {

    throw new Exception"You must only provide 3 values for the sides and angles. At least one value must be a side. Leave the other three values blank.");

  }

  

  // iterate three times to make sure that we get everything

  for ($count=0;$count<3;$count++) {

    // for the three sides/angles

    for ($i1=1;$i1<=3;$i1++) {

      $i2 = ($i1 % 3)+1; // the other side/angle

      $i3 = (($i1+1) % 3)+1; // the other other side/angle

      if (!isset$angles$i1])) {

        // try $angle1 = 180 - $angle2 - $angle3

        if ((isset$angles$i2])) && (isset$angles$i3]))) {

          $angles$i1] = pi() - $angles$i2] - $angles$i3];

        }

      }

      if (!isset$sides$i1])) {

        if (isset$angles$i1])) {

          // try $side1 = $side2 * (sin($angle1)/sin($angle2))

          if ((isset$sides$i2])) && (isset$angles$i2]))) {

            $sides$i1] = $sides$i2] * sin$angles$i1]) / sin$angles$i2]);

          }

          // try $side1 = $side3 * (sin($angle1)/sin($angle3))

          if ((isset$sides$i3])) && (isset$angles$i3]))) {

            $sides$i1] = $sides$i3] * sin$angles$i1]) / sin$angles$i3]);

          }

        }

      }

      if (!isset$angles$i1])) {

        if (isset$sides$i1])) {

          // try $angle1 = arcsin(sin($angle2) * $side1/$side2)

          if ((isset$sides$i2])) && (isset$angles$i2]))) {

            $angles$i1] = asinsin$angles$i2]) * $sides$i1] / $sides$i2]);

          }

          // try $angle1 = arcsin(sin($angle3) * $side1/$side3)

          if ((isset$sides$i3])) && (isset$angles$i3]))) {

            $angles$i1] = asinsin$angles$i3]) * $sides$i1] / $sides$i3]);

          }

        }

      }

      if (!isset$sides$i1])) {

        // try $side1 = sqrt($side2^2 + $side3^2 - 2*$side2*$side3*cos($angle1))

        if ((isset$sides$i2])) && (isset$sides$i3])) && (isset$angles$i1]))) {

          $sides$i1] = sqrt$sides$i2]*$sides$i2] + $sides$i3]*$sides$i3] - 2 * $sides$i2] * $sides$i3] * cos$angles$i1]));

        }

      }

      if (!isset$angles$i1])) {

        // try $angle1 = arccos($side2^2 + $side3^2 - $side1^2 / 2*$side2*$side3))

        if ((isset$sides$i2])) && (isset$sides$i3])) && (isset$sides$i1]))) {

          $angles$i1] = acos(($sides$i2]*$sides$i2] + $sides$i3]*$sides$i3] - $sides$i1]*$sides$i1]) / (2 * $sides$i2] * $sides$i3]));

        }

      }

    }

    // were we able to calculate everything?

    if ((count$sides)+count$angles))==6) break

  }

  

  // bad values?

  foreach ($angles as $value) {

    if (is_nan$value) || is_infinite$value) || ($value<=0)) {

      throw new Exception"A triangle cannot be constructed with those values.");

    }

  }

  

  ksort$sides);ksort$angles);

  

  // convert to degrees if necessary

  if (!$radians) {

    foreach ($angles as $angle => $value) {

      $angles$angle] = rad2deg$value);

    }

  }

  

  return (array'sides'=>$sides, 'angles'=>$angles));

} 

eXorithm – Execute Algorithm: View / Run Algorithm swirl_image

function swirl_image ($image, $iterations, $angle

{

  $height = imagesy$image);

  $width = imagesx$image);

  

  $new_image = imagecreatetruecolor$width, $height);

  $iterations = max(1, $iterations);

  

  $wstep = ($width/2)/($iterations+1);

  $hstep = ($height/2)/($iterations+1);

  

  for ($ii=0;$ii$iterations$ii++) {

    $w = $width - ($ii+1)*$wstep*2;

    $h = $height - ($ii+1)*$hstep*2;

    $images$ii] = imagecreatetruecolor$w, $h);

    imagecopy$images$ii], $image, 0, 0, ($ii+1)*$wstep, ($ii+1)*$hstep, $w, $h);

    $images$ii] = rotate_image_alpha$images$ii], $angle*($ii+1), 'ffffff', 127);

  }

  

  for ($ii=0;$ii$iterations$ii++) {

    // Set the brush

    imagesetbrush$image, $images$ii]);

    // Draw a couple of brushes, each overlaying each

    imageline$image, imagesx$image) / 2, imagesy$image) / 2, imagesx$image) / 2, imagesy$image) / 2, IMG_COLOR_BRUSHED);

  }

  

  return $image

}