mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-23 01:42:17 +00:00
EZ-Components
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the ezcGraphBoundings class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Provides a class representing boundings in a cartesian coordinate system.
|
||||
*
|
||||
* Currently only works with plane rectangular boundings, should be enhanced by
|
||||
* rotated rectangular boundings.
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
* @access private
|
||||
*/
|
||||
class ezcGraphBoundings
|
||||
{
|
||||
/**
|
||||
* Top left x coordinate
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $x0 = 0;
|
||||
|
||||
/**
|
||||
* Top left y coordinate
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $y0 = 0;
|
||||
|
||||
/**
|
||||
* Bottom right x coordinate
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $x1 = false;
|
||||
|
||||
/**
|
||||
* Bottom right y coordinate
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $y1 = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param float $x0 Top left x coordinate
|
||||
* @param float $y0 Top left y coordinate
|
||||
* @param float $x1 Bottom right x coordinate
|
||||
* @param float $y1 Bottom right y coordinate
|
||||
* @return ezcGraphBoundings
|
||||
*/
|
||||
public function __construct( $x0 = 0., $y0 = 0., $x1 = null, $y1 = null )
|
||||
{
|
||||
$this->x0 = $x0;
|
||||
$this->y0 = $y0;
|
||||
$this->x1 = $x1;
|
||||
$this->y1 = $y1;
|
||||
|
||||
// Switch values to ensure correct order
|
||||
if ( $this->x0 > $this->x1 )
|
||||
{
|
||||
$tmp = $this->x0;
|
||||
$this->x0 = $this->x1;
|
||||
$this->x1 = $tmp;
|
||||
}
|
||||
|
||||
if ( $this->y0 > $this->y1 )
|
||||
{
|
||||
$tmp = $this->y0;
|
||||
$this->y0 = $this->y1;
|
||||
$this->y1 = $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for calculated values depending on the boundings.
|
||||
* - 'width': Width of bounding recangle
|
||||
* - 'height': Height of bounding recangle
|
||||
*
|
||||
* @param string $name Name of property to get
|
||||
* @return mixed Calculated value
|
||||
*/
|
||||
public function __get( $name )
|
||||
{
|
||||
switch ( $name )
|
||||
{
|
||||
case 'width':
|
||||
return $this->x1 - $this->x0;
|
||||
case 'height':
|
||||
return $this->y1 - $this->y0;
|
||||
default:
|
||||
throw new ezcBasePropertyNotFoundException( $name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,502 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the abstract ezcGraphMatrix class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Provides a genereic matrix class with basic math operations
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
* @access private
|
||||
*/
|
||||
class ezcGraphMatrix
|
||||
{
|
||||
|
||||
/**
|
||||
* Count of matrix rows
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $rows;
|
||||
|
||||
/**
|
||||
* Count of matrix columns
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $columns;
|
||||
|
||||
/**
|
||||
* Array containing matrix values.
|
||||
*
|
||||
* // Matrix
|
||||
* array(
|
||||
* // Rows
|
||||
* array(
|
||||
* // Column values
|
||||
* (float)
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @var array(array(float))
|
||||
*/
|
||||
protected $matrix;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Creates a matrix with given dimensions. Optionally accepts an array to
|
||||
* define the initial matrix values. If no array is given an identity
|
||||
* matrix is created.
|
||||
*
|
||||
* @param int $rows Number of rows
|
||||
* @param int $columns Number of columns
|
||||
* @param array $values Array with values
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $rows = 3, $columns = 3, array $values = null )
|
||||
{
|
||||
$this->rows = max( 1, (int) $rows );
|
||||
$this->columns = max( 1, (int) $columns );
|
||||
|
||||
if ( $values !== null )
|
||||
{
|
||||
$this->fromArray( $values );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->init();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create matrix from array
|
||||
*
|
||||
* Use an array with float values to set matrix values.
|
||||
*
|
||||
* @param array $values Array with values
|
||||
* @return ezcGraphMatrix Modified matrix
|
||||
*/
|
||||
public function fromArray( array $values )
|
||||
{
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
for ( $j = 0; $j < $this->columns; ++$j )
|
||||
{
|
||||
$this->matrix[$i][$j] =
|
||||
( isset( $values[$i][$j] )
|
||||
? (float) $values[$i][$j]
|
||||
: 0 );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init matrix
|
||||
*
|
||||
* Sets matrix to identity matrix.
|
||||
*
|
||||
* @return ezcGraphMatrix Modified matrix
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
for ( $j = 0; $j < $this->columns; ++$j )
|
||||
{
|
||||
$this->matrix[$i][$j] = ( $i === $j ? 1 : 0 );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of rows
|
||||
*
|
||||
* @return int Number of rows
|
||||
*/
|
||||
public function rows()
|
||||
{
|
||||
return $this->rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of columns
|
||||
*
|
||||
* @return int Number of columns
|
||||
*/
|
||||
public function columns()
|
||||
{
|
||||
return $this->columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single matrix value
|
||||
*
|
||||
* Returns the value of the matrix at the given position
|
||||
*
|
||||
* @param int $i Column
|
||||
* @param int $j Row
|
||||
* @return float Matrix value
|
||||
*/
|
||||
public function get( $i, $j )
|
||||
{
|
||||
if ( ( $i < 0 ) ||
|
||||
( $i >= $this->rows ) ||
|
||||
( $j < 0 ) ||
|
||||
( $j >= $this->columns ) )
|
||||
{
|
||||
throw new ezcGraphMatrixOutOfBoundingsException( $this->rows, $this->columns, $i, $j );
|
||||
}
|
||||
|
||||
return ( !isset( $this->matrix[$i][$j] ) ? .0 : $this->matrix[$i][$j] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a single matrix value
|
||||
*
|
||||
* Sets the value of the matrix at the given position.
|
||||
*
|
||||
* @param int $i Column
|
||||
* @param int $j Row
|
||||
* @param float $value Value
|
||||
* @return ezcGraphMatrix Updated matrix
|
||||
*/
|
||||
public function set( $i, $j, $value )
|
||||
{
|
||||
if ( ( $i < 0 ) ||
|
||||
( $i >= $this->rows ) ||
|
||||
( $j < 0 ) ||
|
||||
( $j >= $this->columns ) )
|
||||
{
|
||||
throw new ezcGraphMatrixOutOfBoundingsException( $this->rows, $this->columns, $i, $j );
|
||||
}
|
||||
|
||||
$this->matrix[$i][$j] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one matrix to the current one
|
||||
*
|
||||
* Calculate the sum of two matrices and returns the resulting matrix.
|
||||
*
|
||||
* @param ezcGraphMatrix $matrix Matrix to sum with
|
||||
* @return ezcGraphMatrix Result matrix
|
||||
*/
|
||||
public function add( ezcGraphMatrix $matrix )
|
||||
{
|
||||
if ( ( $this->rows !== $matrix->rows() ) ||
|
||||
( $this->columns !== $matrix->columns() ) )
|
||||
{
|
||||
throw new ezcGraphMatrixInvalidDimensionsException( $this->rows, $this->columns, $matrix->rows(), $matrix->columns() );
|
||||
}
|
||||
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
for ( $j = 0; $j < $this->columns; ++$j )
|
||||
{
|
||||
$this->matrix[$i][$j] += $matrix->get( $i, $j );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts matrix from current one
|
||||
*
|
||||
* Calculate the diffenrence of two matices and returns the result matrix.
|
||||
*
|
||||
* @param ezcGraphMatrix $matrix subtrahend
|
||||
* @return ezcGraphMatrix Result matrix
|
||||
*/
|
||||
public function diff( ezcGraphMatrix $matrix )
|
||||
{
|
||||
if ( ( $this->rows !== $matrix->rows() ) ||
|
||||
( $this->columns !== $matrix->columns() ) )
|
||||
{
|
||||
throw new ezcGraphMatrixInvalidDimensionsException( $this->rows, $this->columns, $matrix->rows(), $matrix->columns() );
|
||||
}
|
||||
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
for ( $j = 0; $j < $this->columns; ++$j )
|
||||
{
|
||||
$this->matrix[$i][$j] -= $matrix->get( $i, $j );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scalar multiplication
|
||||
*
|
||||
* Multiplies matrix with the given scalar and returns the result matrix
|
||||
*
|
||||
* @param float $scalar Scalar
|
||||
* @return ezcGraphMatrix Result matrix
|
||||
*/
|
||||
public function scalar( $scalar )
|
||||
{
|
||||
$scalar = (float) $scalar;
|
||||
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
for ( $j = 0; $j < $this->columns; ++$j )
|
||||
{
|
||||
$this->matrix[$i][$j] *= $scalar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transpose matrix
|
||||
*
|
||||
* @return ezcGraphMatrix Transposed matrix
|
||||
*/
|
||||
public function transpose()
|
||||
{
|
||||
$matrix = clone $this;
|
||||
|
||||
$this->rows = $matrix->columns();
|
||||
$this->columns = $matrix->rows();
|
||||
|
||||
$this->matrix = array();
|
||||
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
for ( $j = 0; $j < $this->columns; ++$j )
|
||||
{
|
||||
$this->matrix[$i][$j] = $matrix->get( $j, $i );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies two matrices
|
||||
*
|
||||
* Multiply current matrix with another matrix and returns the result
|
||||
* matrix.
|
||||
*
|
||||
* @param ezcGraphMatrix $matrix Second factor
|
||||
* @return ezcGraphMatrix Result matrix
|
||||
*/
|
||||
public function multiply( ezcGraphMatrix $matrix )
|
||||
{
|
||||
$mColumns = $matrix->columns();
|
||||
if ( $this->columns !== ( $mRows = $matrix->rows() ) )
|
||||
{
|
||||
throw new ezcGraphMatrixInvalidDimensionsException( $this->columns, $this->rows, $mColumns, $mRows );
|
||||
}
|
||||
|
||||
$result = new ezcGraphMatrix( $this->rows, $mColumns );
|
||||
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
for ( $j = 0; $j < $mColumns; ++$j )
|
||||
{
|
||||
$sum = 0;
|
||||
for ( $k = 0; $k < $mRows; ++$k ) {
|
||||
$sum += $this->matrix[$i][$k] * $matrix->get( $k, $j );
|
||||
}
|
||||
|
||||
$result->set( $i, $j, $sum );
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Solve nonlinear equatation
|
||||
*
|
||||
* Tries to solve equatation given by two matrices, with assumption, that:
|
||||
* A * x = B
|
||||
* where $this is A, and the paramenter B. x is cosnidered as a vector
|
||||
* x = ( x^n, x^(n-1), ..., x^2, x, 1 )
|
||||
*
|
||||
* Will return a polynomial solution for x.
|
||||
*
|
||||
* See: http://en.wikipedia.org/wiki/Gauss-Newton_algorithm
|
||||
*
|
||||
* @param ezcGraphMatrix $matrix B
|
||||
* @return ezcGraphPolygon Solution of equatation
|
||||
*/
|
||||
public function solveNonlinearEquatation( ezcGraphMatrix $matrix )
|
||||
{
|
||||
// Build complete equatation
|
||||
$equatation = new ezcGraphMatrix( $this->rows, $columns = ( $this->columns + 1 ) );
|
||||
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
for ( $j = 0; $j < $this->columns; ++$j )
|
||||
{
|
||||
$equatation->set( $i, $j, $this->matrix[$i][$j] );
|
||||
}
|
||||
$equatation->set( $i, $this->columns, $matrix->get( $i, 0 ) );
|
||||
}
|
||||
|
||||
// Compute upper triangular matrix on left side of equatation
|
||||
for ( $i = 0; $i < ( $this->rows - 1 ); ++$i )
|
||||
{
|
||||
for ( $j = $i + 1; $j < $this->rows; ++$j )
|
||||
{
|
||||
if ( $equatation->get( $j, $i ) !== 0 )
|
||||
{
|
||||
if ( $equatation->get( $j, $i ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
$factor = -( $equatation->get( $i, $i ) / $equatation->get( $j, $i ) );
|
||||
}
|
||||
|
||||
for ( $k = $i; $k < $columns; ++$k )
|
||||
{
|
||||
$equatation->set( $j, $k, $equatation->get( $i, $k ) + $factor * $equatation->get( $j, $k ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize values on left side matrix diagonale
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
if ( ( ( $value = $equatation->get( $i, $i ) ) != 1 ) &&
|
||||
( $value != 0 ) )
|
||||
{
|
||||
$factor = 1 / $value;
|
||||
for ( $k = $i; $k < $columns; ++$k )
|
||||
{
|
||||
$equatation->set( $i, $k, $equatation->get( $i, $k ) * $factor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build up solving polynom
|
||||
$polynom = new ezcGraphPolynom();
|
||||
for ( $i = ( $this->rows - 1 ); $i >= 0; --$i )
|
||||
{
|
||||
for ( $j = $i + 1; $j < $this->columns; ++$j )
|
||||
{
|
||||
$equatation->set(
|
||||
$i,
|
||||
$this->columns,
|
||||
$equatation->get( $i, $this->columns ) + ( -$equatation->get( $i, $j ) * $polynom->get( $j ) )
|
||||
);
|
||||
$equatation->set( $i, $j, 0 );
|
||||
}
|
||||
$polynom->set( $i, $equatation->get( $i, $this->columns ) );
|
||||
}
|
||||
|
||||
return $polynom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build LR decomposition from matrix
|
||||
*
|
||||
* Use Cholesky-Crout algorithm to get LR decomposition of the current
|
||||
* matrix.
|
||||
*
|
||||
* Will return an array with two matrices:
|
||||
* array(
|
||||
* 'l' => (ezcGraphMatrix) $left,
|
||||
* 'r' => (ezcGraphMatrix) $right,
|
||||
* )
|
||||
*
|
||||
* @return array( ezcGraphMatrix )
|
||||
*/
|
||||
public function LRdecomposition()
|
||||
{
|
||||
/**
|
||||
* Use Cholesky-Crout algorithm to get LR decomposition
|
||||
*
|
||||
* Input: Matrix A ($this)
|
||||
*
|
||||
* For i = 1 To n
|
||||
* For j = i To n
|
||||
* R(i,j)=A(i,j)
|
||||
* For k = 1 TO i-1
|
||||
* R(i,j)-=L(i,k)*R(k,j)
|
||||
* end
|
||||
* end
|
||||
* For j=i+1 To n
|
||||
* L(j,i)= A(j,i)
|
||||
* For k = 1 TO i-1
|
||||
* L(j,i)-=L(j,k)*R(k,i)
|
||||
* end
|
||||
* L(j,i)/=R(i,i)
|
||||
* end
|
||||
* end
|
||||
*
|
||||
* Output: matrices L,R
|
||||
*/
|
||||
$l = new ezcGraphMatrix( $this->columns, $this->rows );
|
||||
$r = new ezcGraphMatrix( $this->columns, $this->rows );
|
||||
|
||||
for ( $i = 0; $i < $this->columns; ++$i )
|
||||
{
|
||||
for ( $j = $i; $j < $this->rows; ++$j )
|
||||
{
|
||||
$r->set( $i, $j, $this->matrix[$i][$j] );
|
||||
for ( $k = 0; $k <= ( $i - 1 ); ++$k )
|
||||
{
|
||||
$r->set( $i, $j, $r->get( $i, $j ) - $l->get( $i, $k ) * $r->get( $k, $j ) );
|
||||
}
|
||||
}
|
||||
|
||||
for ( $j = $i + 1; $j < $this->rows; ++$j )
|
||||
{
|
||||
$l->set( $j, $i, $this->matrix[$j][$i] );
|
||||
for ( $k = 0; $k <= ( $i - 1 ); ++$k )
|
||||
{
|
||||
$l->set( $j, $i, $l->get( $j, $i ) - $l->get( $j, $k ) * $r->get( $k, $i ) );
|
||||
}
|
||||
$l->set( $j, $i, $l->get( $j, $i ) / $r->get( $i, $i ) );
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
'l' => $l,
|
||||
'r' => $r,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the matrix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$string = sprintf( "%d x %d matrix:\n", $this->rows, $this->columns );
|
||||
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
$string .= '| ';
|
||||
for ( $j = 0; $j < $this->columns; ++$j )
|
||||
{
|
||||
$string .= sprintf( '%04.2f ', $this->get( $i, $j ) );
|
||||
}
|
||||
$string .= "|\n";
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,230 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the abstract ezcGraphPolynom class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
*/
|
||||
/**
|
||||
* Provides a class for generic operations on polynoms
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
*/
|
||||
class ezcGraphPolynom
|
||||
{
|
||||
/**
|
||||
* Factors of the polynom
|
||||
*
|
||||
* An example:
|
||||
* Polynom:
|
||||
* 2 * x^3 + .5 * x - 3
|
||||
* Array:
|
||||
* array (
|
||||
* (int) 3 => (float) 2,
|
||||
* (int) 1 => (float) .5,
|
||||
* (int) 0 => (float) -3,
|
||||
* )
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $values;
|
||||
|
||||
// @TODO: Introduce precision option for string output?
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Constructs a polynom object from given array, where the key is the
|
||||
* exponent and the value the factor.
|
||||
* An example:
|
||||
* Polynom:
|
||||
* 2 * x^3 + .5 * x - 3
|
||||
* Array:
|
||||
* array (
|
||||
* (int) 3 => (float) 2,
|
||||
* (int) 1 => (float) .5,
|
||||
* (int) 0 => (float) -3,
|
||||
* )
|
||||
*
|
||||
* @param array $values Array with values
|
||||
* @return ezcGraphPolynom
|
||||
*/
|
||||
public function __construct( array $values = array() )
|
||||
{
|
||||
foreach ( $values as $exponent => $factor )
|
||||
{
|
||||
$this->values[(int) $exponent] = (float) $factor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise a polygon
|
||||
*
|
||||
* Initialise a polygon of the given order. Sets all factors to 0.
|
||||
*
|
||||
* @param int $order Order of polygon
|
||||
* @return ezcGraphPolynom Created polynom
|
||||
*/
|
||||
public function init( $order )
|
||||
{
|
||||
for ( $i = 0; $i <= $order; ++$i )
|
||||
{
|
||||
$this->values[$i] = 0;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return factor for one exponent
|
||||
*
|
||||
* @param int $exponent Exponent
|
||||
* @return float Factor
|
||||
*/
|
||||
public function get( $exponent )
|
||||
{
|
||||
if ( !isset( $this->values[$exponent] ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->values[$exponent];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the factor for one exponent
|
||||
*
|
||||
* @param int $exponent Exponent
|
||||
* @param float $factor Factor
|
||||
* @return ezcGraphPolynom Modified polynom
|
||||
*/
|
||||
public function set( $exponent, $factor )
|
||||
{
|
||||
$this->values[(int) $exponent] = (float) $factor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the order of the polynom
|
||||
*
|
||||
* @return int Polynom order
|
||||
*/
|
||||
public function getOrder()
|
||||
{
|
||||
return max( array_keys( $this->values ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds polynom to current polynom
|
||||
*
|
||||
* @param ezcGraphPolynom $polynom Polynom to add
|
||||
* @return ezcGraphPolynom Modified polynom
|
||||
*/
|
||||
public function add( ezcGraphPolynom $polynom )
|
||||
{
|
||||
$order = max(
|
||||
$this->getOrder(),
|
||||
$polynom->getOrder()
|
||||
);
|
||||
|
||||
for ( $i = 0; $i <= $order; ++$i )
|
||||
{
|
||||
$this->set( $i, $this->get( $i ) + $polynom->get( $i ) );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate Polynom with a given value
|
||||
*
|
||||
* @param float $x Value
|
||||
* @return float Result
|
||||
*/
|
||||
public function evaluate( $x )
|
||||
{
|
||||
$value = 0;
|
||||
foreach ( $this->values as $exponent => $factor )
|
||||
{
|
||||
$value += $factor * pow( $x, $exponent );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string represenation of the polynom
|
||||
*
|
||||
* @return string String representation of polynom
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
krsort( $this->values );
|
||||
$string = '';
|
||||
|
||||
foreach ( $this->values as $exponent => $factor )
|
||||
{
|
||||
if ( $factor == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$string .= ( $factor < 0 ? ' - ' : ' + ' );
|
||||
|
||||
$factor = abs( $factor );
|
||||
switch ( true )
|
||||
{
|
||||
case abs( 1 - $factor ) < .0001:
|
||||
// No not append, if factor is ~1
|
||||
break;
|
||||
case $factor < 1:
|
||||
case $factor >= 1000:
|
||||
$string .= sprintf( '%.2e ', $factor );
|
||||
break;
|
||||
case $factor >= 100:
|
||||
$string .= sprintf( '%.0f ', $factor );
|
||||
break;
|
||||
case $factor >= 10:
|
||||
$string .= sprintf( '%.1f ', $factor );
|
||||
break;
|
||||
default:
|
||||
$string .= sprintf( '%.2f ', $factor );
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( true )
|
||||
{
|
||||
case $exponent > 1:
|
||||
$string .= sprintf( 'x^%d', $exponent );
|
||||
break;
|
||||
case $exponent === 1:
|
||||
$string .= 'x';
|
||||
break;
|
||||
case $exponent === 0:
|
||||
if ( abs( 1 - $factor ) < .0001 )
|
||||
{
|
||||
$string .= '1';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( substr( $string, 0, 3 ) === ' + ' )
|
||||
{
|
||||
$string = substr( $string, 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
$string = '-' . substr( $string, 3 );
|
||||
}
|
||||
|
||||
return trim( $string );
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the ezcGraphRotation class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Class to create rotation matrices from given rotation and center point
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
* @access private
|
||||
*/
|
||||
class ezcGraphRotation extends ezcGraphTransformation
|
||||
{
|
||||
/**
|
||||
* Rotation in degrees
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
protected $rotation;
|
||||
|
||||
/**
|
||||
* Center point
|
||||
*
|
||||
* @var ezcGraphCoordinate
|
||||
*/
|
||||
protected $center;
|
||||
|
||||
/**
|
||||
* Construct rotation matrix from rotation (in degrees) and optional
|
||||
* center point.
|
||||
*
|
||||
* @param int $rotation
|
||||
* @param ezcGraphCoordinate $center
|
||||
* @return ezcGraphTransformation
|
||||
*/
|
||||
public function __construct( $rotation = 0, ezcGraphCoordinate $center = null )
|
||||
{
|
||||
$this->rotation = (float) $rotation;
|
||||
|
||||
if ( $center === null )
|
||||
{
|
||||
$this->center = new ezcGraphCoordinate( 0, 0 );
|
||||
|
||||
$clockwiseRotation = deg2rad( $rotation );
|
||||
$rotationMatrixArray = array(
|
||||
array( cos( $clockwiseRotation ), -sin( $clockwiseRotation ), 0 ),
|
||||
array( sin( $clockwiseRotation ), cos( $clockwiseRotation ), 0 ),
|
||||
array( 0, 0, 1 ),
|
||||
);
|
||||
|
||||
return parent::__construct( $rotationMatrixArray );
|
||||
}
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->center = $center;
|
||||
|
||||
$this->multiply( new ezcGraphTranslation( $center->x, $center->y ) );
|
||||
$this->multiply( new ezcGraphRotation( $rotation ) );
|
||||
$this->multiply( new ezcGraphTranslation( -$center->x, -$center->y ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return rotaion angle in degrees
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getRotation()
|
||||
{
|
||||
return $this->rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the center point of the current rotation
|
||||
*
|
||||
* @return ezcGraphCoordinate
|
||||
*/
|
||||
public function getCenter()
|
||||
{
|
||||
return $this->center;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the ezcGraphTransformation class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Class defining transformations like scaling and rotation by a
|
||||
* 3x3 transformation matrix for |R^2
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
* @access private
|
||||
*/
|
||||
class ezcGraphTransformation extends ezcGraphMatrix
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Creates a matrix with 3x3 dimensions. Optionally accepts an array to
|
||||
* define the initial matrix values. If no array is given an identity
|
||||
* matrix is created.
|
||||
*
|
||||
* @param array $values
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( array $values = null )
|
||||
{
|
||||
parent::__construct( 3, 3, $values );
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies two matrices
|
||||
*
|
||||
* Multiply current matrix with another matrix and returns the result
|
||||
* matrix.
|
||||
*
|
||||
* @param ezcGraphMatrix $matrix Second factor
|
||||
* @return ezcGraphMatrix Result matrix
|
||||
*/
|
||||
public function multiply( ezcGraphMatrix $matrix )
|
||||
{
|
||||
$mColumns = $matrix->columns();
|
||||
|
||||
// We want to ensure, that the matrix stays 3x3
|
||||
if ( ( $this->columns !== $matrix->rows() ) &&
|
||||
( $this->rows !== $mColumns ) )
|
||||
{
|
||||
throw new ezcGraphMatrixInvalidDimensionsException( $this->columns, $this->rows, $mColumns, $matrix->rows() );
|
||||
}
|
||||
|
||||
$result = parent::multiply( $matrix );
|
||||
|
||||
// The matrix dimensions stay the same, so that we can modify $this.
|
||||
for ( $i = 0; $i < $this->rows; ++$i )
|
||||
{
|
||||
for ( $j = 0; $j < $mColumns; ++$j )
|
||||
{
|
||||
$this->set( $i, $j, $result->get( $i, $j ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a coordinate with the current transformation matrix.
|
||||
*
|
||||
* @param ezcGraphCoordinate $coordinate
|
||||
* @return ezcGraphCoordinate
|
||||
*/
|
||||
public function transformCoordinate( ezcGraphCoordinate $coordinate )
|
||||
{
|
||||
$vector = new ezcGraphMatrix( 3, 1, array( array( $coordinate->x ), array( $coordinate->y ), array( 1 ) ) );
|
||||
$vector = parent::multiply( $vector );
|
||||
|
||||
return new ezcGraphCoordinate( $vector->get( 0, 0 ), $vector->get( 1, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the ezcGraphTranslation class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Class creating translation matrices from given movements
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
* @access private
|
||||
*/
|
||||
class ezcGraphTranslation extends ezcGraphTransformation
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param float $x
|
||||
* @param float $y
|
||||
* @return void
|
||||
* @ignore
|
||||
*/
|
||||
public function __construct( $x = 0., $y = 0. )
|
||||
{
|
||||
parent::__construct( array(
|
||||
array( 1, 0, $x ),
|
||||
array( 0, 1, $y ),
|
||||
array( 0, 0, 1 ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,187 @@
|
||||
<?php
|
||||
/**
|
||||
* File containing the ezcGraphVector class
|
||||
*
|
||||
* @package Graph
|
||||
* @version 1.3
|
||||
* @copyright Copyright (C) 2005-2008 eZ systems as. All rights reserved.
|
||||
* @license http://ez.no/licenses/new_bsd New BSD License
|
||||
* @access private
|
||||
*/
|
||||
/**
|
||||
* Represents two dimensional vectors
|
||||
*
|
||||
* @version 1.3
|
||||
* @package Graph
|
||||
* @access private
|
||||
*/
|
||||
class ezcGraphVector extends ezcGraphCoordinate
|
||||
{
|
||||
/**
|
||||
* Rotates vector to the left by 90 degrees
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rotateCounterClockwise()
|
||||
{
|
||||
$tmp = $this->x;
|
||||
$this->x = $this->y;
|
||||
$this->y = -$tmp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates vector to the right by 90 degrees
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function rotateClockwise()
|
||||
{
|
||||
$tmp = $this->x;
|
||||
$this->x = -$this->y;
|
||||
$this->y = $tmp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unifies vector length to 1
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unify()
|
||||
{
|
||||
$length = $this->length();
|
||||
if ( $length == 0 )
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->x /= $length;
|
||||
$this->y /= $length;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns length of vector
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function length()
|
||||
{
|
||||
return sqrt(
|
||||
pow( $this->x, 2 ) +
|
||||
pow( $this->y, 2 )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies vector with a scalar
|
||||
*
|
||||
* @param float $value
|
||||
* @return void
|
||||
*/
|
||||
public function scalar( $value )
|
||||
{
|
||||
$this->x *= $value;
|
||||
$this->y *= $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates scalar product of two vectors
|
||||
*
|
||||
* @param ezcGraphCoordinate $vector
|
||||
* @return void
|
||||
*/
|
||||
public function mul( ezcGraphCoordinate $vector )
|
||||
{
|
||||
return $this->x * $vector->x + $this->y * $vector->y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the angle between two vectors in radian
|
||||
*
|
||||
* @param ezcGraphCoordinate $vector
|
||||
* @return float
|
||||
*/
|
||||
public function angle( ezcGraphCoordinate $vector )
|
||||
{
|
||||
if ( !$vector instanceof ezcGraphVector )
|
||||
{
|
||||
// Ensure beeing a vector for calling length()
|
||||
$vector = ezcGraphVector::fromCoordinate( $vector );
|
||||
}
|
||||
|
||||
$factor = $this->length() * $vector->length();
|
||||
|
||||
if ( $factor == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return acos( $this->mul( $vector ) / $factor );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a vector to another vector
|
||||
*
|
||||
* @param ezcGraphCoordinate $vector
|
||||
* @return void
|
||||
*/
|
||||
public function add( ezcGraphCoordinate $vector )
|
||||
{
|
||||
$this->x += $vector->x;
|
||||
$this->y += $vector->y;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts a vector from another vector
|
||||
*
|
||||
* @param ezcGraphCoordinate $vector
|
||||
* @return void
|
||||
*/
|
||||
public function sub( ezcGraphCoordinate $vector )
|
||||
{
|
||||
$this->x -= $vector->x;
|
||||
$this->y -= $vector->y;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a vector from a coordinate object
|
||||
*
|
||||
* @param ezcGraphCoordinate $coordinate
|
||||
* @return ezcGraphVector
|
||||
*/
|
||||
public static function fromCoordinate( ezcGraphCoordinate $coordinate )
|
||||
{
|
||||
return new ezcGraphVector( $coordinate->x, $coordinate->y );
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform vector using transformation matrix
|
||||
*
|
||||
* @param ezcGraphTransformation $transformation
|
||||
* @return ezcGraphVector
|
||||
*/
|
||||
public function transform( ezcGraphTransformation $transformation )
|
||||
{
|
||||
$result = $transformation->transformCoordinate( $this );
|
||||
|
||||
$this->x = $result->x;
|
||||
$this->y = $result->y;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user