Zion curve

by Mikel Ortega

HTML

<canvas id="photo" width=400 height=400 style="position: absolute;"></canvas>
<canvas id="graph" width=400 height=400 style="position: absolute;"></canvas>

JavaScript

var canvas = document.getElementById('graph'),
    ctx = canvas.getContext('2d');
var photo_canvas = document.getElementById('photo'),
    photo_ctx = photo_canvas.getContext('2d');
var img = new Image();

img.onload = start;
img.src = 'http://farm4.staticflickr.com/3764/11007136095_45c3abaeba_n.jpg';

function start() {
    photo_ctx.drawImage(img, 0, 0, photo.width, photo.height);
    canvas.onmousemove = updateLine;
    drawFixedGraph();
}

function MagicCurve(y) {
    return (y * y - y + 0.15) * (-0.65) * Math.cos(1.17 / (y-0.1)) - 0.30;
}

function photoX(x) {
    return (1.0 + x) * 0.5 * photo.width;
}

function photoY(y) {
    return (1.0 - y) * 0.5 * photo.height;
}

function drawFixedGraph() {
    for (var y = -1.0; y < 1.0; y = y + 0.001) {

        var x = MagicCurve(y);

        ctx.strokeStyle = '#fff';
        ctx.beginPath();
        ctx.arc(photoX(x), photoY(y), 1, 0, 2 * Math.PI);
        ctx.stroke();
    }
    ctx.beginPath();
    ctx.moveTo(photoX(-1), photoY(0));
    ctx.lineTo(photoX(1), photoY(0));
    ctx.moveTo(photoX(0), photoY(-0.8));
    ctx.lineTo(photoX(0), photoY(1));
    ctx.font="12px Courier";
    ctx.strokeText("X = (Y^2+Y+a)*b*cos(c/(Y+d)) + e",photoX(-0.4), photoY(-0.9));
    ctx.stroke();
}

function updateLine(e) {
    var r = canvas.getBoundingClientRect();
    var gy = e.clientY - r.top;
    var y = -2.0 * gy / photo.height + 1.0;

    var x = MagicCurve(y);

    ctx.strokeStyle = '#fff';
    ctx.beginPath();
    ctx.arc(photoX(x), photoY(y), 4, 0, 2 * Math.PI);
    ctx.stroke();
}