home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Image / Graph / Tool.php < prev   
Encoding:
PHP Script  |  2008-07-02  |  10.1 KB  |  291 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * Image_Graph - Main class for the graph creation.
  7.  *
  8.  * PHP versions 4 and 5
  9.  *
  10.  * LICENSE: This library is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU Lesser General Public License as published by
  12.  * the Free Software Foundation; either version 2.1 of the License, or (at your
  13.  * option) any later version. This library is distributed in the hope that it
  14.  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  15.  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
  16.  * General Public License for more details. You should have received a copy of
  17.  * the GNU Lesser General Public License along with this library; if not, write
  18.  * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  19.  * 02111-1307 USA
  20.  *
  21.  * @category   Images
  22.  * @package    Image_Graph
  23.  * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
  24.  * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  25.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  26.  * @version    CVS: $Id: Tool.php,v 1.4 2005/09/14 20:27:24 nosey Exp $
  27.  * @link       http://pear.php.net/package/Image_Graph
  28.  */
  29.  
  30. /**
  31.  * This class contains a set of tool-functions.
  32.  * 
  33.  * These functions are all to be called statically
  34.  *
  35.  * @category   Images
  36.  * @package    Image_Graph
  37.  * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
  38.  * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  39.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  40.  * @version    Release: 0.7.2
  41.  * @link       http://pear.php.net/package/Image_Graph
  42.  */
  43. class Image_Graph_Tool
  44. {
  45.  
  46.     /**
  47.      * Return the average of 2 points
  48.      *
  49.      * @param double P1 1st point
  50.      * @param double P2 2nd point
  51.      * @return double The average of P1 and P2
  52.      * @static
  53.      */
  54.     function mid($p1, $p2)
  55.     {
  56.         return ($p1 + $p2) / 2;
  57.     }
  58.  
  59.     /**
  60.      * Mirrors P1 in P2 by a amount of Factor
  61.      *
  62.      * @param double $p1 1st point, point to mirror
  63.      * @param double $o2 2nd point, mirror point
  64.      * @param double $factor Mirror factor, 0 returns $p2, 1 returns a pure
  65.      * mirror, ie $p1 on the exact other side of $p2
  66.      * @return double $p1 mirrored in $p2 by Factor
  67.      * @static
  68.      */
  69.     function mirror($p1, $p2, $factor = 1)
  70.     {
  71.         return $p2 + $factor * ($p2 - $p1);
  72.     }
  73.  
  74.     /**
  75.      * Calculates a Bezier control point, this function must be called for BOTH
  76.      * X and Y coordinates (will it work for 3D coordinates!?)
  77.      *
  78.      * @param double $p1 1st point
  79.      * @param double $p2 Point to
  80.      * @param double $factor Mirror factor, 0 returns P2, 1 returns a pure
  81.      *   mirror, i.e. P1 on the exact other side of P2
  82.      * @return double P1 mirrored in P2 by Factor
  83.      * @static
  84.      */
  85.     function controlPoint($p1, $p2, $factor, $smoothFactor = 0.75)
  86.     {
  87.         $sa = Image_Graph_Tool::mirror($p1, $p2, $smoothFactor);
  88.         $sb = Image_Graph_Tool::mid($p2, $sa);
  89.  
  90.         $m = Image_Graph_Tool::mid($p2, $factor);
  91.  
  92.         $pC = Image_Graph_Tool::mid($sb, $m);
  93.  
  94.         return $pC;
  95.     }
  96.  
  97.     /**
  98.      * Calculates a Bezier point, this function must be called for BOTH X and Y
  99.      * coordinates (will it work for 3D coordinates!?)
  100.      *
  101.      * @param double $t A position between $p2 and $p3, value between 0 and 1
  102.      * @param double $p1 Point to use for calculating control points
  103.      * @param double $p2 Point 1 to calculate bezier curve between
  104.      * @param double $p3 Point 2 to calculate bezier curve between
  105.      * @param double $p4 Point to use for calculating control points
  106.      * @return double The bezier value of the point t between $p2 and $p3 using
  107.      * $p1 and $p4 to calculate control points
  108.      * @static
  109.      */
  110.     function bezier($t, $p1, $p2, $p3, $p4)
  111.     {
  112.         // (1-t)^3*p1 + 3*(1-t)^2*t*p2 + 3*(1-t)*t^2*p3 + t^3*p4
  113.         return pow(1 - $t, 3) * $p1 +
  114.             3 * pow(1 - $t, 2) * $t * $p2 +
  115.             3 * (1 - $t) * pow($t, 2) * $p3 +
  116.             pow($t, 3) * $p4;
  117.     }
  118.     
  119.     /**
  120.      * For a given point (x,y) return a point rotated by a given angle aroung the center (xy,yc)
  121.      *
  122.      * @param int $x x coordinate of the point to rotate
  123.      * @param int $y y coordinate of the point to rotate
  124.      * @param int $xc x coordinate of the center of the rotation
  125.      * @param int $yc y coordinate of the center of the rotation
  126.      * @param int $angle angle of the rotation
  127.      * @return array the coordinate of the new point
  128.      * @static
  129.      */
  130.     function rotate($x, $y, $xc, $yc, $angle)
  131.     {
  132.         $cos = cos(deg2rad($angle));
  133.         $sin = sin(deg2rad($angle));
  134.         $xr= $x - $xc;
  135.         $yr= $y - $yc;
  136.         $x1= $xc + $cos * $xr - $sin * $yr;
  137.         $y1= $yc + $sin * $xr + $cos * $yr;
  138.         return array((int) $x1,(int) $y1);
  139.     }
  140.  
  141.     /**
  142.      * If a number is close 0 zero (i.e. 0 within $decimal decimals) it is rounded down to zero
  143.      * 
  144.      * @param double $value The value to round
  145.      * @param int $decimal The number of decimals
  146.      * @return double The value or zero if "close enough" to zero
  147.      * @static
  148.      */
  149.     function close2zero($value, $decimal)
  150.     {
  151.         if (abs($value) < pow(10, -$decimal)) {
  152.             return 0;
  153.         }
  154.         else {
  155.             return $value;
  156.         }
  157.     }
  158.     
  159.     /**
  160.      * Calculate the dimensions and center point (of gravity) for an arc
  161.      * 
  162.      * @param int $v1 The angle at which the arc starts
  163.      * @param int $v2 The angle at which the arc ends
  164.      * @return array An array with the dimensions in a fraction of a circle width radius 1 'rx', 'ry' and the
  165.      * center point of gravity ('cx', 'cy')
  166.      * @static
  167.      */
  168.     function calculateArcDimensionAndCenter($v1, $v2)
  169.     { 
  170.         // $v2 always larger than $v1
  171.         $r1x = Image_Graph_Tool::close2zero(cos(deg2rad($v1)), 3); 
  172.         $r2x = Image_Graph_Tool::close2zero(cos(deg2rad($v2)), 3);
  173.         
  174.         $r1y = Image_Graph_Tool::close2zero(sin(deg2rad($v1)), 3);
  175.         $r2y = Image_Graph_Tool::close2zero(sin(deg2rad($v2)), 3);
  176.     
  177.         // $rx = how many percent of the x-diameter of the entire ellipse does the arc x-diameter occupy: 1 entire width, 0 no width
  178.         // $cx = at what percentage of the diameter does the center lie
  179.         
  180.         // if the arc passes through 0/360 degrees the "highest" of r1x and r2x is replaced by 1!
  181.         if ((($v1 <= 0) && ($v2 >= 0)) || (($v1 <= 360) && ($v2 >= 360))) {
  182.             $r1x = min($r1x, $r2x);
  183.             $r2x = 1;
  184.         } 
  185.         
  186.         // if the arc passes through 180 degrees the "lowest" of r1x and r2x is replaced by -1!
  187.         if ((($v1 <= 180) && ($v2 >= 180)) || (($v1 <= 540) && ($v2 >= 540))) {
  188.             $r1x = max($r1x, $r2x);
  189.             $r2x = -1;
  190.         }
  191.         
  192.         if ($r1x >= 0) { // start between [270; 360] or [0; 90]        
  193.             if ($r2x >= 0) {
  194.                 $rx = max($r1x, $r2x) / 2;
  195.                 $cx = 0; // center lies 0 percent along this "vector"
  196.             }
  197.             else {
  198.                 $rx = abs($r1x - $r2x) / 2;
  199.                 $cx = abs($r2x / 2) / $rx;
  200.             }
  201.         }
  202.         else {  // start between ]90; 270[
  203.             if ($r2x < 0) {
  204.                 $rx = max(abs($r1x), abs($r2x)) / 2;
  205.                 $cx = $rx;
  206.             }
  207.             else {
  208.                 $rx = abs($r1x - $r2x) / 2;
  209.                 $cx = abs($r1x / 2) / $rx;
  210.             }
  211.         }
  212.         
  213.         // $ry = how many percent of the y-diameter of the entire ellipse does the arc y-diameter occupy: 1 entire, 0 none
  214.         // $cy = at what percentage of the y-diameter does the center lie
  215.     
  216.         // if the arc passes through 90 degrees the "lowest" of r1x and r2x is replaced by -1!
  217.         if ((($v1 <= 90) && ($v2 >= 90)) || (($v1 <= 450) && ($v2 >= 450))) {
  218.             $r1y = min($r1y, $r2y);
  219.             $r2y = 1;
  220.         }
  221.         
  222.         // if the arc passes through 270 degrees the "highest" of r1y and r2y is replaced by -1!
  223.         if ((($v1 <= 270) && ($v2 >= 270)) || (($v1 <= 630) && ($v2 >= 630))) {
  224.             $r1y = max($r1y, $r2y);
  225.             $r2y = -1;
  226.         } 
  227.             
  228.         if ($r1y >= 0) { // start between [0; 180]        
  229.             if ($r2y >= 0) {
  230.                 $ry = max($r1y, $r2y) / 2;
  231.                 $cy = 0; // center lies 0 percent along this "vector"
  232.             }
  233.             else {
  234.                 $ry = abs($r1y - $r2y) / 2;
  235.                 $cy = abs($r2y / 2) / $ry;
  236.             }
  237.         }
  238.         else {  // start between ]180; 360[
  239.             if ($r2y < 0) {
  240.                 $ry = max(abs($r1y), abs($r2y)) / 2;
  241.                 $cy = $ry;
  242.             }
  243.             else {
  244.                 $ry = abs($r1y - $r2y) / 2;
  245.                 $cy = abs($r1y / 2) / $ry;
  246.             }
  247.         }
  248.         
  249.         return array(
  250.             'rx' => $rx,
  251.             'cx' => $cx,
  252.             'ry' => $ry,
  253.             'cy' => $cy
  254.         );
  255.     }
  256.     
  257.     /**
  258.      * Calculate linear regression on a dataset
  259.      * @param array $data The data to calculate regression upon
  260.      * @return array The slope and intersection of the "best-fit" line
  261.      * @static
  262.      */    
  263.     function calculateLinearRegression(&$data)
  264.     {
  265.         $sumX = 0; 
  266.         $sumY = 0;
  267.         foreach ($data as $point) {
  268.             $sumX += $point['X'];
  269.             $sumY += $point['Y'];
  270.         }        
  271.         $meanX = $sumX / count($data);
  272.         $meanY = $sumY / count($data);
  273.  
  274.         $sumXX = 0;
  275.         $sumYY = 0;
  276.         $sumXY = 0;
  277.         foreach ($data as $point) {
  278.             $sumXX += ($point['X'] - $meanX) * ($point['X'] - $meanX);
  279.             $sumYY += ($point['Y'] - $meanY) * ($point['Y'] - $meanY);
  280.             $sumXY += ($point['X'] - $meanX) * ($point['Y'] - $meanY);
  281.         }        
  282.  
  283.         $result = array();
  284.         $result['slope'] = ($sumXY / $sumXX);
  285.         $result['intersection'] = $meanY - ($result['slope'] * $meanX);
  286.         return $result;
  287.     }
  288.     
  289. }
  290.  
  291. ?>