TeeChartPHP
[ class tree: TeeChartPHP ] [ index: TeeChartPHP ] [ all elements ]

Source for file Spline.php

Documentation is available at Spline.php

  1. <?php
  2.  
  3. /**
  4.  *
  5.  * <p>Title: Spline class</p>
  6.  *
  7.  * <p>Description: Spline smoothing.</p>
  8.  *
  9.  * <p>Copyright (c) 2005-2008 by Steema Software SL. All Rights
  10.  * Reserved.</p>
  11.  *
  12.  * <p>Company: Steema Software SL</p>
  13.  *
  14.  */
  15.  
  16. class Spline {
  17.  
  18.     private $build;
  19.     private $capacity;
  20.     private $interpolate;
  21.     private $pointList=Array();
  22.     private $knuckleList=Array();
  23.     private $vertexList=Array();
  24.     private $matrix=Array();
  25.     private $fragments=100;
  26.     private $noPoints=0;
  27.     private $noVertices;
  28.  
  29.     /**
  30.      * Spline smoothing.
  31.      */
  32.     public function Spline({}
  33.  
  34.     /**
  35.      * Indicates the spline has already calculated smooth points. <br>
  36.      * Set to false to force the spline to rebuild smooth points.<br>
  37.      *
  38.      * @return boolean 
  39.      */
  40.     public function getBuild({
  41.         return $this->build;
  42.     }
  43.  
  44.     /**
  45.      * Indicates the spline has already calculated smooth points. <br>
  46.      * Set to false to force the spline to rebuild smooth points.<br>
  47.      *
  48.      * @param value boolean
  49.      */
  50.     public function setBuild($value{
  51.         if (!$value{
  52.             // Release allocated memory for vertices
  53.             if ($this->build{
  54.                 $this->clearVertexList();
  55.             }
  56.             $this->noVertices 0;
  57.         }
  58.         $this->build $value;
  59.     }
  60.  
  61.     private function setCapacity($value{
  62.  
  63.         if ($value != $this->capacity{
  64.             $currentSize $this->capacity;
  65.             $oldPoints[$this->pointList;
  66.             $oldKnuckle[$this->knuckleList;
  67.             $this->pointList null;
  68.             $this->knuckleList null;
  69.  
  70.             if ($value 0{
  71.                 $this->pointList[$value;
  72.                 $this->knuckleList[$value;
  73.  
  74.                 if ($this->capacity != 0{
  75.                     $this->pointList=Utils::array_copy($oldPoints);
  76.                     $this->knuckleList=Utils::array_copy($oldKnuckle);                    
  77.                 }
  78.             }
  79.  
  80.             if ($currentSize != 0{
  81.                 $oldPoints null;
  82.                 $oldKnuckle null;
  83.             }
  84.  
  85.             $this->capacity $value;
  86.         }
  87.     }
  88.  
  89.     /**
  90.      * The number of resulting smooth points.<br>
  91.      * Must be a multiple of source points.
  92.      *
  93.      * @return int 
  94.      */
  95.     public function getFragments({
  96.         return $this->fragments;
  97.     }
  98.  
  99.     /**
  100.      * Sets the number of resulting smooth points.<br>
  101.      * Must be a multiple of source points.
  102.      *
  103.      * @param value int
  104.      */
  105.     public function setFragments($value{
  106.         if ($this->fragments != $value{
  107.             $this->fragments min($value600);
  108.         }
  109.     }
  110.  
  111.     /**
  112.      * When true, the spline calculates interpolated points that will pass
  113.      * exactly over source points.<br>
  114.      * When false, the spline resulting points do not necessarily pass over
  115.      * source points. <br>
  116.      * Default value: false
  117.      *
  118.      * @return boolean 
  119.      */
  120.     public function getInterpolated({
  121.         return $this->interpolate;
  122.     }
  123.  
  124.     /**
  125.      * When true, the spline calculates interpolated points that will pass
  126.      * exactly over source points.<br>
  127.      * When false, the spline resulting points do not necessarily pass over
  128.      * source points. <br>
  129.      * Default value: false
  130.      *
  131.      * @param value boolean
  132.      */
  133.     public function setInterpolated($value{
  134.         if ($value != $this->interpolate{
  135.             $this->interpolate $value;
  136.             $this->setBuild(false);
  137.         }
  138.     }
  139.  
  140.     public function getPoint($index{
  141.         return $this->pointList[$index];
  142.     }
  143.     /**
  144.      * Use to set the source point for the Knuckle <br><br>
  145.      *
  146.      * @param index int
  147.      * @param value Double
  148.      */
  149.     public function setPoint($index$value{
  150.         $this->pointList[$index$value;
  151.         $this->setBuild(false);
  152.     }
  153.     /**
  154.      * Makes the Index source point a control point. <br><br>
  155.      * By default, TSmoothingFunction does not set any source point <br>
  156.      * as a control point.
  157.      *
  158.      * @param index int
  159.      * @return Double 
  160.      */
  161.     private function getKnuckle($index{
  162.         if (($index == 0|| ($index == $this->noPoints 1)) {
  163.             return false;
  164.         else {
  165.             return $this->knuckleList[$index];
  166.         }
  167.     }
  168.     /**
  169.      * Makes the Index source point a control point. <br><br>
  170.      * By default, TSmoothingFunction does not set any source point <br>
  171.      * as a control point.
  172.      *
  173.      * @param index int
  174.      * @param value boolean
  175.      */
  176.     public function setKnuckle($index$value{
  177.         $this->knuckleList[$index$value;
  178.         $this->setBuild(false);
  179.     }
  180.  
  181.     /**
  182.      * Returns the number of total source points. <br>
  183.      * For each point that is a control point ( Knuckle[ Index ] is true ),
  184.      * the number of vertices is incremented by 2. <br>
  185.      *
  186.      * @return int 
  187.      */
  188.     public function numberOfVertices({
  189.         if (!$this->build{
  190.             $this->rebuild();
  191.         }
  192.         return $this->noVertices;
  193.     }
  194.  
  195.     static $MINLIMIT 1e-5;
  196.  
  197.     private function fillMatrix({
  198.         if (($this->noVertices 2&& ($this->noVertices <= 250)) {
  199.  
  200.             for ($i 2$i $this->noVertices$i++{
  201.                 $this->matrix[$i][$i 16;
  202.                 $this->matrix[$i][$i3;
  203.                 $this->matrix[$i][$i 16;
  204. //                $this->matrix[$i][$i - 1] = 1f / 6f;
  205. //                $this->matrix[$i][$i] = 2f / 3f;
  206. //                $this->matrix[$i][$i + 1] = 1f / 6f;
  207.             }
  208.  
  209.             $this->matrix[1][11;
  210.             $this->matrix[$this->noVertices][$this->noVertices1;
  211.  
  212.             $i 3;
  213.             while ($i $this->noVertices 1{
  214.                 if ((abs($this->vertexList[$i]->-
  215.                     $this->vertexList[$i 1]->xself::$MINLIMIT&&
  216.                     (abs($this->vertexList[$i 1]->$this->vertexList[$i]->x<
  217.                      self::$MINLIMIT&&
  218.                     (abs($this->vertexList[$i]->$this->vertexList[$i 1]->y<
  219.                      self::$MINLIMIT&&
  220.                     (abs($this->vertexList[$i 1]->$this->vertexList[$i]->y<
  221.                      self::$MINLIMIT)) {
  222.                     for ($j $i 1$j <= $i 1$j++{
  223.                         $this->matrix[$j][$j 10;
  224.                         $this->matrix[$j][$j1;
  225.                         $this->matrix[$j][$j 10;
  226.                     }
  227.  
  228.                     $i += 2;
  229.                 else {
  230.                     $i++;
  231.                 }
  232.             }
  233.         }
  234.     }
  235.  
  236.     /**
  237.      * Calculates new smoothed points from list of points.
  238.      */
  239.     public function rebuild({
  240.  
  241.         if ($this->noPoints 1{
  242.             $this->clearVertexList();
  243.             $this->noVertices 0;
  244.  
  245.             for ($i 0$i $this->noPoints$i++{
  246.                 if ($this->getKnuckle($i)) {
  247.                     $this->noVertices += 3;
  248.                 else {
  249.                     $this->noVertices++;
  250.                 }
  251.             }                           
  252.             $this->vertexList=Array();
  253.             //$this->vertexList[] = new TeePoint();
  254. //            $this->vertexList = new TeePoint[$this->noVertices + 2];
  255.  
  256.             $j 0;
  257.             for ($i 0$i $this->noPoints$i++{
  258.                 $vertex2D $this->getPoint($i);
  259.                 if ($this->getKnuckle($i)) {
  260.                     $this->vertexList[$j 1$vertex2D;
  261.                     $this->vertexList[$j 2$vertex2D;
  262.                     $j += 2;
  263.                 }
  264.                 $this->vertexList[$j 1$this->pointList[$i];
  265.                 $j++;
  266.             }
  267.  
  268.             if ($this->interpolate{
  269. //                $matrix = new double[noVertices + 1][];
  270.                 $this->matrix Array();
  271.                 for ($i 1$i <= $this->noVertices$i++{
  272.                     $this->matrix[$iArray();
  273.                     for ($tt=0;$tt<$this->noVertices+1;$tt++)
  274.                        $this->matrix[$i][$tt]=0.0;
  275. //                    $this->matrix[$i] = new double[noVertices + 1];
  276.                 }
  277.  
  278.                 $this->fillMatrix();
  279.                 $this->doInterpolate();
  280.                 $this->matrix null;
  281.             }      
  282.         }
  283.         $this->build true;
  284.         $this->phantomPoints();
  285.     }
  286.  
  287.     private function doInterpolate({
  288.         if (($this->noVertices 250&& ($this->noVertices 2)) {
  289.             $tmp Array();
  290.             for ($tt=0;$tt<$this->noVertices+2;$tt++)
  291.                  $tmp[$tt]=new TeePoint(0,0);
  292. //            Point.Double[] tmp = new Point.Double[noVertices + 2];
  293.  
  294.             for ($i 1$i <= $this->noVertices$i++{
  295.                 for ($j $i 1$j <= $this->noVertices$j++{
  296.                     $factor $this->matrix[$j][$i$this->matrix[$i][$i];
  297.                     for ($k 1$k <= $this->noVertices$k++{
  298.                         $this->matrix[$j][$k$this->matrix[$j][$k$factor $this->matrix[$i][$k];
  299.                     }
  300.  
  301.                     $this->vertexList[$j]->= (float) ($this->vertexList[$j]->-
  302.                                                $factor $this->vertexList[$j 1]->x);
  303.                     $this->vertexList[$j]->= (float) ($this->vertexList[$j]->-
  304.                                                $factor $this->vertexList[$j 1]->y);
  305.                 }
  306.             }
  307.  
  308.             $tmp[$this->noVerticesnew TeePoint(
  309.                     (float) ($this->vertexList[$this->noVertices]->/
  310.                              $this->matrix[$this->noVertices][$this->noVertices]),
  311.                     (float) ($this->vertexList[$this->noVertices]->/
  312.                              $this->matrix[$this->noVertices][$this->noVertices]));
  313.  
  314.             for ($i $this->noVertices 1$i >= 1$i--{
  315.                 $tmp[$inew TeePoint(
  316.                         (float) (($this->matrix[$i][$i]*
  317.                                  ($this->vertexList[$i]->$this->matrix[$i][$i +
  318.                                   1$tmp[$i 1]->x)),
  319.                         (float) (($this->matrix[$i][$i]*
  320.                                  ($this->vertexList[$i]->$this->matrix[$i][$i +
  321.                                   1$tmp[$i 1]->y)));
  322.             }
  323.  
  324.             $this->clearVertexList();
  325.             $this->vertexList $tmp;
  326.         }
  327.     }
  328.  
  329.     /**
  330.      * Adds a new source point with specified X and Y values.
  331.      *
  332.      * @param double
  333.      * @param double
  334.      */
  335.     public function addPoint($x$y{
  336.         if ($this->noPoints == $this->capacity{
  337.             $this->setCapacity($this->capacity 25);
  338.         }
  339.         $this->setPoint($this->noPointsnew TeePoint($x$y));
  340.         $this->noPoints++;
  341.         $this->setBuild(false);
  342.     }
  343.  
  344.     private function clearVertexList({
  345.         $this->vertexList null;
  346.     }
  347.  
  348.     /**
  349.      * Removes all source points.
  350.      */
  351.     public function clear({
  352.         if ($this->numberOfVertices(0{
  353.             $this->clearVertexList();
  354.         }
  355.         $this->noPoints 0;
  356.         $this->noVertices 0;
  357.         $this->setBuild(false);
  358.         $this->setCapacity(0);
  359.         $this->interpolate false;
  360.         $this->fragments 100;
  361.     }
  362.  
  363.     private function phantomPoints({
  364.         if ($this->numberOfVertices(1{
  365.             $i 0;
  366.  
  367.             $this->vertexList[$inew TeePoint(
  368.                     $this->vertexList[$i 1]->$this->vertexList[$i 2]->x,
  369.                     $this->vertexList[$i 1]->$this->vertexList[$i 2]->y);
  370.  
  371.             $this->vertexList[$this->numberOfVertices(1new TeePoint(
  372.                     $this->vertexList[$this->numberOfVertices()]->-
  373.                     $this->vertexList[$this->numberOfVertices(1]->x,
  374.                     $this->vertexList[$this->numberOfVertices()]->-
  375.                     $this->vertexList[$this->numberOfVertices(1]->y);
  376.         }
  377.     }
  378.  
  379.     /**
  380.      * Returns an interpolated point.
  381.      *
  382.      * @param parameter double
  383.      * @return Double 
  384.      */
  385.     public function value($parameter{
  386.         $result new TeePoint(00);
  387.  
  388.         if ($this->noPoints 2{
  389.             return $result;
  390.         }
  391.  
  392.         if (!$this->build{
  393.             $this->rebuild();
  394.         }
  395.  
  396.         (double) $mid ($this->numberOfVertices(1* (float)$parameter 1;
  397.         $s max(0(int) $mid 1);
  398.         $e $s 3;
  399.         if ($s $this->noVertices 1{
  400.             $s $this->noVertices 1;
  401.         }
  402.  
  403.         for ($c $s$c <= $e$c++{
  404.             (double) $dist abs($c $mid);
  405.             if ($dist 2{
  406.                 (double) $mix ($dist 1?
  407.                              (4.0 6.0($dist $dist+
  408.                              (0.5 $dist $dist $dist:
  409.                              ($dist($dist($dist6;
  410.                 $result->+= (float) ($this->vertexList[$c]->$mix);
  411.                 $result->+= (float) ($this->vertexList[$c]->$mix);
  412.             }
  413.         }
  414.         return $result;
  415.     }
  416. }
  417.  
  418. ?>

Documentation generated on Wed, 16 Jun 2010 12:08:22 +0200 by phpDocumentor 1.4.1