Location: PHPKode > projects > MaximaPHP > maximaphp/viewers/mpvmandelbrot.php
<?php

/**
 * mpvmandelbrot.php, MaximaPHP Viewer - Mandelbrot
 *
 * Mandelbrot viewer for MaximaPHP.
 * 
 * This file contains MPVMandelbrot class.
 * @author Bowo Prasetyo <http://www.my-tool.com/maximaphp/fractal/mandelbrot/>
 * @version 0.1.3
 * @package MaximaPHP
 */

/**************************************************************
 *
 * Copyright (C) 2007 Bowo Prasetyo
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation below,
 * 
 * http://www.gnu.org/licenses/gpl.html#TOC1
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
 * MA  02110-1301, USA.
 *
 **************************************************************/

/**
 * Mandelbrot viewer class for MaximaPHP.
 *
 */
class MPVMandelbrot 
{
   /**
    * Examples for expression
    */
   var $examples = array
   (
      array( '0, 0', '2', '12', '400', '360', '300', '0.46', '0.96', '0, 0, 0', '' ),
      array( '0.282, -0.01', '0.003', '120', '300', '360', '300', '1', '1', '0, 0, 0', '' ),
      array( '0.45154329, -0.37432948', '0.000005', '240', '300', '360', '300', '1', '1', '0, 0, 0', '' ),
      array( '0.35591327, 0.64971838', '0.0000003', '240', '150', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-1.7480902, -0.0006932', '0.00001', '240', '300', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-1.7480904, -0.00069315', '0.00000012', '600', '200', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-1.7480904, -0.00069315', '0.00000012', '480', '200', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-0.6654, -0.3556', '0.003', '180', '250', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-0.1293890996, -1.02007242913', '0.000000000007', '480', '175', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-0.1293890996, -1.02007242913', '0.000000000007', '360', '175', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-1.749484337, -0.000145685', '0.00000001', '360', '150', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-1.749484337, -0.000145685', '0.00000001', '480', '150', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-0.16062852204, 1.03760450630', '0.0000000006', '480', '200', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-0.16062852204, 1.03760450630', '0.0000000006', '240', '200', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-1.7494846, -0.000145', '0.000003', '240', '200', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-1.7494846, -0.000145', '0.000003', '360', '175', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '-1.7494846, -0.000145', '0.000003', '480', '175', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '0.3583, 0.6448', '0.006', '240', '250', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '0.45154392, 0.37433051', '0.00000007', '480', '175', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
      array( '0.45154392, 0.37433051', '0.00000007', '360', '175', '360', '300', '1', '1', '0, 0, 0', 'from http://www.ginko.de/user/kremer/karsten/e/ap-gal.htm' ),
   );

   /**
    * Get examples
    * @param integer $count number of examples to get
    * @return string
    */
   function getExamples( $count )
   {
      $ex_out = MPVIEWER_GET_EXAMPLES;
      if ( $count == 0 ) $count = count ( $this->examples );
      for ( $i = 0; $i < $count; $i++ )
      {
         $ex_out .= "<pre style=\"background-color: #f0f9ff; border: 1px solid #cccccc; padding: 1px;\">" . htmlentities( $this->examples[$i][0] ) . '<br />' . htmlentities( $this->examples[$i][1] ) . '<br />' . htmlentities( $this->examples[$i][2] ) . '<br />' . htmlentities( $this->examples[$i][3] ) . '<br />' . htmlentities( $this->examples[$i][4] ) . '<br />' . htmlentities( $this->examples[$i][5] ) . '<br />' . htmlentities( $this->examples[$i][6] ) . '<br />' . htmlentities( $this->examples[$i][7] ) . '<br />' . htmlentities( $this->examples[$i][8] ) . '<br />' . htmlentities( $this->examples[$i][9] ) . '<br />' . "</pre>\n";
      }
      $ex_out .= "\n";
      return $ex_out;
   }

   /**
    * Format output from MaximaPHP
    * @param string $result output from MaximaPHP
    * @return string
    */
   function formatOutput( $result, $size )
   {
      $result = preg_replace( '/.*(?=\n\s*:\| options \|:)/s', '', $result );
      $result = preg_replace( '/\(%i[0-9]+\).*(?=\n\s*:\| mandelbrot \|:)/s', '', $result );
      $result = preg_replace( '/<img src="(http:\/\/www\.my-tool\.com\/mathematics\/maximaphp\/png\/.+\.png)" \/>/s', '<div onmousemove="showXY(event)" onclick="submitForm(event)" style="width:' . $size . 'px; height:' . $size . 'px; background-image: url(\1)"></div>New center: <div id="new_center"> </div>', $result );
      return $result;
   }

   /**
    * Show the viewer
    */
   function show( $qstring )
   {
      require_once( 'mprewriteurl.php' );

      if ( isset( $_SESSION['last_output'] ) )
         $last_output = $_SESSION['last_output'];
      else
         $last_output = '';

      if ( isset( $_SESSION['last_input'] ) )
         $last_input = $_SESSION['last_input'];
      else
         $last_input = '';

      if ( isset( $_GET['sub2'] ) )
         $view = $_GET['sub2'];
      else
         $view = 'text';
      

      if ( isset( $_POST['center'] ) )
         $center = $_POST['center'];
      else
      {
         if ( isset( $_SESSION['last_input'] ) )
            $center = $_SESSION['last_input'];
         else
            $center = '0, 0';
      }

      if ( isset( $_POST['radius'] ) )
         $radius = $_POST['radius'];
      else
      {
         if ( isset( $_SESSION['radius'] ) )
            $radius = $_SESSION['radius'];
         else
            $radius = 2;
      }

      if ( isset( $_POST['size'] ) )
         $size = intval( $_POST['size'] );
      else
      {
         if ( isset( $_SESSION['size'] ) )
            $size = $_SESSION['size'];
         else
            $size = 400;
      }

      if ( isset( $_POST['levels'] ) )
         $levels = intval( $_POST['levels'] );
      else
      {
         if ( isset( $_SESSION['levels'] ) )
            $levels = $_SESSION['levels'];
         else
            $levels = 12;
      }

      if ( isset( $_POST['hue'] ) )
         $hue = intval( $_POST['hue'] );
      else
      {
         if ( isset( $_SESSION['hue'] ) )
            $hue = $_SESSION['hue'];
         else
            $hue = 300;
      }

      if ( isset( $_POST['huerange'] ) )
         $huerange = intval( $_POST['huerange'] );
      else
      {

         if ( isset( $_SESSION['huerange'] ) )
            $huerange = $_SESSION['huerange'];
         else
            $huerange = 360;
      }

      if ( isset( $_POST['saturation'] ) )
         $saturation = $_POST['saturation'];
      else
      {
         if ( isset( $_SESSION['saturation'] ) )
            $saturation = $_SESSION['saturation'];
         else
            $saturation = 0.46;
      }

      if ( isset( $_POST['value'] ) )
         $value = $_POST['value'];
      else
      {
         if ( isset( $_SESSION['value'] ) )
            $value = $_SESSION['value'];
         else
            $value = 0.96;
      }

      if ( isset( $_POST['color'] ) )
         $color = $_POST['color'];
      else
      {
         if ( isset( $_SESSION['color'] ) )
            $color = $_SESSION['color'];
         else
            $color = '0, 0, 0';
      }

      if ( isset( $_POST['example'] ) )
      {
         $last_input = '';
         $center = '';
      }

      if ( $center == '' )
      {
         if ( $last_input != '' ) $center = $last_input;
         else 
         {
            $m = mt_rand( 0, count( $this->examples ) - 1 );
            
            $center = $this->examples[$m][0];
            $radius = $this->examples[$m][1];
            $levels = $this->examples[$m][2];
            $size = $this->examples[$m][3];
            $huerange = $this->examples[$m][4];
            $hue = $this->examples[$m][5];
            $saturation = $this->examples[$m][6];
            $value = $this->examples[$m][7];
            $color = $this->examples[$m][8];
         }
      }

      /**
       * Calculate top-left coordinate
      */
      $center_p = explode(',', $center);
      $left = $center_p[0] - $radius;
      $top = $center_p[1] + $radius;

      /**
       * Link to change view
       */
      $view_link = $view == 'text' ? '<b>Text</b> | ' : '<a href="' . mprewriteurl( 'index.php?' . $qstring . 'sub2=text' ) . '">Text</a> | ';
      $view_link .= $view == 'examples' ? '<b>' . MPVIEWER_EXAMPLES . '</b> | ' : '<a href="' . mprewriteurl( 'index.php?' . $qstring . 'sub2=examples' ) . '">' . MPVIEWER_EXAMPLES . '</a> | ';
      $view_link .= $view == 'code' ? '<b>' . MPVIEWER_CODE . '</b>' : '<a href="' . mprewriteurl( 'index.php?' . $qstring . 'sub2=code' ) . '">' . MPVIEWER_CODE . '</a>';
      $view_link .= "<br /><br />\n";

?>

   <script>
   function showXY(e) 
   {
   	var posx = 0;
   	var posy = 0;
   	if (!e) var e = window.event;
   	if (e.pageX || e.pageY)
      {
         posx = e.pageX;
         posy = e.pageY;
      }
   	else if (e.clientX || e.clientY)
      {
         posx = e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft - 2;
         posy = e.clientY + document.documentElement.scrollTop + document.body.scrollTop - 2;
      }
      var targ;
      if (e.target) targ = e.target;
      else if (e.srcElement) targ = e.srcElement;
      var offset_left = targ.offsetLeft;
      var offset_top = targ.offsetTop;
      while (targ = targ.offsetParent) 
      {
         offset_left += targ.offsetLeft;
         offset_top += targ.offsetTop;
      }
      posx = posx - offset_left;
      posy = posy - offset_top;
      document.getElementById('new_center').innerHTML = (left+2*posx*radius/size)+', '+(top-2*posy*radius/size);
   }
   function submitForm(e) 
   {
   	var posx = 0;
   	var posy = 0;
   	if (!e) var e = window.event;
   	if (e.pageX || e.pageY)
      {
         posx = e.pageX;
         posy = e.pageY;
      }
   	else if (e.clientX || e.clientY)
      {
         posx = e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft - 2;
         posy = e.clientY + document.documentElement.scrollTop + document.body.scrollTop - 2;
      }
      var targ;
      if (e.target) targ = e.target;
      else if (e.srcElement) targ = e.srcElement;
      var offset_left = targ.offsetLeft;
      var offset_top = targ.offsetTop;
      while (targ = targ.offsetParent) 
      {
         offset_left += targ.offsetLeft;
         offset_top += targ.offsetTop;
      }
      posx = posx - offset_left;
      posy = posy - offset_top;
      document.forms[0].center.value = (left+2*posx*radius/size)+', '+(top-2*posy*radius/size);
      document.forms[0].submit();
   }
 
   var top = <?php echo $top ?>;
   var left = <?php echo $left ?>;
   var radius = <?php echo $radius ?>;
   var size = <?php echo $size ?>;
   </script>

   <h3><?php echo MPVMANDELBROT_TITLE ?></h3>
   <?php echo MPVMANDELBROT_MAIN_0 ?><br />

   <?php echo str_replace( '##VERSION2##', MAXIMAPHP_VERSION, str_replace( '##VERSION1##', MAXIMA_VERSION, MPVIEWER_POWERED_BY ) ) ?><br />

   

   <br />
   <?php echo $view_link ?>
   <form action="" method="post">
   <input type="hidden" name="submitted" />
   <table>
   
   <tr><td valign="top"><?php echo MPVMANDELBROT_MAIN_1 ?> </td><td colspan="3"><input type="text" name="center" size="39" value="<?php echo $center ?>" /><span class="eg"><?php echo MPVIEWER_EG ?> 0.282, -0.01</span></td></tr>
   <tr><td valign="top"><?php echo MPVMANDELBROT_MAIN_2 ?></td><td valign="top"><input type="text" name="radius" size="19" value="<?php echo $radius ?>" /></td><td valign="top"><?php echo MPVMANDELBROT_MAIN_3 ?></td><td valign="top"><input type="text" name="levels" size="5" value="<?php echo $levels ?>" /></td></tr>
   <tr><td valign="top"><?php echo MPVMANDELBROT_MAIN_12 ?> </td><td><input type="text" name="size" size="5" value="<?php echo $size ?>" /> <span class="eg"><?php echo MPVMANDELBROT_MAIN_13 ?></span></td><td valign="top"><?php echo MPVMANDELBROT_MAIN_5 ?> </td><td><input type="text" name="huerange" size="5" value="<?php echo $huerange ?>" /> <span class="eg">(-360 ~ 360)</span></td></tr>
   <tr><td colspan="4" style="border:solid thin black"><?php echo MPVMANDELBROT_MAIN_11 ?>
   <table width="100%">
   <tr><td valign="top"><?php echo MPVMANDELBROT_MAIN_4 ?> </td><td><input type="text" name="hue" size="5" value="<?php echo $hue ?>" /> <span class="eg">(0 ~ 360)</span>, </td><td valign="top"><?php echo MPVMANDELBROT_MAIN_6 ?> </td><td><input type="text" name="saturation" size="5" value="<?php echo $saturation ?>" /> <span class="eg">(0 ~ 1)</span>, </td><td valign="top"><?php echo MPVMANDELBROT_MAIN_7 ?> </td><td><input type="text" name="value" size="5" value="<?php echo $value ?>" /> <span class="eg">(0 ~ 1)</span></td></tr>
   </table></td></tr>
   <tr><td valign="top"><?php echo MPVMANDELBROT_MAIN_8 ?> </td><td colspan="3"><input type="text" name="color" size="29" value="<?php echo $color ?>" /> <span class="eg">h, s, v (<?php echo MPVIEWER_EG ?> 0, 0, 0)</span></td></tr>
   <tr><td align="left"><input type="submit" /></td><td align="left"><input type="button" value=" See the Julia " onclick="forms[1].parameter.value=forms[0].center.value;forms[1].submit();return false" /></td><td align="right" colspan="2"><input type="submit" name="example" value=" <?php echo MPVIEWER_EXAMPLE ?> " /></td></tr>
   </table>
   </form>

   <form action="http://www.my-tool.com<?php $julia = $_SERVER["REQUEST_URI"] . '/julia/'; $julia = str_replace( 'mandelbrot/julia', 'julia', str_replace( '//', '/', $julia ) ); echo $julia ?>" method="post">
   <input type="hidden" name="submitted" />
   <input type="hidden" name="parameter" value="<?php echo $center ?>" />
   <input type="hidden" name="center" value="0, 0" />
   <input type="hidden" name="radius" value="1.5" />
   <input type="hidden" name="levels" value="36" />
   <input type="hidden" name="size" value="400" />
   <input type="hidden" name="huerange" value="360" />
   <input type="hidden" name="hue" value="300" />
   <input type="hidden" name="saturation" value="1" />
   <input type="hidden" name="value" value="1" />
   <input type="hidden" name="color" value="0, 0, 0" />
   </form>

<?php

      /**
       * Instantiate MaximaPHP if 'submit' or 'example' button was pressed
       */
      if ( isset( $_POST['submitted'] ) or isset( $_POST['example'] ) )
      {
         require_once( 'maximaphp.php' );
   
         /**
          * Security check for all text inputs
          */
         $maximaphp = new MaximaPHP( $center, $last_input, $last_output );
         $center = $maximaphp->secure();
         $maximaphp->setInput( $radius );
         $radius = $maximaphp->secure();
         $maximaphp->setInput( $size );
         $size = $maximaphp->secure();
         $maximaphp->setInput( $levels );
         $levels = $maximaphp->secure();
         $maximaphp->setInput( $hue );
         $hue = $maximaphp->secure();
         $maximaphp->setInput( $huerange );
         $huerange = $maximaphp->secure();
         $maximaphp->setInput( $saturation );
         $saturation = $maximaphp->secure();
         $maximaphp->setInput( $value );
         $value = $maximaphp->secure();
         $maximaphp->setInput( $color );
         $color = $maximaphp->secure();

         /**
          * Prints error message in case unsecure input
          */
         if ( !$maximaphp->isSecure() )
         {
            $maximaphp->getSecurityWarning();
         }

         /**
          * Otherwise send input to Maxima
          */
         else if ( $center != '' ) 
         {
            $options = "[center, $center], [radius, $radius], [levels, $levels], [size, $size], [huerange, $huerange], [hue, $hue], [saturation, $saturation], [value, $value], [color, $color]";
            $tomaxima = <<<EOT
/*
 * Put your Maxima code to do calculation here
 * it should be free of unsecure commands
 */
load("dynamics");
block
(
 disp(":| options |:"),
 [##OPTIONS##]
);
disp(":|o|:");
block
(
 disp(":| mandelbrot |:"),
 mandelbrot(##OPTIONS##)
)
EOT;
            $_SESSION['last_input'] = $center;
            $_SESSION['radius'] = $radius;
            $_SESSION['size'] = $size;
            $_SESSION['levels'] = $levels;
            $_SESSION['hue'] = $hue;
            $_SESSION['huerange'] = $huerange;
            $_SESSION['saturation'] = $saturation;
            $_SESSION['value'] = $value;
            $_SESSION['color'] = $color;

            /**
             * Do some little pre-processing combining $options and $tomaxima such as
             */
            $tomaxima = str_replace( '##OPTIONS##', $options, $tomaxima );

            /**
             * Set new input to Maxima
             */
            $maximaphp->setInput( $tomaxima );

            /**
             * Since it is already secure we could bypass security
             */
            $maximaphp->bypassSecurity();

            $result = $maximaphp->execute( $view );
            $result = $this->formatOutput( $result, $size );

            $_SESSION['last_output'] = $maximaphp->lastOutput;

            /** 
             * Output the result
             */

?>

   <pre>
<?php
   printf( MPVIEWER_CALCULATION_TIME, $maximaphp->totalTime );
   echo $result;
?>
   </pre>

<?php        
            /** 
             * Print out Maxima code
             */
            if ( $view == 'code' )
            {
?>

<?php echo MPVMANDELBROT_MAIN_9 ?><br /><br />
<textarea rows="20" cols="60" style="border:none" wrap="off" readonly="readonly">
<?php echo MPVMANDELBROT_MAIN_10 . "\n" . htmlentities( $tomaxima ) ?>
</textarea>

<?php
            }
         }
      }
   
      /**
       * Print out examples
       */
      echo $this->getExamples( $view == 'examples' ? 0 : 5 );

?>

<?php
   }
}

?>
Return current item: MaximaPHP