Created
January 16, 2025 01:59
-
-
Save MaBecker/071ca5440565dc9163a8e35a0cf2c5fc to your computer and use it in GitHub Desktop.
Arc Algorithm based on Bresenham Circle routine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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