Skip to content

Instantly share code, notes, and snippets.

@MaBecker
Created January 16, 2025 01:59
Show Gist options
  • Save MaBecker/071ca5440565dc9163a8e35a0cf2c5fc to your computer and use it in GitHub Desktop.
Save MaBecker/071ca5440565dc9163a8e35a0cf2c5fc to your computer and use it in GitHub Desktop.
Arc Algorithm based on Bresenham Circle routine
// Source https://www.scattergood.io/arc-drawing-algorithm/
//
// Arc Algorithm based on Bresenham Circle routine.
//
// Define variables for Arc sectors
//
#define NOT_DRAWN 0
#define STARTS_HERE 1
#define ALL_DRAWN 2
#define ENDS_HERE 3
#define STARTS_ENDS_HERE 4
// Radian to degree conversion value.
#define R_TO_D 57.29578
//===============================================================================
// Circle Sector flags
// Global access by all routines.
//===============================================================================
int arc_sector[8];
//===============================================================================
// FastArc
// Draw an arc,
// Inputs
// xc,yc Centre of arc
// sa,ea start and end angle in degrees
// r radius
//===============================================================================
void FastArc(int xc, int yc, int sa, int ea, int r)
{
int start_sector, end_sector;
int i;
int x, y;
int ep, sp, d;
// Clear all the arc sector flags,
for (i = 0; i < 8; i++)
arc_sector[i] = NOT_DRAWN;
// Calculate the start and end Arc sectors
start_sector = sa / 45;
end_sector = ea / 45;
if (start_sector == end_sector)
{
arc_sector[start_sector] = STARTS_ENDS_HERE;
}
else
{
for (i = start_sector; i < end_sector; i++)
arc_sector[i] = ALL_DRAWN;
arc_sector[start_sector] = STARTS_HERE;
arc_sector[end_sector] = ENDS_HERE;
} /*''Calculate the Start and End Points*/ /*''Calculate points in first sector and translate*/
x = 0;
y = r;
sp = ((double)xc + (double)r * cos((double)sa / R_TO_D));
ep = ((double)xc + (double)r * cos((double)ea / R_TO_D));
d = 2 * (1 - r);
while (y > x)
{
NegativeSectorPoint(xc + y, yc + x, 0, sp, ep);
NegativeSectorPoint(xc + x, yc + y, 1, sp, ep);
NegativeSectorPoint(xc - x, yc + y, 2, sp, ep);
NegativeSectorPoint(xc - y, yc + x, 3, sp, ep);
PositiveSectorPoint(xc - y, yc - x, 4, sp, ep);
PositiveSectorPoint(xc - x, yc - y, 5, sp, ep);
PositiveSectorPoint(xc + x, yc - y, 6, sp, ep);
PositiveSectorPoint(xc + y, yc - x, 7, sp, ep);
if (d + y > 0)
{
y = y - 1;
d = d - 2 * y + 1;
}
else
{
if (x > d)
{
x = x + 1;
d = d + 2 * x + 1;
}
}
}
}
//=================================================================
// PositiveSectorPoint
// Point plotting routine for the Positive direction arc sections
// Inputs
// x,y point to plot
// s sector to check
// sp, ep StartX Point and EndX Point
//=================================================================
void PositiveSectorPoint(int x, int y, int s, int sp, int ep)
{
if (arc_sector[s] == NOT_DRAWN)
return;
if (arc_sector[s] == ALL_DRAWN)
{ // draw all points of this sector
pixel(x, y);
return;
}
if (arc_sector[s] == STARTS_HERE)
{ // draw all points flowing to right
if (x >= sp)
{
pixel(x, y);
return;
}
}
if (arc_sector[s] == ENDS_HERE)
{ // draw all points flowing from left
if (x <= ep)
{
pixel(x, y);
return;
}
}
if (arc_sector[s] == STARTS_ENDS_HERE)
{ // fill only sections of this sector.
if ((x >= sp) && (x <= ep))
pixel(x, y);
}
}
//=================================================================
// NegativeSectorPoint
// Point plotting routine for the Negative direction arc sections
//
// Inputs
// x,y point to plot
// s sector to check
// sp, ep StartX Point and EndX Point
//=================================================================
void NegativeSectorPoint(int x, int y, int s, int sp, int ep)
{
if (arc_sector[s] == NOT_DRAWN)
return;
if (arc_sector[s] == ALL_DRAWN)
{ // Draw all points in this sector
pixel(x, y);
return;
}
if (arc_sector[s] == STARTS_HERE)
{ // Draw all points flowing to the left
if (x <= sp)
{
pixel(x, y);
return;
}
}
if (arc_sector[s] == ENDS_HERE)
{ // Draw all points flowing from the right
if (x >= ep)
{
pixel(x, y);
return;
}
}
if (arc_sector[s] == STARTS_ENDS_HERE)
{ // fill only sections of this sector.
if ((x >= ep) && (x <= sp))
pixel(x, y);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment