Skip to content

Commit ba6d659

Browse files
authored
Optimize draw.aacircle and fix typo (#3012)
* Optimized draw.aacircle and fixed typo Moved pow(radius, 2) outside of loop * formatted * float to double double trouble
1 parent bf4d301 commit ba6d659

File tree

2 files changed

+35
-33
lines changed

2 files changed

+35
-33
lines changed

docs/reST/ref/draw.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ object around the draw calls (see :func:`pygame.Surface.lock` and
213213
| :sg:`aacircle(surface, color, center, radius, width=0, draw_top_right=None, draw_top_left=None, draw_bottom_left=None, draw_bottom_right=None) -> Rect`
214214
215215
Draws an antialiased circle on the given surface.
216-
Uses Xaolin Wu Circle Algorithm.
216+
Uses Xiaolin Wu Circle Algorithm.
217217
adapted from: https://cgg.mff.cuni.cz/~pepca/ref/WU.pdf
218218

219219
:param Surface surface: surface to draw on

src_c/draw.c

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ static void
5858
draw_circle_bresenham_thin(SDL_Surface *surf, int x0, int y0, int radius,
5959
Uint32 color, int *drawn_area);
6060
static void
61-
draw_circle_xaolinwu(SDL_Surface *surf, int x0, int y0, int radius,
62-
int thickness, Uint32 color, int top_right, int top_left,
63-
int bottom_left, int bottom_right, int *drawn_area);
61+
draw_circle_xiaolinwu(SDL_Surface *surf, int x0, int y0, int radius,
62+
int thickness, Uint32 color, int top_right, int top_left,
63+
int bottom_left, int bottom_right, int *drawn_area);
6464
static void
65-
draw_circle_xaolinwu_thin(SDL_Surface *surf, int x0, int y0, int radius,
66-
Uint32 color, int top_right, int top_left,
67-
int bottom_left, int bottom_right, int *drawn_area);
65+
draw_circle_xiaolinwu_thin(SDL_Surface *surf, int x0, int y0, int radius,
66+
Uint32 color, int top_right, int top_left,
67+
int bottom_left, int bottom_right, int *drawn_area);
6868
static void
6969
draw_circle_filled(SDL_Surface *surf, int x0, int y0, int radius, Uint32 color,
7070
int *drawn_area);
@@ -820,33 +820,33 @@ aacircle(PyObject *self, PyObject *args, PyObject *kwargs)
820820
if (!width || width == radius) {
821821
draw_circle_filled(surf, posx, posy, radius - 1, color,
822822
drawn_area);
823-
draw_circle_xaolinwu(surf, posx, posy, radius, 2, color, 1, 1, 1,
824-
1, drawn_area);
823+
draw_circle_xiaolinwu(surf, posx, posy, radius, 2, color, 1, 1, 1,
824+
1, drawn_area);
825825
}
826826
else if (width == 1) {
827-
draw_circle_xaolinwu_thin(surf, posx, posy, radius, color, 1, 1, 1,
828-
1, drawn_area);
827+
draw_circle_xiaolinwu_thin(surf, posx, posy, radius, color, 1, 1,
828+
1, 1, drawn_area);
829829
}
830830
else {
831-
draw_circle_xaolinwu(surf, posx, posy, radius, width, color, 1, 1,
832-
1, 1, drawn_area);
831+
draw_circle_xiaolinwu(surf, posx, posy, radius, width, color, 1, 1,
832+
1, 1, drawn_area);
833833
}
834834
}
835835
else {
836836
if (!width || width == radius) {
837-
draw_circle_xaolinwu(surf, posx, posy, radius, radius, color,
838-
top_right, top_left, bottom_left,
839-
bottom_right, drawn_area);
837+
draw_circle_xiaolinwu(surf, posx, posy, radius, radius, color,
838+
top_right, top_left, bottom_left,
839+
bottom_right, drawn_area);
840840
}
841841
else if (width == 1) {
842-
draw_circle_xaolinwu_thin(surf, posx, posy, radius, color,
843-
top_right, top_left, bottom_left,
844-
bottom_right, drawn_area);
842+
draw_circle_xiaolinwu_thin(surf, posx, posy, radius, color,
843+
top_right, top_left, bottom_left,
844+
bottom_right, drawn_area);
845845
}
846846
else {
847-
draw_circle_xaolinwu(surf, posx, posy, radius, width, color,
848-
top_right, top_left, bottom_left,
849-
bottom_right, drawn_area);
847+
draw_circle_xiaolinwu(surf, posx, posy, radius, width, color,
848+
top_right, top_left, bottom_left,
849+
bottom_right, drawn_area);
850850
}
851851
}
852852

@@ -2514,23 +2514,24 @@ draw_eight_symetric_pixels(SDL_Surface *surf, int x0, int y0, Uint32 color,
25142514
}
25152515
}
25162516

