Convex hull of 4 points using gift wraping algorithm

gift wrapping is inefficient in the general case, but it is easy to code and with only 4 points the order of the algorithm is irrelevant.

HTML

<p>You can drag points around with the mouse.<br />They will snap to neighbours to allow easy check of co-incident points</p>
<p>The convex hull is in blue, the outline of the four points in green</p>
<canvas id='canvas' width=200 height=200></canvas>
<p id='comment'></p>

CSS

canvas {
    background : #aaa;
}

JavaScript

function Point (x, y)
{
	this.x = x;
	this.y = y;
}
Point.prototype.equals = function (p)
{
	return this.x == p.x && this.y == p.y;
};

Point.prototype.distance = function (p)
{ 
	return Math.sqrt (Math.pow (this.x-p.x, 2) 
                    + Math.pow (this.y-p.y, 2));
};

function convex_hull (points)
{
	function left_oriented (p1, p2, candidate)
	{
		var det = (p2.x - p1.x) * (candidate.y - p1.y) 
                - (candidate.x - p1.x) * (p2.y - p1.y);
		if (det > 0) return true;  // left-oriented 
		if (det < 0) return false; // right oriented
		// select the farthest point in case of colinearity
		return p1.distance (candidate) > p1.distance (p2);
	}

    var N = points.length;
    var hull = [];

    // get leftmost point
	var min = 0;
	for (var i = 1; i != N; i++)
	{
		if (points[i].y < points[min].y) min = i;
	}
	hull_point = points[min];

    // walk the hull
    do
	{
		hull.push(hull_point);
		
		var end_point = points[0];
		for (var i = 1; i != N; i++) 
		{
			if (  hull_point.equals (end_point)
			   || left_oriented (hull_point, 
                                 end_point, 
                                 points[i]))
			{
				end_point = points[i];
			}
		}
		hull_point = end_point;
	}
	/*
     * must compare coordinates values (and not simply objects)
	 * for the case of 4 co-incident points
	 */
	while (!end_point.equals (hull[0])); 
	return hull;
}

// --------------------------------------------------------
// demo code
// --------------------------------------------------------
function Demo (canvas, points)
{
	this.drawPoly = function (points)
	{
		this.draw.beginPath();
		this.draw.moveTo (points[0].x, points[0].y);
		for (var i = 1 ; i != points.length ; i++)
		{
			var p = points[i];
			this.draw.lineTo (p.x, p.y);
		}
		this.draw.closePath();
	}
	
	function getCursorPosition(e)
	{
		var x, y;
		if (e.pageX != undefined && e.pageY != undefined)
		{
			x = e.pageX;
			y = e.pageY;
		}
		else
		{
			x = e.clientX + document.body.scrollLeft...