<?
define('Z_CARTESIAN', 0);
define('Z_POLAR', 1);
define('Z_RADIAN', 0);
define('Z_DEGREE', 1);
class Z{
// Constructor
function Z($var = "", $im = "", $type = Z_CARTESIAN, $unit = Z_RADIAN ){
if( $unit ){
$this->unit = $unit;
}
list( $this->x, $this->y ) = $this->parse( func_get_args() );
}
// Public Functions
function SetUnit($unit = Z_RADIAN){
$this->unit = $unit;
return $this->unit;
}
function Re(){
return $this->x;
}
function Im(){
return $this->y;
}
function Mod(){
return hypot( $this->x, $this->y );
}
function Arg(){
if( $this->unit ){
return rad2deg( atan( $this->y / $this->x ) );
}
else{
return atan( $this->y / $this->x );
}
}
# For the following 4-op functions, input vars is same as constructor function.
function Add(){
list( $x, $y ) = $this->parse( func_get_args() );
$this->x+= $x;
$this->y+= $y;
}
function Sub(){
list( $x, $y ) = $this->parse( func_get_args() );
$this->x-= $x;
$this->y-= $y;
}
function Mul(){
list( $x, $y ) = $this->parse( func_get_args() );
list( $mod, $arg ) = $this->ToPolar( $x, $y );
list( $this->x, $this->y ) = $this->ToCartesian( $this->Mod()*$mod, $this->Arg()+$arg );
}
function Div(){
list( $x, $y ) = $this->parse( func_get_args() );
list( $mod, $arg ) = $this->ToPolar( $x, $y );
list( $this->x, $this->y ) = $this->ToCartesian( $this->Mod()/$mod, $this->Arg()-$arg );
}
// Private functions
function parse( $arr ){
list ($var, $im, $type, $unit ) = $arr;
if( $var ){
if( $im ){
if( $type == Z_POLAR ){
if( stristr( $im, "d" ) || ( ($unit == Z_DEGREE) && (!stristr( $im, "d" )) ) ){
$im = deg2rad( $im );
}
list( $x, $y ) = $this->ToCartesian( $var, $im );
}
else{
$x = $var;
$y = $im;
}
}
else{
list( $x, $y ) = $this->parse_number( $var );
}
}
return array( $x, $y );
}
function parse_number($str){
$str = preg_replace("/\s*/","",$str);
if( preg_match("/(?i)[^erd\-+ij.,0-9]+/", $str) ){
return -1;
}
else{
if( stristr( $str, "e" ) ){
preg_match("/(?i)([0-9]+)e-[ij]?([0-9rd]+)[ij]?/", $str, $arr);
if( sizeof( $arr ) ){
if( stristr( $arr[2], "d" ) ){
$arr[2] = deg2rad( $arr[2] );
}
list( $re, $im ) = $this->ToCartesian( $arr[1], $arr[2] );
}
}
else{
preg_match_all( "/(?i)([\-+]?[0-9.,ij]+)/", $str, $arr, PREG_SET_ORDER );
if( sizeof( $arr ) ){
foreach( $arr as $number ){
if( preg_match( "/(?i)[ij]/", $number[1] ) ){
$im += $number[1];
}
else{
$re += $number[1];
}
}
}
}
return array($re, $im);
}
}
function ToCartesian( $mod, $ang ){
return array( ( $mod*cos($ang) ), ( $mod*sin($ang) ) );
}
function ToPolar( $re, $im ){
return array( hypot( $re, $im ) , atan( ($im/$re) ) );
}
}
?> |