This will also be online at http://pobox.com/~kragen/sw/lame.html for easier viewing. Like everything else posted here without a notice to the contrary, I dedicate this to the public domain. <html><head><title>Curves of Lamé</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- about an hour of work, 2007-02-08 --> <script type="text/javascript">//<![CDATA[ function $(id) { return document.getElementById(id) } function drawCurve(ctx, points, x, y) { ctx.beginPath() ctx.moveTo(0, y) for (var ii = 0; ii < points.length; ii++) { ctx.lineTo(points[ii][0] * x, points[ii][1] * y) } ctx.stroke() } function redraw(canvas, exponent) { var ctx = canvas.getContext('2d') var w = canvas.width var h = canvas.height ctx.strokeStyle = 'grey' // set coordinate system ctx.save() ctx.translate(w/2, h/2) // the -1s are so that antialiased lines don't become half-width // when they reach the edge: ctx.scale(w/2-1, h/2-1) ctx.lineWidth = 1/(w/2-1) // draw axes if ($('draw_axes').checked) { ctx.moveTo(-1, 0) ctx.lineTo(1, 0) ctx.moveTo(0, -1) ctx.lineTo(0, 1) ctx.stroke() } // compute a point per pixel var points = [] for (var xx = 0; xx <= 1; xx += 1/(w/2-1)) { // x^n + y^n = 1; y = (1 - x^n)^(1/n) var yy = Math.pow(1 - Math.pow(xx, exponent), 1/exponent) points.push([xx, yy]) } points.push([1, 0]) // ensure it's closed to take care of numerical error // draw them drawCurve(ctx, points, 1, 1) drawCurve(ctx, points, 1, -1) drawCurve(ctx, points, -1, 1) drawCurve(ctx, points, -1, -1) // restore coordinate system ctx.restore() } function cls(canvas) { canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height) } function draw() { var ss = $('exponent') redraw($('canvas'), ss.options[ss.selectedIndex].value) } function erase_old() { cls($('canvas')) draw() } // ]]> </script> </head> <body onload="draw()"> <h1>Curves of Lamé</h1> <div style="float:right; margin-left: 0.5em"> <div> <label for="exponent">Exponent: </label><select onchange="draw()" id="exponent"> <option>0.125</option> <option>0.25</option> <option>0.368</option> <option>0.5</option> <option>0.707</option> <option>1</option> <option>1.414</option> <option>2</option> <option selected="selected">2.718</option> <option>3</option> <option>4</option> <option>8</option> <option>50</option> <option>500</option> <option>5000</option> </select> <button onclick="erase_old()">Erase Old</button> <input type="checkbox" id="draw_axes" checked="checked" onchange="erase_old()" /><label for="draw_axes"> Draw Axes</label> </div> <canvas id="canvas" width="400" height="400" style="margin: 0.5em"> </canvas> </div> <p>These are curves of Lamé, generalizations of the circle given by the formula <nobr><i>x<sup>n</sup> + y<sup>n</sup></i> = 1</nobr>. When <i>n</i> = 2, you get a circle; when <i>n</i> is a bit greater than 2, you get Piet Hein’s “supercircles”. He liked the effect you got when <i>n</i> was roughly <i>e</i>, which is the default here, but you can change the exponent in the drop-down box to see the different kinds of curves you can get.</p> </body></html>


