Stock Ticker

<?php

/**
 * stock_ticker
 *
 * Generate an HTML stock ticker with current quotes.
 *
 * @version 3.2
 * @author Contributors at eXorithm
 * @link /algorithm/view/stock_ticker Listing at eXorithm
 * @link /algorithm/history/stock_ticker History at eXorithm
 * @license /home/show/license
 *
 * @param array $symbols stocks to go in the ticker
 * @param string $background_color (hex color code) color of the ticker background
 * @param string $stock_color (hex color code) color of the stock symbols
 * @param string $price_color (hex color code) color of the prices
 * @param string $up_color (hex color code) color of gains
 * @param string $down_color (hex color code) color of loses
 * @param number $speed speed of scrolling 
 * @return string HTML
 */
function stock_ticker($symbols=array(0=>'AAPL',1=>'GOOG',2=>'DOW',3=>'GCG13.CMX',4=>'P'),$background_color='dddddd',$stock_color='000000',$price_color='0000bb',$up_color='008000',$down_color='ff0000',$speed=6)
{
	sort($symbols);
	
	if ($background_color==$stock_color) {
		// something's wrong, colors weren't specified
		$background_color = invert_color($background_color);
	}
	
	$return = '<div align="center">
	<marquee bgcolor="#'.$background_color.'" loop="20" scrollamount="'.$speed.'">';
	
	foreach ($symbols as $symbol) {
		$data = file_get_contents("http://quote.yahoo.com/d/quotes.csv?s=$symbol&f=sl1d1t1c1ohgv&e=.csv");
		
		$values = explode(",", $data);
		$lasttrade = $values[1];
		$change = $values[4];
		
		$return .= "<span style=\"color:#$stock_color\">$symbol</span> &nbsp;";
		$return .= "<span style=\"color:#$price_color\">$lasttrade</span> &nbsp;";
		if ($change<0)
			$return .= "<span style=\"color:#$down_color\">$change</span> &nbsp;";
		else
			$return .= "<span style=\"color:#$up_color\">$change</span> &nbsp;";
		$return .= "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
	}
	
	$return .= '</marque>
	</div>';
	
	return $return;
}

/**
 * invert_color
 *
 * Invert a color.
 *
 * @version 0.1
 * @author Contributors at eXorithm
 * @link /algorithm/view/invert_color Listing at eXorithm
 * @link /algorithm/history/invert_color History at eXorithm
 * @license /home/show/license
 *
 * @param string $color (hex color code) 
 * @return string hex color code
 */
function invert_color($color='008080')
{
	$new = '';
	for ($i=0;$i<3;$i++){
		$c = 255 - hexdec(substr($color,(2*$i),2));
		$c = dechex($c);
		$new .= (strlen($c) < 2) ? '0'.$c : $c;
	}
	return $new;
}

?>

Draw Cube

<?php

/**
 * draw_cube
 *
 * Draw a 3d cube.
 *
 * @version 0.8
 * @author Contributors at eXorithm
 * @link /algorithm/view/draw_cube Listing at eXorithm
 * @link /algorithm/history/draw_cube History at eXorithm
 * @license /home/show/license
 *
 * @param number $image_size Size of the resulting image.
 * @param number $degree_x Degrees to rotate around the x axis.
 * @param number $degree_y Degrees to rotate around the y axis.
 * @param number $degree_z Degrees to rotate around the z axis.
 * @param number $vdist Distance to vanishing point.
 * @param number $dist Distance from origin. This number should not be less than 0 (or else you will be inside the cube!)
 * @param string $vertex_color (hex color code) Color of the vertices of the cube.
 * @param string $face_color (hex color code) Color of the face of the cube.
 * @param bool $wireframe Display as a wireframe (face color will be ignored).
 * @param bool $dashes Display "hidden" lines as dashes (only if wireframe is not selected).
 * @param bool $rainbow Instead of using the face color, draw each side a different color.
 * @return resource GD image
 */
