CraftyJS Quadratic Bézier curve

by Kieran Dang

HTML

<script src="https://rawgithub.com/craftyjs/Crafty/release/dist/crafty-min.js"></script>
<img src='http://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/Bezier_2_big.gif/240px-Bezier_2_big.gif' />
<div id="game"></div>

JavaScript

Crafty.init(600, 600);

// Quadratic Bézier curve.
// http://mathworld.wolfram.com/QuadraticCurve.html
// x(t) = (1-t)^2 * x1 + 2 * (1-t) * t * x2 + t^2 * x3
// y(t) = (1-t)^2 * y1 + 2 * (1-t) * t * y2 + t^2 * y3

// (x1, y1) is the starting point, (x2, y2) is the control point and (x3, y3) is the end point.

// moveTo(sx, sy), quadraticCurveTo(cpx, cpy, ex, ey)

Crafty.c('Parabola', {
    Parabola: function (sx, sy, ex, ey, h, color) {
        this.x = this.sx = sx;
        this.y = this.sy = sy;

        this.ex = ex;
        this.ey = ey;

        this.w = Math.abs(sx - ex);
        
        // A(sx, sy), B(ex, ey), M(mx, my) middle AB
        // Control point C(cpx, cpy)

        //var mx = (sx + ex) / 2;
        //var my = (sy + ey) / 2;        
        
        // dx = sx - ex and dy = sy - ey, then the normals of AB are n1 = (-dy, dx) and n2 = (dy, -dx).        
        // n3 = (dx, dy) normal vector of line MC

        // Solve 
        // 1: (x - cpx)dx + (y - cpy)dy = 0
        // 2: sqrt[square(cpx - mx) + square(cpy -my)]

        this.cpx = sx + this.w / 2;
        this.cpy = sy - h;
        this.h = h;

        this.color = color || '#000000';

        return this;
    },

    draw: function () {
        var ctx = Crafty.canvas.context;
        ctx.save();

        // Starting point
        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.strokeStyle = '#0000FF';
        ctx.arc(this.sx + 1, this.sy + 1,
        3, 0, Math.PI * 2);
        ctx.stroke();

        // Endpoint
        ctx.moveTo(this.ex, this.ey);
        ctx.arc(
        this.ex + 1,
        this.ey + 1,
        2,
        0,
        Math.PI * 2);
        ctx.stroke();
        
        // Control point
        ctx.moveTo(this.cpx, this.cpy);
        ctx.arc(
        this.cpx + 1,
        this.cpy + 1,
        2,
        0,
        Math.PI * 2);
        ctx.stroke();        

        ctx.beginPath();
        ctx.lineWidth = 2;
        ctx.strokeStyle = this.color;

       ...