| 1 | <?php
 | 
|---|
| 2 | /*=======================================================================
 | 
|---|
| 3 | // File:        JPGRAPH_MESHINTERPOLATE.INC.PHP
 | 
|---|
| 4 | // Description: Utility class to do mesh linear interpolation of a matrix
 | 
|---|
| 5 | // Created:     2009-03-09
 | 
|---|
| 6 | // Ver:         $Id: jpgraph_meshinterpolate.inc.php 1709 2009-07-30 08:00:08Z ljp $
 | 
|---|
| 7 | //
 | 
|---|
| 8 | // Copyright (c) Asial Corporation. All rights reserved.
 | 
|---|
| 9 | //========================================================================
 | 
|---|
| 10 | */
 | 
|---|
| 11 |   
 | 
|---|
| 12 | /**
 | 
|---|
| 13 | * Utility function to do linear mesh interpolation
 | 
|---|
| 14 | * @param $aDat Matrix to interpolate
 | 
|---|
| 15 | * @param $aFactor Interpolation factor  
 | 
|---|
| 16 | */
 | 
|---|
| 17 | function doMeshInterpolate( &$aData, $aFactor ) {
 | 
|---|
| 18 |     $m = new MeshInterpolate();
 | 
|---|
| 19 |     $aData = $m->Linear($aData,$aFactor);
 | 
|---|
| 20 | }
 | 
|---|
| 21 | 
 | 
|---|
| 22 | /**
 | 
|---|
| 23 |  * Utility class to interpolate a given data matrix
 | 
|---|
| 24 |  *
 | 
|---|
| 25 |  */
 | 
