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 Thu, 03 May 2012 15:06:11 +0200 by phpDocumentor 1.4.1