Good JavaScript Arc Algorithm
For circle drawing, there's Bresenham's Circle Algorithm and Midpoint Circle Algorithm and a the two algorithms compared and then there's everything else such as this trigonometric circle where the guy couldn't figure a way to avoid points on the circle or ellipse having spaces in between. Here's a nice Arc maker based on the standard trigonometric circle algorithm but tweaked to create a good looking Arc.
JavaScript Charts, Graphs, Graphics, Circles, Ellipses, Arcs, Lines, and Polygons
Grab and Drop, Not Drag and Drop
Add Ids and onClicks to Divs
Add Ids and onClicks and Grab and Drop to Divs
Make Anti-alias (Almost) Lines
Make Anti-alias (Almost) Lines Using Bresenham's Line Algorithm
Good JavaScript Circle Algorithm
Good JavaScript Ellipse Algorithm
Good JavaScript Arc Algorithm
Make JavaScript Irregular Polygon
JavaScript Area of Irregular Polygon Algorithm
Make Line Chart from User-Inputted Data
Make Line Chart from CSV Data
Make Line Chart from MySQL Table Data
Make Bar Chart from User-Inputted Data
Make Bar Chart from CSV Data
Make Bar Chart from MySQL Table Data
Make Pie Chart from User-Inputted Data
Make Pie Chart from CSV Data
Make Pie Chart from MySQL Table Data
There are endless reasons to need an arc. Our reason was to supply a user-contolled circular arc drawing program where the user selects arcs of 1 degree to 360 degrees from a dropdown select list. We combed cyberspace for any sign of such a utility—a good JavaScript user-selectable arc—and we came up empty. We were hoping that by checking out the algorithm we already had, called Good JavaScript Circle Algorithm, we could determine how to adjust the circle script to make an arc script, since, as everyone who ever took geometry knows, a circular arc is just a part of a circle.
We chose to avoid jQuery and HTML5's Canvas since the former is unneeded and the latter has unsatisfactory support from browsers, and it's more fun just programming in straight JavaScript. There are JavaScript libraries around that have circle and ellipse and arc routines, but you do not learn programming by cheating! And the same can be said for using filters and transforms which each browser does their own way—there's no standard—so this requires several different functions plus browser sniffing and IE dumped support for one method and supported another with little warning. (Note: even though you can use the PHP GD library functions like imageellipse() to draw circles or ellipses or arcs on images, this may mean creating an image as big as the screen, using up RAM memory like a wild man. Even though PHP programmers use the imagedestroy() function to clear the memory BEFORE the script ends, what if image creation itself runs you out of memory? If not, the imagedestroy() function is useful to keep memory usage DURING the script to an acceptable level.)
If you'd like to see an arc algorithm written in JavaScript using the HTML5 canvas element to draw into: HTML5 Canvas Arc Tutorial.
Now, back to the problem at hand. The circle algorithm using trigonometric functions sine and cosine is fairly straightforward. The general formulas are x = xmiddle + radius * cos(angle) and y = ymiddle + radius * sin(angle) and 2PI radians = 360 degrees. Then change the normal incrementation steps to 720 and add 0.5 to increase precision, and make 3x3 points from a gif that could be replaced with an empty div with a colored background. An arc is simply using only part of this circle. Is there an easy way to accomplish this? As it turns out, there is! But only if you use a circle algorithm of the type you see here in the script on this page. There are plenty of circle algorithms—mostly programmed in C—that are more efficient and that only compute the pixels for one octant, and then the pixels can be reflected to get the whole circle, which looks like this in the midpoint circle algorithm:
setPixel(x0 + x, y0 + y);
setPixel(x0 - x, y0 + y);
setPixel(x0 + x, y0 - y);
setPixel(x0 - x, y0 - y);
setPixel(x0 + y, y0 + x);
setPixel(x0 - y, y0 + x);
setPixel(x0 + y, y0 - x);
setPixel(x0 - y, y0 - x);
Sadly, such coding is of little value for our arc goal, since it continuously draws 8 plotpoints around the circle each an octant away from the previous point, until the circle is done. Let us modify our circle script for arc drawing. Rather than going all around the circle, stop at some point. When? Easy! Simply use a select list and let the user choose 1 to 360 arc degrees. Feel free to modify this so an input box gets user-typed numbers 1 through 360. Feel free to also modify the hard-coded radius so an input box gets user-typed numbers, although we feel 200 is pretty reasonable.
In the script, after declaring relevant variables, including radius and circle center coordinates, we code the function choose(). It uses the selectedIndex property, which gives us the index of the user-selected option in our dropdown list. These start at zero, like so many arrays of this kind. Now, knowing which option was picked is fine, but now we need to know its value, so we get it with document.myform.selectarcdegrees.options[Selected].value, where the form name is myform and the select tag name is selectarcdegrees, and the select options collection is the list (as an array) of all the options in a dropdown list, so options[Selected].value gives us the needed option value. Then, since our script is using 720 rather than 360, we double the user-chosen value and put that in the variable q. When our for loop runs, for (var i = 0; i <= q; i++) {}, this q will inform the script how many circle perimeter points to plot before quitting. Cool, huh?
We were too lazy to type 360 numbers into our Select box code, so we used a for loop and the document.write() method to create our Select box on the fly. This same method was used to stick arc points on the screen with 3x3 gifs. You may notice that our Select box form has action="" and onsubmit="choose()" as form attributes. Why reload the page or run a separate script when it's easier to just let an onsubmit event handler do the work?
CIRCLE:
Plot points at X and Y increasing angle from 0 to 360 (2PI radians) or increase precision by using 720 everywhere so there are fewer gaps in the points, and at the sizes we show here, no gaps, as long as the "points" are 3x3 rather than 1x1 or 2x2. For bigger gapless ellipses and circles, increase 3x3 to 4x4 or 5x5—etc.
X = parseInt(xmiddle+(radius*Math.sin(angle*2*(Math.PI/720)))+0.5);
Y = parseInt(ymiddle+(radius*Math.cos(angle*2*(Math.PI/720)))+0.5);
User choice of an arc degree angle value, then pressing the Choose button is all it takes to run the arc script.
<html>
<head>
<script type="text/javascript">
var x,y,q;
radius=200;xmiddle=500;ymiddle=300;
var xlast = -1;
var ylast = -1;
function choose(){
var Selected = document.myform.selectarcdegrees.selectedIndex;
var SelectedOption = document.myform.selectarcdegrees.options[Selected].value;
q=SelectedOption*2;
for (var i = 0; i <= q; i++) {
x = parseInt(xmiddle+(radius*Math.sin(i*2*(Math.PI/720)))+0.5)
y = parseInt(ymiddle+(radius*Math.cos(i*2*(Math.PI/720)))+0.5)
if (xlast != x || ylast != y){
xlast = x;ylast = y;
document.write("<div style='position:absolute;left:"+x+"px;top:"+y+"px'><IMG SRC='3x3.gif' WIDTH=3 HEIGHT=3 BORDER=0></div>");}}}
</script>
</head>
<body>
<script type="text/javascript">
document.write('<form name="myform" action="" onsubmit="choose()">');
document.write('<select name="selectarcdegrees">');
for (var i = 1; i <= 360; i++) {
document.write('<option value="'+i+'">'+i+' degrees arc</option>');}
document.write('</select>');
document.write('<input type="submit" value="Choose"></form>');
</script>
</body>
</html>