diff options
author | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2010-12-20 20:26:52 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2010-12-20 20:26:52 -0500 |
commit | 182ca6b7ab15720e810148bc5315b12a73e9b449 (patch) | |
tree | 8669a46fc51338062261ac77ed743c396bbb7ca5 | |
parent | 193100012641e494ae0c08eb24114dd40d60b3ce (diff) |
short edge e update
-rw-r--r-- | poly2.c | 91 |
1 files changed, 72 insertions, 19 deletions
@@ -121,7 +121,6 @@ step_y (sample_t yi) return yi + 1; } - typedef struct polygon_t polygon_t; typedef struct point_t point_t; typedef struct seg_t seg_t; @@ -154,7 +153,8 @@ typedef struct uninitialized_edge_t uninitialized_edge_t; typedef enum { VERTICAL, - SHORT, + SHORT_W, + SHORT_E, LONG, UNINITIALIZED } edge_type_t; @@ -162,36 +162,39 @@ typedef enum struct edge_common_t { edge_type_t type; - sample_t bottom; int dir; + sample_t xi; + sample_t bottom; }; struct short_edge_t { - sample_t xi; - uint32_t e; - uint32_t delta_e_big_x; - uint32_t delta_e_small_x; - uint32_t delta_e_big_y; - uint32_t delta_e_small_y; + edge_common_t common; + uint32_t e; + uint32_t delta_e_big_x; + uint32_t delta_e_small_x; + uint32_t delta_e_big_y; + uint32_t delta_e_small_y; }; struct vertical_edge_t { - sample_t xi; + edge_common_t common; }; struct long_edge_t { + edge_common_t common; /* stuff here, pointer */ }; struct uninitialized_edge_t { - sample_t yi; - const seg_t *seg; - const point_t *top; - const point_t *bottom; + edge_common_t common; + sample_t yi; + const seg_t * seg; + const point_t * top; + const point_t * bottom; }; union edge_t @@ -205,6 +208,48 @@ union edge_t }; static void +short_e_edge_update_error (short_edge_t *edge) +{ + while (edge->e <= 0) + { + if (fixed_frac (edge->common.xi) == N_GRID_X - 1) + { + edge->e += edge->delta_e_big_x; + edge->common.xi = fixed_floor (edge->common.xi + fixed_1); + } + else + { + edge->e += edge->delta_e_small_x; + edge->common.xi++; + } + } +} + +static void +short_w_edge_update_error (short_edge_t *edge) +{ +again: + if (fixed_frac (edge->common.xi) == 0) + { + if (edge->e > edge->delta_e_big_x) + { + edge->e -= edge->delta_e_big_x; + edge->common.xi = (edge->common.xi - fixed_1) | (N_GRID_X - 1); + goto again; + } + } + else + { + if (edge->e > edge->delta_e_small_x) + { + edge->e -= edge->delta_e_small_x; + edge->common.xi--; + goto again; + } + } +} + +static void edge_init (edge_t *edge, sample_t first_yi) { const point_t *top = edge->uninitialized.top; @@ -213,12 +258,12 @@ edge_init (edge_t *edge, sample_t first_yi) edge->common.dir = 2 * (top == &seg->p1) - 1; edge->common.bottom = next_sample_y (bottom->y); + edge->common.xi = next_sample_x (top->x); if (top->x == bottom->x) { /* vertical */ edge->common.type = VERTICAL; - edge->vertical.xi = next_sample_x (top->x); } else { @@ -234,16 +279,24 @@ edge_init (edge_t *edge, sample_t first_yi) dx < 8 * dy) { /* short */ - sample_t xi = next_sample_x (top->x); - - edge->short_.xi = xi; edge->short_.e = - (sample_to_pos_x (xi) - top->x) * dy - + (sample_to_pos_x (edge->common.xi) - top->x) * dy - (sample_to_pos_y (first_yi) - top->y) * dx; edge->short_.delta_e_big_x = BIG_STEP_X * dy; edge->short_.delta_e_small_x = SMALL_STEP_X * dy; edge->short_.delta_e_big_y = BIG_STEP_Y * dx; edge->short_.delta_e_small_y = SMALL_STEP_Y * dx; + + if (dx >= 0) + { + edge->common.type = SHORT_E; + short_e_edge_update_error (&edge->short_); + } + else + { + edge->common.type = SHORT_W; + short_w_edge_update_error (&edge->short_); + } } else { |