diff --git a/polygons.cpp b/polygons.cpp index 3768ea6f..bdbc19cd 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -6,6 +6,18 @@ namespace hr { +ld signum(ld x) { return x<0?-1:x>0?1:0; } + +bool asign(ld y1, ld y2) { + return signum(y1) != signum(y2); + } + +ld xcross(ld x1, ld y1, ld x2, ld y2) { + return x1 + (x2 - x1) * y1 / (y1 - y2); + } + +hyperpoint intester; + // draw the lines static const int POLY_DRAWLINES = 1; // draw the area @@ -38,6 +50,9 @@ static const int POLY_VCONVEX = 4096; // Convex shape (central) static const int POLY_CCONVEX = 8192; +// new system of side checking +static const int POLY_CENTERIN = 16384; + vector hpc; int prehpc; @@ -200,16 +215,41 @@ void addpoly(const transmatrix& V, const vector &tab, int ofs, int cnt hyperpoint last = V * glhr::gltopoint(tab[ofs]); bool last_behind = is_behind(last); if(!last_behind) addpoint(last); + hyperpoint enter; + hyperpoint firstleave; + int start_behind = last_behind ? 1 : 0; for(int i=ofs+1; i 0) { + hyperpoint he = (h + enter) / 2; + ld sca = sqrt(sca2) / hypot2(he); + he[0] *= sca; h[1] *= sca; + printf("sca2 = %lf zl=%lf/%lf\n", sca2, zlevel(h), zlevel(he)); + addpoint(he); + } + } */ + addpoint(h); + last_behind = !last_behind; } + if(!last_behind) addpoint(curr); + last = curr; + } + if(start_behind == 2) { + if(firstleave[0] * enter[0] + firstleave[1] * enter[1] < 0) poly_flags |= POLY_BEHIND; + else addpoint(firstleave); } } @@ -646,7 +686,12 @@ void drawpolyline(polytodraw& p) { p.col = 0; */ addpoly(pp.V, *pp.tab, pp.offset, pp.cnt); - // if(poly_flags & POLY_BEHIND) return; + for(int i=1; i vid.xres * 2 || dy > vid.yres * 2) return; + } + if(poly_flags & POLY_BEHIND) return; if(isize(glcoords) <= 1) return; mercator_loop_min = mercator_loop_max = 0; @@ -663,16 +708,49 @@ void drawpolyline(polytodraw& p) { bool equi = mdAzimuthalEqui() || pmodel == mdFisheye; + bool nofill = false; + if((spherespecial > 0 || (sphere && equi)) && !(poly_flags & POLY_ISSIDE)) { - double rarea = 0; - for(int i=0; i0) - poly_flags ^= POLY_INVERSE; + else { + + double rarea = 0; + for(int i=0; i0) + poly_flags ^= POLY_INVERSE; + } if(poly_flags & POLY_INVERSE) { if(curradius < vid.alpha - 1e-6) return; @@ -697,8 +775,6 @@ void drawpolyline(polytodraw& p) { lastl = l; } - bool nofill = false; - if(equi && (poly_flags & POLY_INVERSE)) { if(abs(zlevel(pp.V * C0) - 1) < 1e-6 && !pp.tinf) { // we should fill the other side @@ -1248,6 +1324,17 @@ void finishshape() { area += hpc[i][0] * hpc[i+1][1] - hpc[i+1][0] * hpc[i][1]; if(abs(area) < 1e-9) last->flags |= POLY_ISSIDE; if(area >= 0) last->flags |= POLY_INVERSE; + + for(int i=last->s; ie-1; i++) { + ld x1 = hpc[i][0] - intester[0], y1 = hpc[i][1] - intester[1], x2 = hpc[i+1][0] - intester[0], y2 = hpc[i+1][1] - intester[1]; + if(asign(y1, y2)) { + ld x = xcross(x1, y1, x2, y2); + if(abs(x) < 1e-6 && !(last->flags & POLY_ISSIDE)) { + printf("close call, x = %lf\n", x); + } + if(x < 0) last->flags ^= POLY_CENTERIN; + } + } bool allplus = true, allminus = true; for(int i=last->s; ie-1; i++) { @@ -1415,6 +1502,8 @@ ld dlow_table[SIDEPARS], dhi_table[SIDEPARS]; #define SHADMUL (S3==4 ? 1.05 : 1.3) void buildpolys() { + + intester = hpxy(1e-3, 1.3e-3); symmetriesAt.clear(); allshapes.clear(); @@ -1483,7 +1572,7 @@ void buildpolys() { x *= gp::scale; if(gp::scale != 1) x /= 2; for(int t=0; t<=S6; t++) { hpcpush(C0); if(t) hpcpush(ddi(S7 + t*S14, x) * C0); - last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW; + last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW | POLY_ISSIDE; } x = rhexf; @@ -1491,7 +1580,7 @@ void buildpolys() { // x *= gp::scale; bshape(shFullCross[1], PPR_FLOOR); for(int t=0; t<=S7; t++) { hpcpush(C0); if(t) hpcpush(ddi(t*S12+td, x) * C0); } - last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW; + last->flags |= POLY_HASWALLS | POLY_FULL | POLY_HASSHADOW | POLY_ISSIDE; } double floorrad0 = hexvdist*0.92;