-
-
Notifications
You must be signed in to change notification settings - Fork 488
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to draw to bigger circles in 0.90 #1510
Comments
Here'a a test cart for bresenham ellipses -- title: Test bresenham ellipsis
-- author: ddelemeny
-- desc: algorithm based on : https://dai.fmph.uniba.sk/upload/0/01/Ellipse.pdf
-- script: moon
fixed_ellib = (x,y,a,b,c)->
plot = (x,y,_x,_y) ->
pix(x+_x,y+_y,c)
pix(x+_x,y-_y,c)
pix(x-_x,y+_y,c)
pix(x-_x,y-_y,c)
local _x, _y, dx, dy, sx, sy, e, two_a_sq, _two_b_sq
two_a_sq = 2*a*a
two_b_sq = 2*b*b
_x = a
_y = 0
dx = b*b*(1-(2*a))
dy = a*a
e = 0
sx = two_b_sq*a
sy = 0
while sx>=sy do
plot(x,y,_x,_y,c)
_y += 1
sy += two_a_sq
e += dy
dy += two_a_sq
if (2*e +dx >0 )
_x -= 1
sx -= two_b_sq
e += dx
dx += two_b_sq
_x = 0
_y = b
dx = b*b
dy = a*a*(1-(2*b))
e = 0
sx = 0
sy = two_a_sq*b
while sy>=sx do
plot(x,y,_x,_y,c)
_x += 1
sx += two_b_sq
e += dx
dx += two_b_sq
if (2*e +dy >0 )
_y -= 1
sy -= two_a_sq
e += dy
dy += two_a_sq
r = 1
export TIC=->
cls 0
if (btn 4) and (r < 512) then r+=1
if (btn 5) and (r > 1) then r-=1
ellib(100+r,68,r,r,2)
fixed_ellib(120+r,68,r,r,8)
print('a to grow, b to shrink')
print("r = #{r}", 0, 10)
-- <PALETTE>
-- 000:1a1c2c5d275db13e53ef7d57ffcd75a7f07038b76425717929366f3b5dc941a6f673eff7f4f4f494b0c2566c86333c57
-- </PALETTE>
And here's a patch : diff --git a/src/core/draw.c b/src/core/draw.c
index de6b30b..d9b26f1 100644
--- a/src/core/draw.c
+++ b/src/core/draw.c
@@ -477,34 +477,43 @@ static void setSideTexPixel(s32 x, s32 y, float u, float v)
}
}
-static void drawEllipse(tic_mem* memory, s32 x0, s32 y0, s32 x1, s32 y1, u8 color, PixelFunc pix)
+static void drawEllipse(tic_mem* memory, s32 x0, s32 y0, s32 a, s32 b, u8 color, PixelFunc pix)
{
- s32 a = abs(x1-x0), b = abs(y1-y0), b1 = b&1; /* values of diameter */
- s32 dx = 4*(1-a)*b*b, dy = 4*(b1+1)*a*a; /* error increment */
- s32 err = dx+dy+b1*a*a, e2; /* error of 1.step */
+ s32 aa2 = a*a*2, bb2 = b*b*2;
+ {
+ s32 x = a, y = 0;
+ s32 dx = (1-2*a)*b*b, dy = a*a;
+ s32 sx = bb2*a, sy=0;
+ s32 e = 0;
+
+ while (sx >= sy)
+ {
- if (x0 > x1) { x0 = x1; x1 += a; } /* if called with swapped pos32s */
- if (y0 > y1) y0 = y1; /* .. exchange them */
- y0 += (b+1)/2; y1 = y0-b1; /* starting pixel */
- a *= 8*a; b1 = 8*b*b;
+ pix(memory, x0+x, y0+y, color); /* I. Quadrant */
+ pix(memory, x0+x, y0-y, color); /* II. Quadrant */
+ pix(memory, x0-x, y0+y, color); /* III. Quadrant */
+ pix(memory, x0-x, y0-y, color); /* IV. Quadrant */
- do
+ y++; sy += aa2; e += dy; dy += aa2;
+ if(2*e+dx >0) { x--; sx -= bb2; e += dx; dx += bb2; }
+ }
+ }
{
- pix(memory, x1, y0, color); /* I. Quadrant */
- pix(memory, x0, y0, color); /* II. Quadrant */
- pix(memory, x0, y1, color); /* III. Quadrant */
- pix(memory, x1, y1, color); /* IV. Quadrant */
- e2 = 2*err;
- if (e2 <= dy) { y0++; y1--; err += dy += a; } /* y step */
- if (e2 >= dx || 2*err > dy) { x0++; x1--; err += dx += b1; } /* x step */
- } while (x0 <= x1);
-
- while (y0-y1 < b)
- { /* too early stop of flat ellipses a=1 */
- pix(memory, x0-1, y0, color); /* -> finish tip of ellipse */
- pix(memory, x1+1, y0++, color);
- pix(memory, x0-1, y1, color);
- pix(memory, x1+1, y1--, color);
+ s32 x = 0, y = b;
+ s32 dx = b*b, dy = (1-2*b)*a*a;
+ s32 sx = 0, sy=aa2*b;
+ s32 e = 0;
+
+ while (sy >= sx)
+ {
+ pix(memory, x0+x, y0+y, color); /* I. Quadrant */
+ pix(memory, x0+x, y0-y, color); /* II. Quadrant */
+ pix(memory, x0-x, y0+y, color); /* III. Quadrant */
+ pix(memory, x0-x, y0-y, color); /* IV. Quadrant */
+
+ x++; sx += bb2; e += dx; dx += bb2;
+ if(2*e+dy >0) { y--; sy -= aa2; e += dy; dy += aa2; }
+ }
}
}
@@ -537,7 +546,7 @@ void tic_api_circ(tic_mem* memory, s32 x, s32 y, s32 r, u8 color)
if(r < 0) return;
initSidesBuffer();
- drawEllipse(memory, x - r, y - r, x + r, y + r, 0, setElliSide);
+ drawEllipse(memory, x , y , r, r, 0, setElliSide);
drawSidesBuffer(memory, y - r, y + r + 1, color);
}
@@ -545,7 +554,7 @@ void tic_api_circb(tic_mem* memory, s32 x, s32 y, s32 r, u8 color)
{
if(r < 0) return;
- drawEllipse(memory, x - r, y - r, x + r, y + r, mapColor(memory, color), setElliPixel);
+ drawEllipse(memory, x , y , r, r, mapColor(memory, color), setElliPixel);
}
void tic_api_elli(tic_mem* memory, s32 x, s32 y, s32 a, s32 b, u8 color)
@@ -553,7 +562,7 @@ void tic_api_elli(tic_mem* memory, s32 x, s32 y, s32 a, s32 b, u8 color)
if(a < 0 || b < 0) return;
initSidesBuffer();
- drawEllipse(memory, x - a, y - b, x + a, y + b, 0, setElliSide);
+ drawEllipse(memory, x , y, a, b, 0, setElliSide);
drawSidesBuffer(memory, y - b, y + b + 1, color);
}
@@ -561,7 +570,7 @@ void tic_api_ellib(tic_mem* memory, s32 x, s32 y, s32 a, s32 b, u8 color)
{
if(a < 0 || b < 0) return;
- drawEllipse(memory, x - a, y - b, x + a, y + b, mapColor(memory, color), setElliPixel);
+ drawEllipse(memory, x, y , a, b, mapColor(memory, color), setElliPixel);
}
static void ticLine(tic_mem* memory, s32 x0, s32 y0, s32 x1, s32 y1, u8 color, PixelFunc func)
|
@ddelemeny |
All is ok if we will use |
Thank you @ddelemeny for the better fix |
Indeed, the error and stop points being cubes of the radius, they overflow quite fast. |
It doesn't draw properly when i draw circ ( 120+512 , 68 , 512 ,color ) or circ ( 120 , 68+512 , 512 , color ) , Same goes for circb as well
4 four of my carts got effected : https://tic80.com/play?cart=1976 , https://tic80.com/play?cart=1977
These carts worked fine in 0.80
The text was updated successfully, but these errors were encountered: