Here's the image:
And here's the SVG source code:
<?xml version="1.0" encoding="UTF-8"?> <svg version="1.1" width="800" height="600" xmlns="http://www.w3.org/2000/svg" contentScriptType="text/ecmascript" > <!-- Runge-Kutta Method SVG Demo (c) soonts.livejournal.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="560" font-size="14pt" 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,300) scale( 350, -270 )" 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>