function degtorad ($degrees
{
  return ($degrees * (pi()/180.0));
}Â
Tag: Data
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 validate_domain
function validate_domain ($domain
{
  return preg_match ("/^[a-zA-Z0-9-.]+.(com|org|net|mil|edu)$/i", $domain);
}Â
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
}Â