Bezier area

Area under a Berzier curve

by Richard Morris

HTML

<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<canvas id="canvas" width=400 height=300></canvas>
<br/>Num point:
<input id="nPts" name="sang" value="5" size="5" />
<br/>
<input id="goBut" type="button" value="Go" />Area:
<input id="area" name="sang" value="5" size="5" />

CSS

body {
    background-color: ivory;
}
#canvas {
    border:1px solid green;
}

JavaScript

// canvas and mousedown related variables
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();

// save canvas size to vars b/ they're used often
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;

// The control points
// The control points
//var P = [{X:  13, Y: 224 }, 
//         {X: 150, Y: 100 }, 
//         {X: 251, Y:  93 }, 
//         {X: 341, Y: 224 }, ];

var P = [{X: 120, Y: 160 }, 
         {X:  35, Y: 200 }, 
         {X: 220, Y: 260 }, 
         {X: 180, Y:  40 }, ];

ctx.lineWidth = 6;
ctx.strokeStyle = "#333";
ctx.beginPath();
ctx.moveTo(P[0].X, P[0].Y);
ctx.bezierCurveTo(P[1].X, P[1].Y, P[2].X, P[2].Y, P[3].X, P[3].Y);
ctx.stroke();

// draw the control polygon
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(P[0].X, P[0].Y);
ctx.lineTo(P[1].X, P[1].Y);
ctx.lineTo(P[2].X, P[2].Y);
ctx.lineTo(P[3].X, P[3].Y);
ctx.stroke();

function evalBez(poly, t) {
    var x = poly[0] * (1 - t) * (1 - t) * (1 - t) + 3 * poly[1] * t * (1 - t) * (1 - t) + 3 * poly[2] * t * t * (1 - t) + poly[3] * t * t * t;
    return x;
}

var PX = [P[0].X, P[1].X, P[2].X, P[3].X];
var PY = [P[0].Y, P[1].Y, P[2].Y, P[3].Y];

function findarea(n) {
    ctx.lineWidth = 3;
    ctx.strokeStyle = "#f00";
    ctx.beginPath();

    var nSteps = n - 1;
    var x = [P[0].X];
    var y = [P[0].Y];
    ctx.moveTo(x[0], y[0]);

    var area = 0.0;
    for (var i = 1; i <= nSteps; ++i) {
        var t = i / nSteps;
        x[i] = evalBez(PX, t);
        y[i] = evalBez(PY, t);
        ctx.lineTo(x[i], y[i]);
        area += (x[i] - x[i - 1]) * (y[i - 1] + y[i]) / 2;
        if (x[i] < x[i - 1]) alert("Not strictly increasing in x, area will be incorrect");
    }
    ctx.stroke();
    $("#area").val(area);
}

function findBB() {
    var a = 3 * P[3].X -...