Koch Snowflake Generator - Example of DOM based interactive document
authorSam Moore <[email protected]>
Tue, 20 May 2014 04:03:50 +0000 (12:03 +0800)
committerSam Moore <[email protected]>
Tue, 20 May 2014 04:03:50 +0000 (12:03 +0800)
The literature review seems to have devolved into trying to make the coolest figures...

It's a shame you can't embed HTML in PDF oh god what am I saying

figures/koch.html [new file with mode: 0644]
figures/koch.js [new file with mode: 0644]

diff --git a/figures/koch.html b/figures/koch.html
new file mode 100644 (file)
index 0000000..65945d9
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+       <head>
+               <title>SVG and Koch's Fractal</title>
+               <script type="text/javascript" src="koch.js"></script>
+       </head>
+<body>
+       <h1> Koch's Snowflake </h1>
+       <p> An example of using the DOM to make a fractal --- an interactive document.</p>
+       <p> <b>Warning:</b> If you iterate too many times you will likely crash your browser </p>
+       <svg
+               id="kochSVG"
+               xmlns="http://www.w3.org/2000/svg"
+               version="1.1"
+               width="400"
+               height="400"
+       >
+               <path
+                       id="line"
+                       style="stroke:#000000; fill:none; stroke-width:1px;"
+                       d = "M 100,100 300,100 200,273.2051 100,100"
+               />
+       </svg>
+       <p></p>
+       <table>
+               <tr> <td> Inwards <input type="radio" name="dir" id="dir_in"/> Outwards <input type="radio" name="dir" value="dir_out" checked="yes"/> </td> </tr>
+               <tr> <td> Insert <input type="radio" name="mode" id="mode_insert" checked="yes"/> Append <input type="radio" name="mode" id="mode_append"/> </td> </tr>
+               <tr> <td> <input type="text" value="1" id="iterations"/> <button onclick="iterateKoch();">Koch Iterate</button> </td> </tr>
+               <tr> <td> <input type="text" value="#000000" id="stroke"/> <button onclick="stroke();">Stroke Colour</button> </td> </tr>       
+               <tr> <td> <input type="text" value="none" id="fill"> <button onclick="fill();">Fill Colour</button> </td> </tr>
+               <tr> <td> <input type="text" value="1" id="stroke-width"/> <button onclick="strokeWidth();">Stroke Thickness</button> </td> </tr>
+               <tr> <td><button onclick="reset();">Reset</button> <button onclick="svgToText();">Standalone SVG</button></td></tr>
+       </table>
+       <p id="debug"></p>
+</body>
+</html>
diff --git a/figures/koch.js b/figures/koch.js
new file mode 100644 (file)
index 0000000..7ff1164
--- /dev/null
@@ -0,0 +1,140 @@
+/**
+ * This code will perform the koch snowflake iteration on svg paths
+ * Wierd things might happen if the path isn't a straight line path
+ */
+
+
+function koch(direction, mode)
+{
+       var svgs = document.getElementsByTagName("svg");
+       for (var i = 0; i < svgs.length; ++i)
+       {
+               var paths = svgs[i].getElementsByTagName("path");
+               for (var j = 0; j < paths.length; ++j)
+               {
+                       var d = paths[j].getAttribute("d").split(/[\s,]+/);
+                       var x = [];
+                       var y = [];
+                       for (var k = 0; k < d.length; ++k)
+                       {
+                               var asfloat = parseFloat(d[k]);
+                               if (isNaN(asfloat)) continue;
+                               var coord = (y.length == x.length) ? x : y;
+                               coord.push(asfloat);
+                       }
+                       var result = "M";
+                       for (var k = 0; k < x.length-1; ++k)
+                       {
+                               var s = [x[k+1]-x[k], y[k+1]-y[k]];
+                               var dist = Math.pow(Math.pow(s[0],2) + Math.pow(s[1],2),1/2);
+                               var n = [-s[1]/dist, s[0]/dist]; // normal vector
+                               var a = [0,0];
+                               var b = [0,0];
+                               var c = [0,0];
+                               for (var ii = 0; ii < 2; ++ii)
+                               {
+                                       var p = (ii == 0 ? x : y);
+                                       a[ii] = p[k] + s[ii]/3;
+                                       b[ii] = p[k] + 2*s[ii]/3;
+                                       if (direction == "in")
+                                       {
+                                               c[ii] = p[k] + s[ii]/2 + dist/3 * n[ii];
+                                       }
+                                       else if (direction == "out")    
+                                       {
+                                               c[ii] = p[k] + s[ii]/2 - dist/3 * n[ii];
+                                       }
+                               }
+
+                               result += " " + x[k]+","+y[k] + " "+a.join(",") + " " + c.join(",") + " " + b.join(",");
+                               if (mode == "append")
+                                       result += " " + a.join(",") + " " + b.join(",");
+                               
+                                       
+                       }
+                       result += " " + x[x.length-1]+","+y[x.length-1];
+
+
+                       //document.getElementById("debug").innerHTML = paths[j].getAttribute("d") + " to " + result;
+                       paths[j].setAttribute("d", result);
+               }
+       }
+}
+
+/** Helper lets us repeat the iteration **/
+function iterateKoch()
+{
+       var iterations = parseFloat(document.getElementById("iterations").value);
+       var direction = (document.getElementById("dir_in").checked) ? "in" : "out";
+       var mode = (document.getElementById("mode_insert").checked) ? "insert" : "append";
+       if (!isNaN(iterations))
+       {
+               for (var i = 0; i < iterations; ++i) koch(direction, mode);
+       }
+}
+
+/** Change stroke thickness **/
+function strokeWidth()
+{
+       var thickness = parseFloat(document.getElementById("stroke-width").value);
+       if (isNaN(thickness)) return;
+
+       var svgs = document.getElementsByTagName("svg");
+       for (var i = 0; i < svgs.length; ++i)
+       {
+               var paths = svgs[i].getElementsByTagName("path");
+               for (var j = 0; j < paths.length; ++j)
+               {
+                       paths[j].style.strokeWidth = thickness+"px";
+               }
+       }
+}
+
+
+/** Change fill **/
+function fill()
+{
+       var fill = document.getElementById("fill").value;
+
+       var svgs = document.getElementsByTagName("svg");
+       for (var i = 0; i < svgs.length; ++i)
+       {
+               var paths = svgs[i].getElementsByTagName("path");
+               for (var j = 0; j < paths.length; ++j)
+               {
+                       paths[j].style.fill = fill;
+               }
+       }
+}
+
+/** Change stroke colour **/
+function stroke()
+{
+       var stroke = document.getElementById("stroke").value;
+
+       var svgs = document.getElementsByTagName("svg");
+       for (var i = 0; i < svgs.length; ++i)
+       {
+               var paths = svgs[i].getElementsByTagName("path");
+               for (var j = 0; j < paths.length; ++j)
+               {
+                       paths[j].style.stroke = stroke;
+               }
+       }
+}
+
+function reset()
+{
+       document.getElementById("line").setAttribute("d", "M 100,100 300,100 200,273.2051 100,100");
+       document.getElementById("line").setAttribute("style", "stroke:#000000; fill:none; stroke-width:1px;");
+}
+
+function svgToText()
+{
+       var data = "<svg id=\"kochSVG\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"400\" height=\"400\">";
+       data += "<path id=\"line\" style=\"stroke:"+document.getElementById("stroke").value+"; fill:"+document.getElementById("fill").value+"; stroke-width:"+document.getElementById("stroke-width").value+"px;\" d=\""+document.getElementById("line").getAttribute("d")+"\"/>";
+       data += "</svg>"
+       var win = window.open("image/svg+xml");
+       win.document.write(data);
+       win.focus();
+}

UCC git Repository :: git.ucc.asn.au