|---|
| 26 | class MeshInterpolate {
 | 
|---|
| 27 |     private $data = array();
 | 
|---|
| 28 | 
 | 
|---|
| 29 |    /**
 | 
|---|
| 30 |     * Calculate the mid points of the given rectangle which has its top left
 | 
|---|
| 31 |     * corner at $row,$col. The $aFactordecides how many spliots should be done.
 | 
|---|
| 32 |     * i.e. how many more divisions should be done recursively
 | 
|---|
| 33 |     *
 | 
|---|
| 34 |     * @param $row Top left corner of square to work with
 | 
|---|
| 35 |     * @param $col Top left corner of square to work with
 | 
|---|
| 36 |     * $param $aFactor In how many subsquare should we split this square. A value of 1 indicates that no action
 | 
|---|
| 37 |     */
 | 
|---|
| 38 |     function IntSquare( $aRow, $aCol, $aFactor ) {
 | 
|---|
| 39 |         if ( $aFactor <= 1 )
 | 
|---|
| 40 |             return;
 | 
|---|
| 41 | 
 | 
|---|
| 42 |         $step = pow( 2, $aFactor-1 );
 | 
|---|
| 43 | 
 | 
|---|
| 44 |         $v0 = $this->data[$aRow][$aCol];
 | 
|---|
| 45 |         $v1 = $this->data[$aRow][$aCol + $step];
 | 
|---|
| 46 |         $v2 = $this->data[$aRow + $step][$aCol];
 | 
|---|
| 47 |         $v3 = $this->data[$aRow + $step][$aCol + $step];
 | 
|---|
| 48 | 
 | 
|---|
| 49 |         $this->data[$aRow][$aCol + $step / 2] = ( $v0 + $v1 ) / 2;
 | 
|---|
| 50 |         $this->data[$aRow + $step / 2][$aCol] = ( $v0 + $v2 ) / 2;
 | 
|---|
| 51 |         $this->data[$aRow + $step][$aCol + $step / 2] = ( $v2 + $v3 ) / 2;
 | 
|---|
| 52 |         $this->data[$aRow + $step / 2][$aCol + $step] = ( $v1 + $v3 ) / 2;
 | 
|---|
| 53 |         $this->data[$aRow + $step / 2][$aCol + $step / 2] = ( $v0 + $v1 + $v2 + $v3 ) / 4;
 | 
|---|
| 54 | 
 | 
|---|
| 55 |         $this->IntSquare( $aRow, $aCol, $aFactor-1 );
 | 
|---|
| 56 |         $this->IntSquare( $aRow, $aCol + $step / 2, $aFactor-1 );
 | 
|---|
| 57 |         $this->IntSquare( $aRow + $step / 2, $aCol, $aFactor-1 );
 | 
|---|
| 58 |         $this->IntSquare( $aRow + $step / 2, $aCol + $step / 2, $aFactor-1 );
 | 
|---|
| 59 |     }
 | 
|---|
| 60 | 
 | 
|---|
| 61 |     /**
 | 
|---|
| 62 |      * Interpolate values in a matrice so that the total number of data points
 | 
|---|
| 63 |      * in vert and horizontal axis are $aIntNbr more. For example $aIntNbr=2 will
 | 
|---|
| 64 |      * make the data matrice have tiwce as many vertical and horizontal dta points.
 | 
|---|
| 65 |      *
 | 
|---|
| 66 |      * Note: This will blow up the matrcide in memory size in the order of $aInNbr^2
 | 
|---|
| 67 |      *
 | 
|---|
| 68 |      * @param  $ &$aData The original data matricde
 | 
|---|
| 69 |      * @param  $aInNbr Interpolation factor
 | 
|---|
| 70 |      * @return the interpolated matrice
 | 
|---|
| 71 |      */
 | 
|---|
| 72 |     function Linear( &$aData, $aIntFactor ) {
 | 
|---|
| 73 |         $step = pow( 2, $aIntFactor-1 );
 | 
|---|
| 74 | 
 | 
|---|
| 75 |         $orig_cols = count( $aData[0] );
 | 
|---|
| 76 |         $orig_rows = count( $aData );
 | 
|---|
| 77 |         // Number of new columns/rows
 | 
|---|
| 78 |         // N = (a-1) * 2^(f-1) + 1
 | 
|---|
| 79 |         $p = pow( 2, $aIntFactor-1 );
 | 
|---|
| 80 |         $new_cols = $p * ( $orig_cols - 1 ) + 1;
 | 
|---|
| 81 |         $new_rows = $p * ( $orig_rows - 1 ) + 1;
 | 
|---|
| 82 | 
 | 
|---|
| 83 |         $this->data = array_fill( 0, $new_rows, array_fill( 0, $new_cols, 0 ) );
 | 
|---|
| 84 |         // Initialize the new matrix with the values that we know
 | 
|---|
| 85 |         for ( $i = 0; $i < $new_rows; $i++ ) {
 | 
|---|
| 86 |             for ( $j = 0; $j < $new_cols; $j++ ) {
 | 
|---|
| 87 |                 $v = 0 ;
 | 
|---|
| 88 |                 if ( ( $i % $step == 0 ) && ( $j % $step == 0 ) ) {
 | 
|---|
| 89 |                     $v = $aData[$i / $step][$j / $step];
 | 
|---|
| 90 |                 }
 | 
|---|
| 91 |                 $this->data[$i][$j] = $v;
 | 
|---|
| 92 |             }
 | 
|---|
| 93 |         }
 | 
|---|
| 94 | 
 | 
|---|
| 95 |         for ( $i = 0; $i < $new_rows-1; $i += $step ) {
 | 
|---|
| 96 |             for ( $j = 0; $j < $new_cols-1; $j += $step ) {
 | 
|---|
| 97 |                 $this->IntSquare( $i, $j, $aIntFactor );
 | 
|---|
| 98 |             }
 | 
|---|
| 99 |         }
 | 
|---|
| 100 | 
 | 
|---|
| 101 |         return $this->data;
 | 
|---|
| 102 |     }
 | 
|---|
| 103 | }
 | 
|---|
| 104 |   
 | 
|---|
| 105 | ?>
 | 
|---|