Pārlūkot izejas kodu

Implement olivec_ellipse

rexim 2 gadi atpakaļ
vecāks
revīzija
d2443c2aed
3 mainītis faili ar 32 papildinājumiem un 1 dzēšanām
  1. 21 0
      olive.c
  2. 11 1
      test.c
  3. BIN
      test/fill_ellipse_expected.png

+ 21 - 0
olive.c

@@ -331,6 +331,7 @@ OLIVECDEF void olivec_fill(Olivec_Canvas oc, uint32_t color);
 OLIVECDEF void olivec_rect(Olivec_Canvas oc, int x, int y, int w, int h, uint32_t color);
 OLIVECDEF void olivec_frame(Olivec_Canvas oc, int x, int y, int w, int h, size_t thiccness, uint32_t color);
 OLIVECDEF void olivec_circle(Olivec_Canvas oc, int cx, int cy, int r, uint32_t color);
+OLIVECDEF void olivec_ellipse(Olivec_Canvas oc, int cx, int cy, int rx, int ry, uint32_t color);
 // TODO: lines with different thiccness
 OLIVECDEF void olivec_line(Olivec_Canvas oc, int x1, int y1, int x2, int y2, uint32_t color);
 OLIVECDEF bool olivec_normalize_triangle(size_t width, size_t height, int x1, int y1, int x2, int y2, int x3, int y3, int *lx, int *hx, int *ly, int *hy);
@@ -499,6 +500,26 @@ OLIVECDEF void olivec_frame(Olivec_Canvas oc, int x, int y, int w, int h, size_t
     olivec_rect(oc, x2 + t/2, y1 - t/2, -t, (y2 - y1 + 1) + t/2*2, color); // Right
 }
 
+OLIVECDEF void olivec_ellipse(Olivec_Canvas oc, int cx, int cy, int rx, int ry, uint32_t color)
+{
+    Olivec_Normalized_Rect nr = {0};
+    int rx1 = rx + OLIVEC_SIGN(int, rx);
+    int ry1 = ry + OLIVEC_SIGN(int, ry);
+    if (!olivec_normalize_rect(cx - rx1, cy - ry1, 2*rx1, 2*ry1, oc.width, oc.height, &nr)) return;
+
+    for (int y = nr.y1; y <= nr.y2; ++y) {
+        for (int x = nr.x1; x <= nr.x2; ++x) {
+            float nx = (x + 0.5 - nr.x1)/(2.0f*rx1);
+            float ny = (y + 0.5 - nr.y1)/(2.0f*ry1);
+            float dx = nx - 0.5;
+            float dy = ny - 0.5;
+            if (dx*dx + dy*dy <= 0.5*0.5) {
+                OLIVEC_PIXEL(oc, x, y) = color;
+            }
+        }
+    }
+}
+
 OLIVECDEF void olivec_circle(Olivec_Canvas oc, int cx, int cy, int r, uint32_t color)
 {
     Olivec_Normalized_Rect nr = {0};

+ 11 - 1
test.c

@@ -603,6 +603,15 @@ Olivec_Canvas test_bilinear_interpolation(void)
     return dst;
 }
 
+Olivec_Canvas test_fill_ellipse(void)
+{
+    size_t factor = 3;
+    Olivec_Canvas dst = canvas_alloc(100*factor, 50*factor);
+    olivec_fill(dst, BACKGROUND_COLOR);
+    olivec_ellipse(dst, dst.width/2, dst.height/2, dst.width/3, dst.height/3, RED_COLOR);
+    return dst;
+}
+
 Test_Case test_cases[] = {
     DEFINE_TEST_CASE(fill_rect),
     DEFINE_TEST_CASE(fill_circle),
@@ -626,7 +635,8 @@ Test_Case test_cases[] = {
     DEFINE_TEST_CASE(sprite_blend_vs_copy),
     DEFINE_TEST_CASE(triangle_order_flip),
     DEFINE_TEST_CASE(barycentric_overflow),
-    DEFINE_TEST_CASE(bilinear_interpolation)
+    DEFINE_TEST_CASE(bilinear_interpolation),
+    DEFINE_TEST_CASE(fill_ellipse),
 };
 #define TEST_CASES_COUNT (sizeof(test_cases)/sizeof(test_cases[0]))
 

BIN
test/fill_ellipse_expected.png