Thursday, February 4, 2016
Fast rounded corners
I was always fascinated by ingenious coding, like what Bill Atkinson did for Macintosh back in 1981.
Apple Lisa's 68000 CPU didn't support floating point operations and therefore square roots to calculate circle wasn't on the table.
Bill found out, that because sum of a sequence of odd numbers is always a perfect square (like 1 + 3 = 4 and 1 + 3 + 5 + 7 = 16), the only thing he had to do was to iterate until a threshold was exceeded.
https://www.folklore.org/StoryView.py?story=Round_Rects_Are_Everywhere.txt
RoundRects
- #include <graphics.h>
void DrawPixel(int x, int y) {
putpixel(x, y, WHITE);
}
void DrawCircle(int xc, int yc, int r) {
int x = r, y = 0;
int decisionOver2 = 1 - x;
while (y <= x) {
DrawPixel(xc + x, yc + y);
DrawPixel(xc + y, yc + x);
DrawPixel(xc - y, yc + x);
DrawPixel(xc - x, yc + y);
DrawPixel(xc - x, yc - y);
DrawPixel(xc - y, yc - x);
DrawPixel(xc + y, yc - x);
DrawPixel(xc + x, yc - y);
y++;
if (decisionOver2 <= 0) {
decisionOver2 += 2 * y + 1;
} else {
x--;
decisionOver2 += 2 * (y - x) + 1;
}
}
}
void DrawRoundRect(int x, int y, int width, int height, int radius) {
// Draw corners
DrawCircle(x + radius, y + radius, radius); // Top-left corner
DrawCircle(x + width - radius, y + radius, radius); // Top-right corner
DrawCircle(x + width - radius, y + height - radius, radius); // Bottom-right corner
DrawCircle(x + radius, y + height - radius, radius); // Bottom-left corner
// Draw edges
line(x + radius, y, x + width - radius, y); // Top edge
line(x + width, y + radius, x + width, y + height - radius); // Right edge
line(x + width - radius, y + height, x + radius, y + height); // Bottom edge
line(x, y + height - radius, x, y + radius); // Left edge
}
int main() {
int gd = DETECT, gm;
initgraph(&gd, &gm, "");
DrawRoundRect(100, 100, 200, 100, 20);
getch();
closegraph();
return 0;
}
asdf