function draw_cube($image_size=400,$degree_x=35,$degree_y=35,$degree_z=0,$vdist=800,$dist=100,$vertex_color='0000ff',$face_color='ff0000',$wireframe=false,$dashes=false,$rainbow=false)
{
	$degree_x = $degree_x % 360;
	$degree_y = $degree_y % 360;
	$degree_z = $degree_z % 360;
	
	// construct the cube polygons
	$size = 400; // the size is arbitrary
	
	$x1=$size/2;
	$x0=-($size/2);
	$y1=$size/2;
	$y0=-($size/2);
	$z1=$size/2;
	$z0=-($size/2);
	
	$sides = array();
	
	$sides[] = array($x0,$y0,$z0, $x0,$y0,$z1, $x0,$y1,$z1, $x0,$y1,$z0);
	$sides[] = array($x1,$y0,$z0, $x1,$y0,$z1, $x1,$y1,$z1, $x1,$y1,$z0);
	
	$sides[] = array($x0,$y0,$z0, $x0,$y0,$z1, $x1,$y0,$z1, $x1,$y0,$z0);
	$sides[] = array($x0,$y1,$z0, $x0,$y1,$z1, $x1,$y1,$z1, $x1,$y1,$z0);
	
	$sides[] = array($x0,$y0,$z0, $x0,$y1,$z0, $x1,$y1,$z0, $x1,$y0,$z0);
	$sides[] = array($x0,$y0,$z1, $x0,$y1,$z1, $x1,$y1,$z1, $x1,$y0,$z1);
	
	// project each of the 6 polygons that makes up the cube
	for ($i=0; $i<count($sides); $i++) {
		$points[] = project_polygon($sides[$i], $degree_x, $degree_y, $degree_z, 0, 0, 0, $vdist+($size/2), $dist+($size/2), true);
	}
	
	// scale the image somewhat
	$scale = $image_size/($size*1.8);
	
	if ($rainbow) {
		$face_color = array('ff0000', '00d000', 'ffff00', 'a000a0', '0000ff', 'FF8040');
	}
	
	return render_polygons($points, $vertex_color, $face_color, $wireframe, $dashes, $image_size, $scale);
}

/**
 * project_polygon
 *
 * Project a the points of a 3d polygon onto a flat 2d surface (the screen).
 *
 * @version 0.5
 * @author Contributors at eXorithm
 * @link /algorithm/view/project_polygon Listing at eXorithm
 * @link /algorithm/history/project_polygon History at eXorithm
 * @license /home/show/license
 *
 * @param array $points Points of the polygon, in the form x1, y1, z1, x2, y2, z2, etc.
 * @param number $degree_x Degrees to rotate around the x axis.
 * @param number $degree_y Degrees to rotate around the y axis.
 * @param number $degree_z Degrees to rotate around the z axis.
 * @param number $center_x Location to center the view on.
 * @param number $center_y Location to center the view on.
 * @param number $center_z Location to center the view on.
 * @param number $dist1 Distance from viewer to screen (distance to vanishing point).
 * @param number $dist2 Distance from screen to object.
 * @param bool $include_z Return the z (distance) parameter for each point as well.
 * @return mixed
 */
function project_polygon($points=array(0=>'-1',1=>'-1',2=>'0',3=>'-1',4=>'1',5=>'0',6=>'1',7=>'1',8=>'0',9=>'1',10=>'-1',11=>'0'),$degree_x=45,$degree_y=45,$degree_z=45,$center_x=0,$center_y=0,$center_z=0,$dist1=5,$dist2=2,$include_z=false)
{
	// check points
	if ((count($points)%3)!=0) {
		throw new Exception('The points must be a list like x1, y1, z1, x2, y2, z2, etc. The number of points therefore must be divisible by three.');
	}
	
	$degree_x = deg2rad($degree_x);
	$degree_y = deg2rad($degree_y);
	$degree_z = deg2rad($degree_z);
	
	$cosx = cos($degree_x);
	$sinx = sin($degree_x);
	$cosy = cos($degree_y);
	$siny = sin($degree_y);
	$cosz = cos($degree_z);
	$sinz = sin($degree_z);
	
	$array = array();
	
	for ($i=0;$i<count($points);$i=$i+3) {
		$x0 = $points[$i]-$center_x;
		$y0 = $points[$i+1]-$center_y;
		$z0 = $points[$i+2]-$center_z;
		
		$x1 = $cosy*($sinz*$y0 + $cosz*$x0) - $siny*$z0;
		$y1 = $sinx*($cosy*$z0 + $siny*($sinz*$y0 + $cosz*$x0)) + $cosx*($cosz*$y0 - $sinz*$x0);
		$z1 = $cosx*($cosy*$z0 + $siny*($sinz*$y0 + $cosz*$x0)) - $sinx*($cosz*$y0 - $sinz*$x0);
	
		$x2 = $x1*$dist1/($z1+$dist1+$dist2);
		$y2 = $y1*$dist1/($z1+$dist1+$dist2);
		$z2 = $z1*$dist1/($z1+$dist1+$dist2);
	
		$array[] = $x2;
		$array[] = $y2;
		if ($include_z) $array[] = $z2;
	}
	
	return $array;
}

