Points on Arc Circumference

Example source code


<!DOCTYPE html>
<html>
<head>

<script type="text/javascript">
var ctx = null, game = null;
var circleX = 30, circleY = 20, radius = 10;
var pointList = null, fullPointList = null;
var arcRadius = 1;
var arcStart = Math.PI*0.5, arcEnd = Math.PI*0.8;
var mouseX = 0, mouseY = 0;

window.onload = function() {
	game = document.getElementById('game');
	ctx = game.getContext('2d');
	ctx.font = "bold 10pt sans-serif";

	pointList = pointsInArc(circleX, circleY, radius, arcStart, arcEnd);

	game.addEventListener('mousemove', function(e) {
		// Get the position of the mouse click on the page
		x = e.pageX;
		y = e.pageY;

		// Find the offset of the Canvas relative to the document top, left,
		// and modify the mouse position to account for this
		var p = game;
		do
		{
			x-= p.offsetLeft;
			y-= p.offsetTop;

			p = p.offsetParent;
		} while(p!=null);

		// fit the real mouse position to our 10x10 grid
		x = Math.floor(x / 10);
		y = Math.floor(y / 10);
		
		mouseX = x;
		mouseY = y;

		// Find the angle between the circle centre and here
		var a = getAngle(circleX, circleY, x, y);
		arcStart 	= a - (arcRadius / 2);
		arcEnd		= a + (arcRadius / 2);

		pointList = pointsInArc(circleX, circleY, radius, arcStart, arcEnd);
	});
	window.addEventListener('keypress', function(e) {
		// Increase / decrease the arc radius
		if(e.keyCode==39) { arcRadius+= 0.1; }
		else if(e.keyCode==37) { arcRadius-= 0.1; }

		// Correct for too small / too large
		if(arcRadius<0.1) { arcRadius = 0.1; }
		if(arcRadius>(Math.PI*2)) { arcRadius = (Math.PI*2); }
		
		// Find the angle between the circle centre and the mouse
		var a = getAngle(circleX, circleY, mouseX, mouseY);
		arcStart 	= a - (arcRadius / 2);
		arcEnd		= a + (arcRadius / 2);

		// Update the list of points on the circles circumference
		pointList = pointsInArc(circleX, circleY, radius, arcStart, arcEnd);

		// Show a list of points for information
		var htm = '';
		for(p in pointList)
		{
			htm+= '<li>' + pointList[p][0] + ', ' + pointList[p][1] + '</li>';
		}
		document.getElementById('pointList').innerHTML = htm;
	});

	requestAnimationFrame(drawGame);
};

function pointsInArc(cx, cy, cr, angleStart, angleEnd)
{
	var list	= pointsOnCircumference(cx, cy, cr);
	var arc		= new Array();
	
	for(i in list)
	{
		var a = getAngle(cx, cy, list[i][0], list[i][1]);

		if(angleStart < 0 && (a >= (Math.PI*2 + angleStart))) { arc.push(list[i]); }
		else if(angleEnd > (Math.PI*2) && a <= (angleEnd - (Math.PI*2))) { arc.push(list[i]); }
		else if(a>=angleStart && a<=angleEnd) { arc.push(list[i]); }
	}
	
	return arc;
}

function pointsOnCircumference(cx, cy, cr)
{
	var list = new Array();
	
	var x = cr;
	var y = 0;
	var o2 = Math.floor(1 - x);

	while(y <= x)
	{
		list.push([ x + cx,  y + cy]);
		list.push([ y + cx,  x + cy]);
		list.push([-x + cx,  y + cy]);
		list.push([-y + cx,  x + cy]);
		list.push([-x + cx, -y + cy]);
		list.push([-y + cx, -x + cy]);
		list.push([ x + cx, -y + cy]);
		list.push([ y + cx, -x + cy]);

		y+= 1;

		if(o2 <= 0) { o2+= (2 * y) + 1; }
		else
		{
			x-= 1;
			o2+= (2 * (y - x)) + 1;
		}
	}

	return list;
}

function getAngle(x, y, x2, y2)
{
	var a = Math.atan2(y2 - y, x2 - x);
	return a < 0 ? a + (Math.PI * 2) : a;
}

function drawGame()
{
	if(ctx==null) { return; }

	// Clear the Canvas
	ctx.fillStyle = "#ffffff";
	ctx.fillRect(0, 0, 600, 400);

	// Draw the grid
	ctx.strokeStyle = "#999999";
	ctx.beginPath();
	for(y = 0; y < (400/10); ++y)
	{
		for(x = 0; x < (600/10); ++x)
		{
			ctx.rect((x*10), (y*10), 10, 10);
		}
	}
	ctx.closePath();
	ctx.stroke();
	
	// Draw the centre of the circle
	ctx.fillStyle = "#aaaaff";
	ctx.strokeStyle = "#0000dd";
	ctx.fillRect(circleX*10, circleY*10, 10, 10);
	ctx.strokeRect(circleX*10, circleY*10, 10, 10);
	
	// Draw the points on the circles edge
	ctx.fillStyle = "#ff9999";
	ctx.strokeStyle = "#ff3333";
	ctx.beginPath();
	for(p in pointList)
	{
		ctx.rect(pointList[p][0] * 10, pointList[p][1] * 10, 10, 10);
	}
	ctx.closePath();
	ctx.fill();
	ctx.stroke();

	// Show some information...
	ctx.fillStyle = "#ff0000";
	ctx.fillText("Circle at " + circleX + "," + circleY + " radius " + radius, 10, 20);
	ctx.fillText("Arc radius: " + arcRadius.toFixed(2) + ", start: " + arcStart.toFixed(2) + ", end: " + arcEnd.toFixed(2), 10, 40);

	// Ask for the next animation frame
	requestAnimationFrame(drawGame);
}
</script>
</head>
<body>

<p>Move the mouse around the grid to change the direction of the arc.  Press the ledt arrow key to reduce the arc radius, and the right arrow key to increase it.  If you do not see the grid and arc, please check you have Javascript enabled and that your browser supports the Canvas element.</p>

<canvas id="game" width="600" height="400"></canvas>
<ul id="pointList" style="font-family:monospace;"></ul>

</body>
</html>

Page loaded in 0.012 second(s).