<?xml version="1.0" encoding="UTF-8"?>

<svg version="1.1" width="600" height="500" xmlns="http://www.w3.org/2000/svg" contentScriptType="text/ecmascript" >

 

<!-- Runge-Kutta Method SVG Demo (c) soonts@live.com, 2009 -->

 

<defs>

       <!-- Define the styles -->

       <style type="text/css"><![CDATA[

       line

       {

              stroke:black;

              stroke-width:0.002;

       }

       line.xy

       {

              stroke:black;

              stroke-width:0.005;

       }

       polyline

       {

              stroke:blue;

              stroke-width:0.005;

              fill:none;

       }

       ]]></style>

 

       <marker id="xyArrowHead" viewBox="0 0 10 10" refX="1" refY="5"

                     markerUnits="strokeWidth" orient="auto"

                     markerWidth="8" markerHeight="6">

              <polyline points="0,0 10,5 0,10 1,5" fill="black" style="fill:black;" />

       </marker>

 

<!-- Here goes the script itself -->    

<script> <![CDATA[

 

       // Use the Runge-Kutta method to solve the following 2 equations:

       // y1' = y2

       // y2' = f2( y1, y2 ) = ( 1 - y1^2 ) * y2 - y1

       // Origin: http://shura.luberetsky.ru/2009/04/28/reshaem-uravnenie-burbulyatora/

 

       function f2( y1, y2)

       {

              return ( 1.0 - Math.pow( y1, 2 ) ) * y2 - y1;

       }

 

       function CalcNextValue( h, obj )

       {

              var y1 = obj.y1, y2=obj.y2;

              var p11 = h * y2;

              var p12 = h * f2( y1, y2);

 

              var p21 = h * ( y2 + p12/2.0 );

              var p22 = h * f2( y1 + p11/2.0, y2 + p12/2.0 );

 

              var p31 = h * ( y2 + p22/2.0 );

              var p32 = h * f2 ( y1 + p21/2.0, y2 + p22/2.0 );

 

              var p41 = h * ( y2 + p32 );

              var p42 = h * f2( y1 + p31, y2 + p32 );

 

              obj.x += h;

              obj.y1 += ( p11 + 2.0*p21 + 2.0*p31 + p41 ) / 6.0;

              obj.y2 += ( p12 + 2.0*p22 + 2.0*p32 + p42 ) / 6.0;

       }

 

       function Plot(evt)

       {

              var svgDocument;

              if ( window.svgDocument == null )

                     svgDocument = evt.target.ownerDocument;

              else

                     svgDocument = window.svgDocument;

 

              // Much more intuitive createElement works in Opera and Adobe ActiveX but not in FF/Safari

              var p = svgDocument.createElementNS("http://www.w3.org/2000/svg","polyline");

              var strPoints, x, y;

              strPoints = "";

              var obj = {x:0, y1:0, y2:0.0001};

              var xStep = 0.1;

              var dtStart = new Date();

              while(obj.x <= 64)

              {

                     CalcNextValue(xStep, obj);

                     // The solution is X[0..64], Y[-2..+2], so we scale the values to fit the plot into the [0..2] [-1..+1] destination rectangle

                     strPoints += obj.x / 32 + "," + obj.y1 / 2.5 + " ";

              };

              var dtEnd = new Date();

 

              p.setAttribute("points", strPoints);

              svgDocument.getElementById("PlotArea").appendChild(p);

 

              var strText = "Time spent calculating: " + ( dtEnd - dtStart ) + " ms.";

              svgDocument.getElementById("TimeSpent").firstChild.nodeValue = strText

       }

]]> </script>

 

</defs>

 

<!-- The background -->

<rect width="100%" height="100%" style="fill:#CCCCCC;" />

 

<!-- Text labels -->

<text x="80" y="50" font-size="20pt" fill="green" >Runge-Kutta Method SVG Demo</text>

<text x="80" y="75" font-size="10pt" fill="black" >View source for more details</text>

 

<text id="TimeSpent" x="80" y="470" font-size="12pt" fill="black" >Time spent calculating: N/A</text>

 

<!-- Make the plot area to be be x:[0..2],y:[-1..1 ] -->

<g id="PlotArea" transform="translate(50,250) scale( 250, -220 )" onload="Plot(evt)" >

 

<!-- Add the 2 arrows -->

<line class="xy" x1="-0.05" y1="0" x2="2.05" y2="0" marker-end="url(#xyArrowHead)" />

<line class="xy" x1="0" y1="-1" x2="0" y2="1" marker-end="url(#xyArrowHead)" />

 

</g>

 

</svg>