Improved code, reduced size

pull/250/head
BillyOwen 4 years ago committed by GitHub
parent 3f6bb34564
commit 85f431396d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 133
      olcPixelGameEngine.h

@ -2128,23 +2128,18 @@ namespace olc
void PixelGameEngine::FillArc(int32_t iterations, int32_t centreX, int32_t centreY, int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t radius, olc::Pixel p)
{
if (!iterations) return;
//Get points
int32_t midX = (x0 + x1) >> 1;
int32_t midY = (y0 + y1) >> 1;
int32_t arcX = radius * cos(atan2(midY - centreY, midX - centreX)) + centreX;
int32_t arcY = radius * sin(atan2(midY - centreY, midX - centreX)) + centreY;
//Fill triangle
FillTriangle(x0, y0, x1, y1, arcX, arcY, p);
//Recur
FillArc(iterations - 1, centreX, centreY, x0, y0, arcX, arcY, radius, p);
FillArc(iterations - 1, centreX, centreY, x1, y1, arcX, arcY, radius, p);
return;
}
void PixelGameEngine::FillCircle(int32_t x, int32_t y, int32_t radius, Pixel p)
{ // Thanks to IanM-Matrix1 #PR121
if (radius < 0 || x < -radius || y < -radius || x - GetDrawTargetWidth() > radius || y - GetDrawTargetHeight() > radius)
return;
if (radius==0)
{
Draw(x, y, p);
@ -2156,95 +2151,66 @@ namespace olc
if (radius > height || radius > width)
{
//This can be modified for higher precision
const int32_t ITERATIONS = 4;
//Currently unprotected against overflow
//Check if all four points are within circle
const int32_t ITERATIONS = 1;
//Check if all four corners are within circle
const bool topLeft = (x)*(x)+(y)*(y) <= radius * radius;
const bool topRight = (x - width)*(x - width) + (y)*(y) <= radius * radius;
const bool bottomLeft = (x)*(x)+(y - height)*(y - height) <= radius * radius;
const bool bottomRight = (x - width)*(x - width) + (y - height)*(y - height) <= radius * radius;
//Four Points inside circle
if (
bottomRight &&
topRight &&
bottomLeft &&
topLeft
)
int32_t yRight = y + (topLeft?1:-1)*sqrt(radius*radius - (width - x)*(width - x));
int32_t yLeft = y + (topLeft?1:-1)*sqrt(radius*radius-x*x);
int32_t xTop = x + (topLeft?1:-1)*sqrt(radius*radius - (height - y)*(height - y));
int32_t xBottom = x + (topLeft?1:-1)*sqrt(radius*radius - y * y);
//Four corners inside circle
if (bottomRight && topRight && bottomLeft && topLeft)
{
Clear(p);
return;
}
//Three Points inside circle
//Three corners inside circle
else if (topLeft + topRight + bottomRight + bottomLeft == 3)
{
int32_t yIntercept = y + ((topLeft&&topRight)?1:-1)*sqrt(radius*radius - ((topLeft&&bottomLeft)?(width-x)*(width-x):(x*x)));
int32_t xIntercept = x + ((topLeft&&bottomLeft)?1:-1)*sqrt(radius*radius - ((topLeft&&topRight)?(height-y)*(height-y):(y*y)));
if (!topLeft)
{
FillTriangle(width, 0, width, height, 0, height, p);
int32_t yLeft = y - sqrt(radius*radius - x*x);
int32_t xTop = x - sqrt(radius*radius - y * y);
FillTriangle(0, height, 0, yLeft, xTop, 0,p);
FillTriangle(0,height,xTop,0,width,0, p);
//Fill arc
FillArc(ITERATIONS, x, y, 0, yLeft, xTop, 0, radius, p);
FillTriangle(0, height, 0, yIntercept, xIntercept, 0,p);
FillTriangle(0,height,xIntercept,0,width,0, p);
FillArc(ITERATIONS, x, y, 0, yIntercept, xIntercept, 0, radius, p);
return;
}
else if (!topRight)
{
FillTriangle(0,0, width, height, 0, height, p);
int32_t yRight = y - sqrt(radius*radius - (width-x) * (width - x));
int32_t xTop = x + sqrt(radius*radius - y*y);
FillTriangle(0, 0, xTop, 0, width, yRight, p);
FillTriangle(0, 0, width, yRight, width, height, p);
FillArc(ITERATIONS, x, y, width, yRight, xTop, 0, radius, p);
FillTriangle(0, 0, xIntercept, 0, width, yIntercept, p);
FillTriangle(0, 0, width, yIntercept, width, height, p);
FillArc(ITERATIONS, x, y, width, yIntercept, xIntercept, 0, radius, p);
return;
}
else if (!bottomLeft)
{
FillTriangle(0, 0, width, 0, width, height, p);
int32_t yLeft = y + sqrt(radius*radius - x * x);
int32_t xBottom = x - sqrt(radius*radius - (height - y) * (height - y));
FillTriangle(0, yLeft, xBottom, height, width, height, p);
FillTriangle(0, 0, 0, yLeft, width, height, p);
FillArc(ITERATIONS, x, y, 0, yLeft, xBottom, height, radius, p);
FillTriangle(0, yIntercept, xIntercept, height, width, height, p);
FillTriangle(0, 0, 0, yIntercept, width, height, p);
FillArc(ITERATIONS, x, y, 0, yIntercept, xIntercept, height, radius, p);
return;
}
else //!bottomRight
{
FillTriangle(0, 0, width, 0, 0, height, p);
int32_t yRight = y + sqrt(radius*radius - (width - x) * (width - x));
int32_t xBottom = x + sqrt(radius*radius - (height - y) * (height - y));
FillTriangle(0, height, width, 0, width, yRight,p);
FillTriangle(0, height, xBottom, height, width, yRight, p);
FillArc(ITERATIONS, x, y, width, yRight, xBottom, height, radius, p);
FillTriangle(0, height, width, 0, width, yIntercept,p);
FillTriangle(0, height, xIntercept, height, width, yIntercept, p);
FillArc(ITERATIONS, x, y, width, yIntercept, xIntercept, height, radius, p);
return;
}
}
//Two points inside circle
//Two corners inside circle
else if (topLeft + topRight + bottomRight + bottomLeft == 2)
{
if (topLeft && topRight)
{
int32_t yRight = y + sqrt(radius*radius - (width - x)*(width - x));
int32_t yLeft = y + sqrt(radius*radius - x * x);
if (x > width / 2)
if (yRight > yLeft)
{
FillRect(0, 0, width, yLeft, p);
FillTriangle(0, yLeft, width, yLeft, width, yRight, p);
@ -2259,9 +2225,7 @@ namespace olc
}
else if (topLeft && bottomLeft)
{
int32_t xTop = x + sqrt(radius*radius - (height - y)*(height - y));
int32_t xBottom = x + sqrt(radius*radius - y * y);
if (y > height / 2)
if (xTop > xBottom)
{
FillRect(0, 0, xBottom, height, p);
FillTriangle(xBottom, 0, xBottom, height, xTop, height, p);
@ -2276,9 +2240,7 @@ namespace olc
}
else if (bottomRight && topRight)
{
int32_t xTop = x - sqrt(radius*radius - (height - y)*(height - y));
int32_t xBottom = x - sqrt(radius*radius - y * y);
if (y > height / 2)
if (xBottom > xTop)
{
FillTriangle(xBottom, 0, xTop, height, xBottom, height, p);
FillRect(xBottom, 0, width, height, p);
@ -2293,9 +2255,7 @@ namespace olc
}
else //bottomRight && bottomLeft
{
int32_t yLeft = y - sqrt(radius*radius - x * x);
int32_t yRight = y - sqrt(radius*radius - (width - x)*(width - x));
if (x > width / 2)
if (yLeft > yRight)
{
FillRect(0, yLeft, width, height, p);
FillTriangle(0, yLeft, width, yLeft, width, yRight, p);
@ -2309,48 +2269,37 @@ namespace olc
return;
}
}
//One Point inside circle
//One corner inside circle
else if (topLeft)
{
int32_t yLeft = y + sqrt(radius*radius - x * x);
int32_t xTop = x + sqrt(radius*radius - y*y);
xTop = x + sqrt(radius*radius - y*y);
FillTriangle(0, 0, xTop, 0, 0, yLeft, p);
FillArc(ITERATIONS, x, y, xTop, 0, 0, yLeft, radius, p);
return;
}
else if (topRight)
{
int32_t yRight = y + sqrt(radius*radius - (width-x) * (width - x));
int32_t xTop = x - sqrt(radius*radius - y * y);
yRight = y + sqrt(radius*radius - (width-x) * (width - x));
xTop = x - sqrt(radius*radius - y * y);
FillTriangle(xTop, 0, width, 0, width, yRight, p);
FillArc(ITERATIONS, x, y, xTop, 0, width, yRight, radius, p);
return;
}
else if (bottomRight)
{
int32_t yRight = y - sqrt(radius*radius - (width - x) * (width - x));
int32_t xBottom = x - sqrt(radius*radius - (height-y) * (height - y));
xBottom = x - sqrt(radius*radius - (height-y) * (height - y));
FillTriangle(xBottom, height, width, height, width, yRight, p);
FillArc(ITERATIONS, x, y, xBottom, height, width, yRight, radius, p);
return;
}
else if (bottomLeft)
{
int32_t yLeft = y - sqrt(radius*radius - x*x);
int32_t xBottom = x + sqrt(radius*radius - (height - y) * (height - y));
xBottom = x + sqrt(radius*radius - (height - y) * (height - y));
FillTriangle(0, yLeft, 0, height, xBottom, height, p);
FillArc(ITERATIONS, x, y, xBottom, height, 0, yLeft, radius, p);
return;
}
//No points inside circle
//No corners inside circle
else
{
//Do extra checks on the y's
@ -2358,9 +2307,7 @@ namespace olc
{
int32_t yLeft1 = y - sqrt(radius*radius - x * x);
int32_t yLeft2 = y + sqrt(radius*radius - x * x);
if (yLeft1 < 0 || yLeft2 < 0 || yLeft1 > height || yLeft2 > height) return;
FillArc(ITERATIONS, x, y, 0, yLeft1, 0, yLeft2, radius, p);
return;
}
@ -2368,9 +2315,7 @@ namespace olc
{
int32_t yRight1 = y - sqrt(radius*radius - (width-x) * (width - x));
int32_t yRight2 = y + sqrt(radius*radius - (width - x) * (width - x));
if (yRight1 < 0 || yRight2 < 0 || yRight1 > height || yRight2 > height) return;
FillArc(ITERATIONS, x, y, width, yRight1, width, yRight2, radius, p);
return;
}
@ -2378,9 +2323,7 @@ namespace olc
{
int32_t xTop1 = x - sqrt(radius*radius - y * y);
int32_t xTop2 = x + sqrt(radius*radius - y * y);
if (xTop1 < 0 || xTop2 < 0 || xTop1 > width || xTop2 > width) return;
FillArc(ITERATIONS, x, y, xTop1, 0, xTop2, 0, radius, p);
return;
}
@ -2388,18 +2331,12 @@ namespace olc
{
int32_t xBottom1 = x - sqrt(radius*radius - (height - y)*(height - y));
int32_t xBottom2 = x + sqrt(radius*radius - (height - y)*(height - y));
if (xBottom1 < 0 || xBottom2 < 0 || xBottom1 > width || xBottom2 > width) return;
FillArc(ITERATIONS, x, y, xBottom1, height, xBottom2, height, radius, p);
return;
}
//overflow
return;
}
goto standardCircleFill;
}
else

Loading…
Cancel
Save