Browse Source

Fix the olivec_line stairs

rexim 3 years ago
parent
commit
941d29a058

+ 20 - 20
olive.c

@@ -337,35 +337,35 @@ OLIVECDEF void olivec_circle(Olivec_Canvas oc, int cx, int cy, int r, uint32_t c
 // TODO: AA for line
 // TODO: AA for line
 OLIVECDEF void olivec_line(Olivec_Canvas oc, int x1, int y1, int x2, int y2, uint32_t color)
 OLIVECDEF void olivec_line(Olivec_Canvas oc, int x1, int y1, int x2, int y2, uint32_t color)
 {
 {
-    // TODO: fix the olivec_draw_line stairs
     int dx = x2 - x1;
     int dx = x2 - x1;
     int dy = y2 - y1;
     int dy = y2 - y1;
 
 
-    if (dx != 0) {
-        int c = y1 - dy*x1/dx;
+    if (dx == 0 && dy == 0) {
+        olivec_blend_color(&OLIVEC_PIXEL(oc, x1, y1), color);
+        return;
+    }
 
 
-        if (x1 > x2) OLIVEC_SWAP(int, x1, x2);
+    if (OLIVEC_ABS(int, dx) > OLIVEC_ABS(int, dy)) {
+        if (x1 > x2) {
+            OLIVEC_SWAP(int, x1, x2);
+            OLIVEC_SWAP(int, y1, y2);
+        }
         for (int x = x1; x <= x2; ++x) {
         for (int x = x1; x <= x2; ++x) {
+            int y = dy*(x - x1)/dx + y1;
             // TODO: move boundary checks out side of the loops in olivec_draw_line
             // TODO: move boundary checks out side of the loops in olivec_draw_line
-            if (0 <= x && x < (int) oc.width) {
-                int sy1 = dy*x/dx + c;
-                int sy2 = dy*(x + 1)/dx + c;
-                if (sy1 > sy2) OLIVEC_SWAP(int, sy1, sy2);
-                for (int y = sy1; y <= sy2; ++y) {
-                    if (0 <= y && y < (int) oc.height) {
-                        olivec_blend_color(&OLIVEC_PIXEL(oc, x, y), color);
-                    }
-                }
+            if (0 <= x && x < (int) oc.width && 0 <= y && y < (int) oc.height) {
+                olivec_blend_color(&OLIVEC_PIXEL(oc, x, y), color);
             }
             }
         }
         }
     } else {
     } else {
-        int x = x1;
-        if (0 <= x && x < (int) oc.width) {
-            if (y1 > y2) OLIVEC_SWAP(int, y1, y2);
-            for (int y = y1; y <= y2; ++y) {
-                if (0 <= y && y < (int) oc.height) {
-                    olivec_blend_color(&OLIVEC_PIXEL(oc, x, y), color);
-                }
+        if (y1 > y2) {
+            OLIVEC_SWAP(int, x1, x2);
+            OLIVEC_SWAP(int, y1, y2);
+        }
+        for (int y = y1; y <= y2; ++y) {
+            int x = dx*(y - y1)/dy + x1;
+            if (0 <= x && x < (int) oc.width && 0 <= y && y < (int) oc.height) {
+                olivec_blend_color(&OLIVEC_PIXEL(oc, x, y), color);
             }
             }
         }
         }
     }
     }

+ 23 - 0
test.c

@@ -296,6 +296,28 @@ Olivec_Canvas test_circle_example(void)
     return oc;
     return oc;
 }
 }
 
 
+Olivec_Canvas test_lines_circle(void)
+{
+    int width = 800;
+    int height = 600;
+    uint32_t *pixels = context_alloc(width*height*sizeof(uint32_t));
+    Olivec_Canvas oc = olivec_canvas(pixels, width, height, width);
+    olivec_fill(oc, BACKGROUND_COLOR);
+
+    size_t n = 20;
+    float angle = 2*M_PI/n;
+    float length = 200;
+    float x1 = width/2;
+    float y1 = height/2;
+    for (size_t i = 0; i < n; ++i) {
+        float x2 = x1 + cosf(angle*i)*length;
+        float y2 = y1 + sinf(angle*i)*length;
+        olivec_line(oc, x1, y1, x2, y2, 0xFF1818FF);
+    }
+
+    return oc;
+}
+
 Olivec_Canvas test_lines_example(void)
 Olivec_Canvas test_lines_example(void)
 {
 {
     int width = 800;
     int width = 800;
@@ -343,6 +365,7 @@ Test_Case test_cases[] = {
     DEFINE_TEST_CASE(test_circle_example),
     DEFINE_TEST_CASE(test_circle_example),
     DEFINE_TEST_CASE(test_lines_example),
     DEFINE_TEST_CASE(test_lines_example),
     DEFINE_TEST_CASE(test_hello_world_text_rendering),
     DEFINE_TEST_CASE(test_hello_world_text_rendering),
+    DEFINE_TEST_CASE(test_lines_circle),
 };
 };
 #define TEST_CASES_COUNT (sizeof(test_cases)/sizeof(test_cases[0]))
 #define TEST_CASES_COUNT (sizeof(test_cases)/sizeof(test_cases[0]))
 
 

BIN
test/test_draw_line_expected.png


BIN
test/test_lines_circle_expected.png


BIN
test/test_lines_example_expected.png


BIN
wasm/3d.wasm


BIN
wasm/squish.wasm


BIN
wasm/triangle.wasm


BIN
wasm/triangle3d.wasm