diff --git a/solidify/face.c b/solidify/face.c index b4f5175..18f8d8a 100644 --- a/solidify/face.c +++ b/solidify/face.c @@ -75,6 +75,9 @@ static struct face *read_file(const char *name) f->sx = f->a->max_x-f->a->min_x+1; f->sy = f->a->max_y-f->a->min_y+1; + f->cx = (f->a->min_x+f->a->max_x)/2; + f->cy = (f->a->min_y+f->a->max_y)/2; + h = make_histo(f->a); f->z_ref = f->a->min_z+median(h); free_histo(h); diff --git a/solidify/face.h b/solidify/face.h index 4c6fac1..2c98e20 100644 --- a/solidify/face.h +++ b/solidify/face.h @@ -32,6 +32,7 @@ struct matrix { struct face { struct array *a; int sx, sy; /* size */ + int cx, cy; /* center */ int z_ref; double fx, fy; /* inclination factor */ struct matrix m; diff --git a/solidify/overlap.c b/solidify/overlap.c index 2a66f3f..0eea1c3 100644 --- a/solidify/overlap.c +++ b/solidify/overlap.c @@ -83,20 +83,32 @@ static double zmix(struct face *f, double x, double y) } +/* + * Coordinate transformations, on the example of the x coordinate: + * + * - the x coordinate runs from 0 to sx(s)-1 + * - since we work relative to the screen center, this becomes x-sx(s)/2 + * This is what we perform the coordinate transform on. + * - our model runs from min_x to max_x. Its center is at cx. + */ + static void point(const struct solid *s, int x, int y, guchar *p) { double za, zb, z; - int xa = x+s->a->a->min_x; - int ya = y+s->a->a->min_y; - int yb = sy(s)-1-y+s->a->a->min_y; + int xa, xb, ya, yb; + double xaf, xbf, yaf, ybf; - za = zmix(s->a, - xa*s->a->m.a[0][0]+ya*s->a->m.a[0][1]+s->a->m.b[0], - xa*s->a->m.a[1][0]+ya*s->a->m.a[1][1]+s->a->m.b[1]); + xa = x-sx(s)/2; + ya = y-sy(s)/2; + xaf = xa*s->a->m.a[0][0]+ya*s->a->m.a[0][1]+s->a->m.b[0]+s->a->cx; + yaf = xa*s->a->m.a[1][0]+ya*s->a->m.a[1][1]+s->a->m.b[1]+s->a->cy; + za = zmix(s->a, xaf, yaf); - zb = zmix(s->b, - xa*s->b->m.a[0][0]+yb*s->b->m.a[0][1]+s->b->m.b[0], - xa*s->b->m.a[1][0]+yb*s->b->m.a[1][1]+s->b->m.b[1]); + xb = x-sx(s)/2; + yb = (sy(s)-1)/2-y; + xbf = xb*s->b->m.a[0][0]+yb*s->b->m.a[0][1]+s->b->m.b[0]+s->b->cx; + ybf = xb*s->b->m.a[1][0]+yb*s->b->m.a[1][1]+s->b->m.b[1]+s->b->cy; + zb = zmix(s->b, xbf, ybf); if (za == UNDEF_F && zb == UNDEF_F) return; @@ -125,8 +137,8 @@ static void point(const struct solid *s, int x, int y, guchar *p) } z = za; - za -= face_z0(s->a, xa, ya); - zb -= face_z0(s->b, xa, yb); + za -= face_z0(s->a, xaf, yaf); + zb -= face_z0(s->b, xbf, ybf); if (za+zb < -s->dist) { p[0] = 0;