linea21-externals
[ class tree: linea21-externals ] [ index: linea21-externals ] [ all elements ]

Source for file Math.class.php

Documentation is available at Math.class.php

  1. <?php
  2. /*
  3.  * This work is hereby released into the Public Domain.
  4.  * To view a copy of the public domain dedication,
  5.  * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
  6.  * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
  7.  *
  8.  */
  9.  
  10. require_once dirname(__FILE__)."/../Graph.class.php";
  11.  
  12. abstract class awShape {
  13.     
  14.     /**
  15.      * Is the shape hidden ?
  16.      *
  17.      * @var bool 
  18.      */
  19.     protected $hide = FALSE;
  20.     
  21.     /**
  22.      * Shape style
  23.      *
  24.      * @var int 
  25.      */
  26.     public $style;
  27.     
  28.     /**
  29.      * Shape thickness
  30.      *
  31.      * @var int 
  32.      */
  33.     public $thickness;
  34.     
  35.     /**
  36.      * Solid shape
  37.      *
  38.      * @var int 
  39.      */
  40.     const SOLID 1;
  41.     
  42.     /**
  43.      * Dotted shape
  44.      *
  45.      * @var int 
  46.      */
  47.     const DOTTED 2;
  48.     
  49.     /**
  50.      * Dashed shape
  51.      *
  52.      * @var int 
  53.      */
  54.     const DASHED 3;
  55.     
  56.     /**
  57.      * Change shape style
  58.      *
  59.      * @param int $style Line style
  60.      */
  61.     public function setStyle($style{
  62.         $this->style = (int)$style;
  63.     }
  64.     
  65.     /**
  66.      * Return shape style
  67.      *
  68.      * @return int 
  69.      */
  70.     public function getStyle({
  71.         return $this->style;
  72.     }
  73.     
  74.     /**
  75.      * Change shape thickness
  76.      *
  77.      * @param int $thickness Shape thickness in pixels
  78.      */
  79.     public function setThickness($thickness{
  80.         $this->thickness = (int)$thickness;
  81.     }
  82.     
  83.     /**
  84.      * Return shape thickness
  85.      *
  86.      * @return int 
  87.      */
  88.     public function getThickness({
  89.         return $this->thickness;
  90.     }
  91.     
  92.     /**
  93.      * Hide the shape
  94.      *
  95.      * @param bool $hide 
  96.      */
  97.     public function hide($hide{
  98.         $this->hide = (bool)$hide;
  99.     }
  100.     
  101.     /**
  102.      * Show the shape
  103.      *
  104.      * @param bool $shape 
  105.      */
  106.     public function show($shape{
  107.         $this->hide = (bool)!$shape;
  108.     }
  109.     
  110.     /**
  111.      * Is the line hidden ?
  112.      *
  113.      * @return bool 
  114.      */
  115.     public function isHidden({
  116.         return $this->hide;
  117.     }
  118.     
  119. }
  120.  
  121. registerClass('Shape'TRUE);
  122.  
  123. /**
  124.  * Describe a point
  125.  *
  126.  * @package linea21.externals
  127.  * @subpackage artichow
  128.  */
  129. class awPoint extends awShape {
  130.  
  131.     /**
  132.      * X coord
  133.      *
  134.      * @var float 
  135.      */
  136.     public $x;
  137.  
  138.     /**
  139.      * Y coord
  140.      *
  141.      * @var float 
  142.      */
  143.     public $y;
  144.     
  145.     /**
  146.      * Build a new awpoint
  147.      *
  148.      * @param float $x 
  149.      * @param float $y 
  150.      */
  151.     public function __construct($x$y{
  152.     
  153.         $this->setLocation($x$y);
  154.         
  155.     }
  156.     
  157.     /**
  158.      * Change X value
  159.      *
  160.      * @param float $x 
  161.      */
  162.     public function setX($x{
  163.         $this->x = (float)$x;
  164.     }
  165.     
  166.     /**
  167.      * Change Y value
  168.      *
  169.      * @param float $y 
  170.      */
  171.     public function setY($y{
  172.         $this->y = (float)$y;
  173.     }
  174.     
  175.     /**
  176.      * Change point location
  177.      *
  178.      * @param float $x 
  179.      * @param float $y 
  180.      */
  181.     public function setLocation($x$y{
  182.         $this->setX($x);
  183.         $this->setY($y);
  184.     }
  185.     
  186.     /**
  187.      * Get point location
  188.      *
  189.      * @param array Point location
  190.      */
  191.     public function getLocation({
  192.         return array($this->x$this->y);
  193.     }
  194.     
  195.     /**
  196.      * Get distance to another point
  197.      *
  198.      * @param awPoint $p A point
  199.      * @return float 
  200.      */
  201.     public function getDistance(awPoint $p{
  202.     
  203.         return sqrt(pow($p->$this->x2pow($p->$this->y2));
  204.     
  205.     }
  206.     
  207.     /**
  208.      * Move the point to another location
  209.      *
  210.      * @param Point A Point with the new awlocation
  211.      */
  212.     public function move($x$y{
  213.     
  214.         return new awPoint(
  215.             $this->x + $x,
  216.             $this->y + $y
  217.         );
  218.         
  219.     }
  220.  
  221. }
  222.  
  223. registerClass('Point');
  224.  
  225. /* <php4> */
  226.  
  227. define("LINE_SOLID"1);
  228. define("LINE_DOTTED"2);
  229. define("LINE_DASHED"3);
  230.  
  231. /* </php4> */
  232.  
  233. /**
  234.  * Describe a line
  235.  *
  236.  * @package linea21.externals
  237.  * @subpackage artichow
  238.  */
  239. class awLine extends awShape {
  240.  
  241.     /**
  242.      * Line first point
  243.      *
  244.      * @param Point 
  245.      */
  246.     public $p1;
  247.  
  248.     /**
  249.      * Line second point
  250.      *
  251.      * @param Point 
  252.      */
  253.     public $p2;
  254.     
  255.     /**
  256.      * The line slope (the m in y = mx + p)
  257.      * 
  258.      * @param float 
  259.      */
  260.     private $slope;
  261.     
  262.     /**
  263.      * The y-intercept value of the line (the p in y = mx + p)
  264.      * 
  265.      * @param float 
  266.      */
  267.     private $origin;
  268.     
  269.     /**
  270.      * Build a new awline
  271.      *
  272.      * @param awPoint $p1 First point
  273.      * @param awPoint $p2 Second point
  274.      * @param int $type Style of line (default to solid)
  275.      * @param int $thickness Line thickness (default to 1)
  276.      */
  277.     public function __construct($p1 NULL$p2 NULL$type awLine::SOLID$thickness 1{
  278.     
  279.         $this->setLocation($p1$p2);
  280.         $this->setStyle($type);
  281.         $this->setThickness($thickness);
  282.         
  283.     }
  284.     
  285.     /**
  286.      * Build a line from 4 coords
  287.      *
  288.      * @param int $x1 Left position
  289.      * @param int $y1 Top position
  290.      * @param int $x2 Right position
  291.      * @param int $y2 Bottom position
  292.      */
  293.     public static function build($x1$y1$x2$y2{
  294.     
  295.         return new awLine(
  296.             new awPoint($x1$y1),
  297.             new awPoint($x2$y2)
  298.         );
  299.     
  300.     }
  301.     
  302.     /**
  303.      * Change X values of the line
  304.      *
  305.      * @param int $x1 Begin value
  306.      * @param int $x2 End value
  307.      */
  308.     public function setX($x1$x2{
  309.         $this->p1->setX($x1);
  310.         $this->p2->setX($x2);
  311.         
  312.         // Resets slope and origin values so they are
  313.         // recalculated when and if needed.
  314.         $this->slope NULL;
  315.         $this->origin NULL;
  316.     }
  317.     
  318.     /**
  319.      * Change Y values of the line
  320.      *
  321.      * @param int $y1 Begin value
  322.      * @param int $y2 End value
  323.      */
  324.     public function setY($y1$y2{
  325.         $this->p1->setY($y1);
  326.         $this->p2->setY($y2);
  327.         
  328.         // Resets slope and origin values so they are
  329.         // recalculated when and if needed.
  330.         $this->slope NULL;
  331.         $this->origin NULL;
  332.     }
  333.     
  334.     /**
  335.      * Change line location
  336.      *
  337.      * @param awPoint $p1 First point
  338.      * @param awPoint $p2 Second point
  339.      */
  340.     public function setLocation($p1$p2{
  341.         if(is_null($p1or $p1 instanceof awPoint{
  342.             $this->p1 = $p1;
  343.         }
  344.         if(is_null($p2or $p2 instanceof awPoint{
  345.             $this->p2 = $p2;
  346.         }
  347.         
  348.         // Resets slope and origin values so they are
  349.         // recalculated when and if needed.
  350.         $this->slope NULL;
  351.         $this->origin NULL;
  352.     }
  353.     
  354.     /**
  355.      * Get line location
  356.      *
  357.      * @param array Line location
  358.      */
  359.     public function getLocation({
  360.         return array($this->p1$this->p2);
  361.     }
  362.     
  363.     /**
  364.      * Get the line size
  365.      *
  366.      * @return float 
  367.      */
  368.     public function getSize({
  369.     
  370.         $square pow($this->p2->$this->p1->x2pow($this->p2->$this->p1->y2);
  371.         return sqrt($square);
  372.     
  373.     }
  374.     
  375.     /**
  376.      * Calculate the line slope
  377.      * 
  378.      */
  379.     private function calculateSlope({
  380.         if($this->isHorizontal()) {
  381.             $this->slope 0;
  382.         else {
  383.             $slope ($this->p1->$this->p2->y($this->p1->$this->p2->x);
  384.             
  385.             $this->slope $slope;
  386.         }
  387.     }
  388.     
  389.     /**
  390.      * Calculate the y-intercept value of the line
  391.      * 
  392.      */
  393.     private function calculateOrigin({
  394.         if($this->isHorizontal()) {
  395.             $this->origin $this->p1->y// Or p2->y
  396.         else {
  397.             $y1 $this->p1->y;
  398.             $y2 $this->p2->y;
  399.             $x1 $this->p1->x;
  400.             $x2 $this->p2->x;
  401.             
  402.             $origin ($y2 $x1 $y1 $x2($x1 $x2);
  403.             
  404.             $this->origin $origin;
  405.         }
  406.     }
  407.     
  408.     /**
  409.      * Calculate the slope and y-intercept value of the line
  410.      * 
  411.      */
  412.     private function calculateEquation({
  413.         $this->calculateSlope();
  414.         $this->calculateOrigin();
  415.     }
  416.     
  417.     /**
  418.      * Get the line slope value
  419.      *
  420.      * @return float 
  421.      */
  422.     public function getSlope({
  423.         if($this->isVertical()) {
  424.             return NULL;
  425.         elseif($this->slope !== NULL{
  426.             return $this->slope;
  427.         else {
  428.             $this->calculateSlope();
  429.             return $this->slope;
  430.         }
  431.     }
  432.     
  433.     /**
  434.      * Get the line y-intercept value
  435.      * 
  436.      * @return float 
  437.      */
  438.     public function getOrigin({
  439.         if($this->isVertical()) {
  440.             return NULL;
  441.         elseif($this->origin !== NULL{
  442.             return $this->origin;
  443.         else {
  444.             $this->calculateOrigin();
  445.             return $this->origin;
  446.         }
  447.     }
  448.     
  449.     /**
  450.      * Get the line equation
  451.      * 
  452.      * @return array An array containing the slope and y-intercept value of the line
  453.      */
  454.     public function getEquation({
  455.         $slope    $this->getSlope();
  456.         $origin $this->getOrigin();
  457.         
  458.         return array($slope$origin);
  459.     }
  460.     
  461.     /**
  462.      * Return the x coordinate of a point on the line
  463.      * given its y coordinate.
  464.      *
  465.      * @param float $y The y coordinate of the Point
  466.      * @return float $x The corresponding x coordinate
  467.      */
  468.     public function getXFrom($y{
  469.         $x NULL;
  470.         
  471.         if($this->isVertical()) {
  472.             list($p$this->getLocation();
  473.             $x $p->x;
  474.         else {
  475.             list($slope$origin$this->getEquation();
  476.             
  477.             if($slope !== 0{
  478.                 $y = (float)$y;
  479.                 $x ($y $origin$slope;
  480.             }
  481.         }
  482.         
  483.         return $x;
  484.     }
  485.     
  486.     /**
  487.      * Return the y coordinate of a point on the line
  488.      * given its x coordinate.
  489.      *
  490.      * @param float $x The x coordinate of the Point
  491.      * @return float $y The corresponding y coordinate
  492.      */
  493.     public function getYFrom($x{
  494.         $y NULL;
  495.         
  496.         if($this->isHorizontal()) {
  497.             list($p$this->getLocation();
  498.             $y $p->y;
  499.         else {
  500.             list($slope$origin$this->getEquation();
  501.             
  502.             if($slope !== NULL{
  503.                 $x = (float)$x;
  504.                 $y $slope $x $origin;
  505.             }
  506.         }
  507.         
  508.         return $y;
  509.     }
  510.     
  511.     /**
  512.      * Test if the line can be considered as a point
  513.      *
  514.      * @return bool 
  515.      */
  516.     public function isPoint({
  517.         return ($this->p1->=== $this->p2->and $this->p1->=== $this->p2->y);
  518.     }
  519.     
  520.     /**
  521.      * Test if the line is a vertical line
  522.      *
  523.      * @return bool 
  524.      */
  525.     public function isVertical({
  526.         return ($this->p1->=== $this->p2->x);
  527.     }
  528.     
  529.     /**
  530.      * Test if the line is an horizontal line
  531.      *
  532.      * @return bool 
  533.      */
  534.     public function isHorizontal({
  535.         return ($this->p1->=== $this->p2->y);
  536.     }
  537.     
  538.     /**
  539.      * Returns TRUE if the line is going all the way from the top
  540.      * to the bottom of the polygon surrounding box.
  541.      * 
  542.      * @param $polygon Polygon A Polygon object
  543.      * @return bool 
  544.      */
  545.     public function isTopToBottom(awPolygon $polygon{
  546.         list($xMin$xMax$polygon->getBoxXRange();
  547.         list($yMin$yMax$polygon->getBoxYRange();
  548.         
  549.         if($this->isHorizontal()) {
  550.             return FALSE;
  551.         else {            
  552.             if($this->p1->$this->p2->y{
  553.                 $top $this->p1;
  554.                 $bottom $this->p2;
  555.             else {
  556.                 $top $this->p2;
  557.                 $bottom $this->p1;
  558.             }
  559.             
  560.             return (
  561.                 $this->isOnBoxTopSide($top$xMin$xMax$yMin)
  562.                 and
  563.                 $this->isOnBoxBottomSide($bottom$xMin$xMax$yMax)
  564.             );
  565.         }
  566.     }
  567.     
  568.     /**
  569.      * Returns TRUE if the line is going all the way from the left side
  570.      * to the right side of the polygon surrounding box.
  571.      * 
  572.      * @param $polygon Polygon A Polygon object
  573.      * @return bool 
  574.      */
  575.     public function isLeftToRight(awPolygon $polygon{
  576.         list($xMin$xMax$polygon->getBoxXRange();
  577.         list($yMin$yMax$polygon->getBoxYRange();
  578.         
  579.         if($this->isVertical()) {
  580.             return FALSE;
  581.         else {
  582.             if($this->p1->$this->p2->x{
  583.                 $left $this->p1;
  584.                 $right $this->p2;
  585.             else {
  586.                 $left $this->p2;
  587.                 $right $this->p1;
  588.             }
  589.         }
  590.         
  591.         return (
  592.             $this->isOnBoxLeftSide($left$yMin$yMax$xMin)
  593.             and
  594.             $this->isOnBoxRightSide($right$yMin$yMax$xMax)
  595.         );
  596.     }
  597.     
  598.     private function isOnBoxTopSide(awPoint $point$xMin$xMax$yMin{
  599.         if(
  600.             $point->=== $yMin
  601.             and 
  602.             $point->>= $xMin
  603.             and
  604.             $point-><= $xMax
  605.         {
  606.             return TRUE;
  607.         else {
  608.             return FALSE;
  609.         }
  610.     }
  611.  
  612.     private function isOnBoxBottomSide(awPoint $point$xMin$xMax$yMax{
  613.         if(
  614.             $point->=== $yMax
  615.             and
  616.             $point->>= $xMin
  617.             and
  618.             $point-><= $xMax
  619.         {
  620.             return TRUE;
  621.         else {
  622.             return FALSE;
  623.         }
  624.     }
  625.     
  626.     private function isOnBoxLeftSide(awPoint $point$yMin$yMax$xMin{
  627.         if(
  628.             $point->=== $xMin
  629.             and 
  630.             $point->>= $yMin
  631.             and 
  632.             $point-><= $yMax
  633.         {
  634.             return TRUE;
  635.         else {
  636.             return FALSE;
  637.         }
  638.     }
  639.     
  640.     private function isOnBoxRightSide(awPoint $point$yMin$yMax$xMax{
  641.         if(
  642.             $point->=== $xMax
  643.             and 
  644.             $point->>= $yMin
  645.             and 
  646.             $point-><= $yMax
  647.         {
  648.             return TRUE;
  649.         else {
  650.             return FALSE;
  651.         }
  652.     }
  653.     
  654. }
  655.  
  656. registerClass('Line');
  657.  
  658. /**
  659.  * A vector is a type of line
  660.  * The sense of the vector goes from $p1 to $p2.
  661.  *
  662.  * @package linea21.externals
  663.  * @subpackage artichow
  664.  */
  665. class awVector extends awLine {
  666.     
  667.     /**
  668.      * Get vector angle in radians
  669.      *
  670.      * @return float 
  671.      */
  672.     public function getAngle({
  673.     
  674.         if($this->isPoint()) {
  675.             return 0.0;
  676.         }
  677.         
  678.         $size $this->getSize();
  679.     
  680.         $width ($this->p2->$this->p1->x);
  681.         $height ($this->p2->$this->p1->y* -1;
  682.         
  683.         if($width >= and $height >= 0{
  684.             return acos($width $size);
  685.         else if($width <= and $height >= 0{
  686.             return acos($width $size);
  687.         else {
  688.             $height *= -1;
  689.             if($width >= and $height >= 0{
  690.                 return M_PI acos($width $size);
  691.             else if($width <= and $height >= 0{
  692.                 return M_PI acos($width $size);
  693.             }
  694.         }
  695.     
  696.     }
  697.  
  698. }
  699.  
  700. registerClass('Vector');
  701.  
  702. /* <php4> */
  703.  
  704. define("POLYGON_SOLID"1);
  705. define("POLYGON_DOTTED"2);
  706. define("POLYGON_DASHED"3);
  707.  
  708. /* </php4> */
  709.  
  710. /**
  711.  * Describe a polygon
  712.  *
  713.  * @package linea21.externals
  714.  * @subpackage artichow
  715.  */
  716. class awPolygon extends awShape {
  717.  
  718.     /**
  719.      * Polygon points
  720.      *
  721.      * @var array 
  722.      */
  723.     protected $points = array();
  724.  
  725.     /**
  726.      * Set a point in the polygon
  727.      *
  728.      * @param int $pos Point position
  729.      * @param awPoint $point 
  730.      */
  731.     public function set($pos$point{
  732.         if(is_null($pointor $point instanceof awPoint{
  733.             $this->points[$pos$point;
  734.         }
  735.     }
  736.     
  737.     /**
  738.      * Add a point at the end of the polygon
  739.      *
  740.      * @param awPoint $point 
  741.      */
  742.     public function append($point{
  743.         if(is_null($pointor $point instanceof awPoint{
  744.             $this->points[$point;
  745.         }
  746.     }
  747.     
  748.     /**
  749.      * Get a point at a position in the polygon
  750.      *
  751.      * @param int $pos Point position
  752.      * @return Point 
  753.      */
  754.     public function get($pos{
  755.         return $this->points[$pos];
  756.     }
  757.     
  758.     /**
  759.      * Count number of points in the polygon
  760.      *
  761.      * @return int 
  762.      */
  763.     public function count({
  764.         return count($this->points);
  765.     }
  766.     
  767.     /**
  768.      * Returns all points in the polygon
  769.      *
  770.      * @return array 
  771.      */
  772.     public function all({
  773.         return $this->points;
  774.     }
  775.     
  776.     /**
  777.      * Returns the different lines formed by the polygon vertices
  778.      * 
  779.      * @return array 
  780.      */
  781.     public function getLines({
  782.         $lines array();
  783.         $count $this->count();
  784.     
  785.         for($i 0$i $count 1$i++{
  786.             $lines[new Line($this->get($i)$this->get($i 1));
  787.         }
  788.         
  789.         // "Close" the polygon
  790.         $lines[new Line($this->get($count 1)$this->get(0));
  791.  
  792.         return $lines;
  793.     }
  794.     
  795.     /**
  796.      * Get the upper-left and lower-right points
  797.      * of the bounding box around the polygon
  798.      * 
  799.      * @return array An array of two Point objects
  800.      */
  801.     public function getBoxPoints({
  802.         $count $this->count();
  803.         $x $y array();
  804.         
  805.         for($i 0$i $count$i++{
  806.             $point $this->get($i);
  807.     
  808.             list($x[]$y[]$point->getLocation();
  809.         }
  810.         
  811.         $upperLeft  new Point(min($x)min($y));
  812.         $lowerRight new Point(max($x)max($y));
  813.         
  814.         return array($upperLeft$lowerRight);
  815.     }
  816.     
  817.     /**
  818.      * Return the range of the polygon on the y axis,
  819.      * i.e. the minimum and maximum y value of any point in the polygon
  820.      * 
  821.      * @return array 
  822.      */
  823.     public function getBoxYRange({
  824.         list($p1$p2$this->getBoxPoints();
  825.     
  826.         list($yMin$p1->getLocation();
  827.         list($yMax$p2->getLocation();
  828.         
  829.         return array($yMin$yMax);
  830.     }
  831.     
  832.     /**
  833.      * Return the range of the polygon on the x axis,
  834.      * i.e. the minimum and maximum x value of any point in the polygon
  835.      *
  836.      * @return array 
  837.      */
  838.     public function getBoxXRange({
  839.         list($p1$p2$this->getBoxPoints();
  840.     
  841.         list($xMin$p1->getLocation();
  842.         list($xMax$p2->getLocation();
  843.         
  844.         return array($xMin$xMax);
  845.     }
  846.  
  847. }
  848.  
  849. registerClass('Polygon');
  850. ?>

Documentation generated on Fri, 16 Oct 2009 09:36:18 +0200 by phpDocumentor 1.4.1