/**
 * render_polygons
 *
 * Helper function to render polygons to the screen with a number of options.
 *
 * @version 0.5
 * @author Contributors at eXorithm
 * @link /algorithm/view/render_polygons Listing at eXorithm
 * @link /algorithm/history/render_polygons History at eXorithm
 * @license /home/show/license
 *
 * @param array $polygons Multi-dimensional array. Each element will be an array of points (x1, y1, z1, x2, y2, z2, etc).
 * @param string $vertex_color (hex color code) Color of the vertices of the polygons.
 * @param string $face_color (hex color code) Color of the faces of the polygons.
 * @param bool $wireframe Display as a wireframe (face color will be ignored).
 * @param bool $dashes Display "hidden" vertices as dashes (only if wireframe is not selected).
 * @param number $image_size Size of the resulting image.
 * @param number $scale Scale factor. Set to 0 to auto-scale (fill the image).
 * @return resource GD image
 */
function render_polygons($polygons=array(0=>array(0=>-100,1=>-100,2=>1,3=>0,4=>100,5=>1,6=>100,7=>-100,8=>1)),$vertex_color='000000',$face_color='ffd700',$wireframe=false,$dashes=false,$image_size=300,$scale=1)
{
	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; $i<count($polygons); $i++) {
			for ($j=0; $j<count($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; $i<count($polygons); $i++) {
		$max = $polygons[$i][2];
		for ($j=0; $j<count($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; $i<count($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; $i<count($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;
}

/**
 * image_create_alpha
 *
 * Helper function to create a new blank image with transparency.
 *
 * @version 0.1
 * @author Contributors at eXorithm
 * @link /algorithm/view/image_create_alpha Listing at eXorithm
 * @link /algorithm/history/image_create_alpha History at eXorithm
 * @license /home/show/license
 *
 * @param mixed $width 
 * @param mixed $height 
 * @return resource GD image
 */
function image_create_alpha($width='',$height='')
{
	// Create a normal image and apply required settings
	$img = imagecreatetruecolor($width, $height);
	imagealphablending($img, false);
	imagesavealpha($img, true);
	
	// Apply the transparent background
	$trans = imagecolorallocatealpha($img, 0, 0, 0, 127);
	for ($x = 0; $x < $width; $x++)
	{
		for ($y = 0; $y < $height; $y++)
		{
			imagesetpixel($img, $x, $y, $trans);
		}
	}
	
	return $img;
}

/**
 * allocate_color
 *
 * Helper function to allocate a color to an image. Color should be a 6-character hex string.
 *
 * @version 0.2
 * @author Contributors at eXorithm
 * @link /algorithm/view/allocate_color Listing at eXorithm
 * @link /algorithm/history/allocate_color History at eXorithm
 * @license /home/show/license
 *
 * @param resource $image (GD image) The image that will have the color allocated to it.
 * @param string $color (hex color code) The color to allocate to the image.
 * @param mixed $transparency The level of transparency from 0 to 127.
 * @return mixed
 */
function allocate_color($image=null,$color='268597',$transparency='0')
{
	if (preg_match('/[0-9ABCDEF]{6}/i', $color)==0) {
		throw new Exception("Invalid color code.");
	}
	if ($transparency<0 || $transparency>127) {
		throw new Exception("Invalid transparency.");
	}
	
	$r  = hexdec(substr($color, 0, 2));
	$g  = hexdec(substr($color, 2, 2));
	$b  = hexdec(substr($color, 4, 2));
	if ($transparency>127) $transparency = 127;
	
	if ($transparency<=0)
		return imagecolorallocate($image, $r, $g, $b);
	else
		return imagecolorallocatealpha($image, $r, $g, $b, $transparency);
}

?>

Round Corners

<?php

/**
 * round_corners
 *
 * Round the corners of an image. Transparency and anti-aliasing are supported.
 *
 * @version 0.2
 * @author Contributors at eXorithm
 * @link /algorithm/view/round_corners Listing at eXorithm
 * @link /algorithm/history/round_corners History at eXorithm
 * @license /home/show/license
 *
 * @param resource $image (GD image) 
 * @param number $radius Radius of the rounded corners.
 * @param string $color (hex color code) Color of the background.
 * @param mixed $transparency Level of transparency. 0 is no transparency, 127 is full transparency.
 * @return resource GD image
 */
function round_corners($image=null,$radius=20,$color='ffffff',$transparency='127')
{
	$width = imagesx($image);
	$height = imagesy($image);
	
	$image2 = imagecreatetruecolor($width, $height);
	
	imagesavealpha($image2, true);
	imagealphablending($image2, false);
	
	imagecopy($image2, $image, 0, 0, 0, 0, $width, $height);
	
	
	
	$full_color = allocate_color($image2, $color, $transparency);
	
	// loop 4 times, for each corner...
	for ($left=0;$left<=1;$left++) {
		for ($top=0;$top<=1;$top++) {
			
			$start_x = $left * ($width-$radius);
			$start_y = $top * ($height-$radius);
			$end_x = $start_x+$radius;
			$end_y = $start_y+$radius;
			
			$radius_origin_x = $left * ($start_x-1) + (!$left) * $end_x;
			$radius_origin_y = $top * ($start_y-1) + (!$top) * $end_y;
			
			for ($x=$start_x;$x<$end_x;$x++) {
				for ($y=$start_y;$y<$end_y;$y++) {
					$dist = sqrt(pow($x-$radius_origin_x,2)+pow($y-$radius_origin_y,2));
					
					if ($dist>($radius+1)) {
						imagesetpixel($image2, $x, $y, $full_color);
					} else {
						if ($dist>$radius) {
						  $pct = 1-($dist-$radius);
						  $color2 = antialias_pixel($image2, $x, $y, $full_color, $pct);
						  imagesetpixel($image2, $x, $y, $color2);
						}
					}
				}
			}
			
		}
	}
	
	return $image2;
}

/**
 * allocate_color
 *
 * Helper function to allocate a color to an image. Color should be a 6-character hex string.
 *
 * @version 0.2
 * @author Contributors at eXorithm
 * @link /algorithm/view/allocate_color Listing at eXorithm
 * @link /algorithm/history/allocate_color History at eXorithm
 * @license /home/show/license
 *
 * @param resource $image (GD image) The image that will have the color allocated to it.
 * @param string $color (hex color code) The color to allocate to the image.
 * @param mixed $transparency The level of transparency from 0 to 127.
 * @return mixed
 */
function allocate_color($image=null,$color='268597',$transparency='0')
{
	if (preg_match('/[0-9ABCDEF]{6}/i', $color)==0) {
		throw new Exception("Invalid color code.");
	}
	if ($transparency<0 || $transparency>127) {
		throw new Exception("Invalid transparency.");
	}
	
	$r  = hexdec(substr($color, 0, 2));
	$g  = hexdec(substr($color, 2, 2));
	$b  = hexdec(substr($color, 4, 2));
	if ($transparency>127) $transparency = 127;
	
	if ($transparency<=0)
		return imagecolorallocate($image, $r, $g, $b);
	else
		return imagecolorallocatealpha($image, $r, $g, $b, $transparency);
}

/**
 * antialias_pixel
 *
 * Helper function to apply a certain weight of a certain color to a pixel in an image. The index of the resulting color is returned. 
 *
 * @version 0.1
 * @author Contributors at eXorithm
 * @link /algorithm/view/antialias_pixel Listing at eXorithm
 * @link /algorithm/history/antialias_pixel History at eXorithm
 * @license /home/show/license
 *
 * @param resource $image (GD image) The image containing the pixel.
 * @param number $x X-axis position of the pixel.
 * @param number $y Y-axis position of the pixel.
 * @param number $color The index of the color to be applied to the pixel.
 * @param number $weight Should be between 0 and 1,  higher being more of the original pixel color, and 0.5 being an even mixture.
 * @return mixed
 */
function antialias_pixel($image=null,$x=0,$y=0,$color=0,$weight=0.5)
{
	$c = imagecolorsforindex($image, $color);
	$r1 = $c['red'];
	$g1 = $c['green'];
	$b1 = $c['blue'];
	$t1 = $c['alpha'];
	
	$color2 = imagecolorat($image, $x, $y);
	$c = imagecolorsforindex($image, $color2);
	$r2 = $c['red'];
	$g2 = $c['green'];
	$b2 = $c['blue'];
	$t2 = $c['alpha'];
	
	$cweight = $weight+($t1/127)*(1-$weight)-($t2/127)*(1-$weight);
	
	$r = round($r2*$cweight + $r1*(1-$cweight));
	$g = round($g2*$cweight + $g1*(1-$cweight));
	$b = round($b2*$cweight + $b1*(1-$cweight));
	
	$t = round($t2*$weight + $t1*(1-$weight));
	
	return imagecolorallocatealpha($image, $r, $g, $b, $t);
}

?>

Fibonacci Binet

<?php

/**
 * fibonacci_binet
 *
 * Simple example of Fibonacci series algorithm using Binet
 *
 * @version 0.3
 * @author Contributors at eXorithm
 * @link /algorithm/view/fibonacci_binet Listing at eXorithm
 * @link /algorithm/history/fibonacci_binet History at eXorithm
 * @license /home/show/license
 *
 * @param number $n 
 * @return mixed
 */
function fibonacci_binet($n=13)
{
	$phi = (1 + sqrt(5)) / 2;
	$u = (pow($phi, $n) - pow(1 - $phi, $n)) / sqrt(5);
	return $u;
}

?>