2517-
/* Xaolin Wu Circle Algorithm
2517+
/* Xiaolin Wu Circle Algorithm
25182518
* adapted from: https://cgg.mff.cuni.cz/~pepca/ref/WU.pdf
25192519
* with additional line width parameter and quadrants option
25202520
*/
25212521
static void
2522-
draw_circle_xaolinwu(SDL_Surface *surf, int x0, int y0, int radius,
2523-
int thickness, Uint32 color, int top_right, int top_left,
2524-
int bottom_left, int bottom_right, int *drawn_area)
2522+
draw_circle_xiaolinwu(SDL_Surface *surf, int x0, int y0, int radius,
2523+
int thickness, Uint32 color, int top_right, int top_left,
2524+
int bottom_left, int bottom_right, int *drawn_area)
25252525
{
25262526
for (int layer_radius = radius - thickness; layer_radius <= radius;
25272527
layer_radius++) {
25282528
int x = 0;
25292529
int y = layer_radius;
2530+
double pow_layer_r = pow(layer_radius, 2);
25302531
double prev_opacity = 0.0;
25312532
if (layer_radius == radius - thickness) {
25322533
while (x < y) {
2533-
double height = sqrt(pow(layer_radius, 2) - pow(x, 2));
2534+
double height = sqrt(pow_layer_r - pow(x, 2));
25342535
double opacity = 255.0 * (ceil(height) - height);
25352536
if (opacity < prev_opacity) {
25362537
--y;
@@ -2547,7 +2548,7 @@ draw_circle_xaolinwu(SDL_Surface *surf, int x0, int y0, int radius,
25472548
}
25482549
else if (layer_radius == radius) {
25492550
while (x < y) {
2550-
double height = sqrt(pow(layer_radius, 2) - pow(x, 2));
2551+
double height = sqrt(pow_layer_r - pow(x, 2));
25512552
double opacity = 255.0 * (ceil(height) - height);
25522553
if (opacity < prev_opacity) {
25532554
--y;
@@ -2565,7 +2566,7 @@ draw_circle_xaolinwu(SDL_Surface *surf, int x0, int y0, int radius,
25652566
}
25662567
else {
25672568
while (x < y) {
2568-
double height = sqrt(pow(layer_radius, 2) - pow(x, 2));
2569+
double height = sqrt(pow_layer_r - pow(x, 2));
25692570
double opacity = 255.0 * (ceil(height) - height);
25702571
if (opacity < prev_opacity) {
25712572
--y;
@@ -2584,15 +2585,16 @@ draw_circle_xaolinwu(SDL_Surface *surf, int x0, int y0, int radius,
25842585
}
25852586

25862587
static void
2587-
draw_circle_xaolinwu_thin(SDL_Surface *surf, int x0, int y0, int radius,
2588-
Uint32 color, int top_right, int top_left,
2589-
int bottom_left, int bottom_right, int *drawn_area)
2588+
draw_circle_xiaolinwu_thin(SDL_Surface *surf, int x0, int y0, int radius,
2589+
Uint32 color, int top_right, int top_left,
2590+
int bottom_left, int bottom_right, int *drawn_area)
25902591
{
25912592
int x = 0;
25922593
int y = radius;
2594+
double pow_r = pow(radius, 2);
25932595
double prev_opacity = 0.0;
25942596
while (x < y) {
2595-
double height = sqrt(pow(radius, 2) - pow(x, 2));
2597+
double height = sqrt(pow_r - pow(x, 2));
25962598
double opacity = 255.0 * (ceil(height) - height);
25972599
if (opacity < prev_opacity) {
25982600
--y;

0 commit comments

Comments
 (0)