From 44c1b43b1c5949b4940c234af5b98110d08de06a Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sat, 10 Nov 2018 14:26:49 +0100 Subject: [PATCH] refactored do_draw(cell*, const transmatrix&) --- archimedean.cpp | 28 +++++---------- binary-tiling.cpp | 59 ++++++++++++++---------------- graph.cpp | 12 ------- hyper.h | 9 +++++ hypgraph.cpp | 92 ++++++++++++++++++++++++++++------------------- 5 files changed, 100 insertions(+), 100 deletions(-) diff --git a/archimedean.cpp b/archimedean.cpp index 292ce474..621ee6b5 100644 --- a/archimedean.cpp +++ b/archimedean.cpp @@ -604,15 +604,6 @@ void create_adjacent(heptagon *h, int d) { connect_digons_too(hi, heptspin(hnew, 0)); } -set visited; -queue> drawqueue; - -void enqueue(heptagon *h, const transmatrix& T) { - if(visited.count(h)) { return; } - visited.insert(h); - drawqueue.emplace(h, T, band_shift); - } - pair& archimedean_tiling::get_triangle(heptagon *h, int cid) { return triangles[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)]; } @@ -641,23 +632,21 @@ transmatrix adjcell_matrix(heptagon *h, int d) { } void draw() { - visited.clear(); - enqueue(viewctr.at, cview()); - int idx = 0; + dq::visited.clear(); + dq::enqueue(viewctr.at, cview()); - while(!drawqueue.empty()) { - auto p = drawqueue.front(); - drawqueue.pop(); + while(!dq::drawqueue.empty()) { + auto& p = dq::drawqueue.front(); heptagon *h = get<0>(p); transmatrix V = get<1>(p); dynamicval b(band_shift, get<2>(p)); + dq::drawqueue.pop(); + int id = id_of(h); int S = isize(current.triangles[id]); if(id < 2*current.N ? !DUAL : !PURE) { - if(vid.use_smart_range == 0 && !dodrawcell(h->c7)) continue; - if(vid.use_smart_range && idx > 50 && !in_smart_range(V)) continue; - if(vid.use_smart_range == 2) setdist(h->c7, 7, h->c7); + if(!do_draw(h->c7, V)) continue; drawcell(h->c7, V, 0, false); } @@ -667,9 +656,8 @@ void draw() { if(PURE && id >= 2*current.N && h->move(i) && id_of(h->move(i)) >= 2*current.N) continue; transmatrix V1 = V * adjcell_matrix(h, i); bandfixer bf(V1); - enqueue(h->move(i), V1); + dq::enqueue(h->move(i), V1); } - idx++; } } diff --git a/binary-tiling.cpp b/binary-tiling.cpp index cf025473..147976d2 100644 --- a/binary-tiling.cpp +++ b/binary-tiling.cpp @@ -152,39 +152,34 @@ namespace binary { return transmatrix {{{-u*u/8+1, u/2, u*u/8}, {-u/2, 1, u/2}, {-u*u/8, u/2, u*u/8+1}}}; } - void draw_rec(cell *c, int dirs, const transmatrix& V, int reclev) { - - transmatrix V1 = V; - bandfixer bf(V1); - - if(vid.use_smart_range == 0 && !dodrawcell(c)) return; - if(vid.use_smart_range && reclev >= 2 && !in_smart_range(V1)) return; - if(vid.use_smart_range == 2) setdist(c, 7, c); - - drawcell(c, V1, 0, false); - // 1: up - if(dirs & 1) - draw_rec(createMov(c, bd_up), 7, V1 * xpush(-log(2)), reclev+1); - // right - if(dirs & 2) - draw_rec(createMov(c, bd_right), 2, V1 * parabolic(1), reclev+1); - // left - if(dirs & 4) - draw_rec(createMov(c, bd_left), 4, V1 * parabolic(-1), reclev+1); - // down - if((dirs & 8) && c->type == 6) - draw_rec(createMov(c, bd_down), dirs & 62, V1 * xpush(log(2)), reclev+1); - // down_left - if((dirs & 16) && c->type == 7) - draw_rec(createMov(c, bd_down_left), dirs & 28, V1 * parabolic(-1) * xpush(log(2)), reclev+1); - // down_right - if((dirs & 32) && c->type == 7) - draw_rec(createMov(c, bd_down_right), dirs & 42, V1 * parabolic(1) * xpush(log(2)), reclev+1); - } - void draw() { - draw_rec(viewctr.at->c7, 63, cview(), 0); - } + dq::visited.clear(); + dq::enqueue(viewctr.at, cview()); + + while(!dq::drawqueue.empty()) { + auto& p = dq::drawqueue.front(); + heptagon *h = get<0>(p); + transmatrix V = get<1>(p); + dynamicval b(band_shift, get<2>(p)); + bandfixer bf(V); + dq::drawqueue.pop(); + + cell *c = h->c7; + if(!do_draw(c, V)) continue; + drawcell(c, V, 0, false); + + dq::enqueue(h->move(bd_up), V * xpush(-log(2))); + dq::enqueue(h->move(bd_right), V * parabolic(1)); + dq::enqueue(h->move(bd_left), V * parabolic(-1)); + if(c->type == 6) + dq::enqueue(h->move(bd_down), V * xpush(log(2))); + // down_left + if(c->type == 7) { + dq::enqueue(h->move(bd_down_left), V * parabolic(-1) * xpush(log(2))); + dq::enqueue(h->move(bd_down_right), V * parabolic(1) * xpush(log(2))); + } + } + } transmatrix relative_matrix(heptagon *h2, heptagon *h1) { if(gmatrix0.count(h2->c7) && gmatrix0.count(h1->c7)) diff --git a/graph.cpp b/graph.cpp index 5e86b234..98baa2de 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3388,18 +3388,6 @@ void pushdown(cell *c, int& q, const transmatrix &V, double down, bool rezoom, b } } -bool dodrawcell(cell *c) { - // do not display out of range cells, unless on torus - if(c->pathdist == PINFD && geometry != gTorus && vid.use_smart_range == 0) - return false; - // do not display not fully generated cells, unless a cheater - if(c->mpdist > 7 && !cheater && !autocheat) return false; - // in the Yendor Challenge, scrolling back is forbidden - if(c->cpdist > 7 && yendor::on && !cheater && !autocheat) return false; - - return true; - } - // 1 : (floor, water); 2 : (water, bottom); 4 : (bottom, inf) int shallow(cell *c) { diff --git a/hyper.h b/hyper.h index 9f51a882..43901ddc 100644 --- a/hyper.h +++ b/hyper.h @@ -4356,5 +4356,14 @@ inline void delayed_geo_reset() { need_reset_geometry = true; } extern unordered_map params; +namespace dq { + extern set visited; + extern queue> drawqueue; + + void enqueue(heptagon *h, const transmatrix& T); + } + +bool do_draw(cell *c, const transmatrix& T); + } diff --git a/hypgraph.cpp b/hypgraph.cpp index 6e22cdb1..8c5a5781 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -690,8 +690,11 @@ transmatrix applyspin(const heptspin& hs, const transmatrix& V) { } bool in_smart_range(const transmatrix& T) { + if(std::isnan(T[2][2]) || std::isinf(T[2][2]) || T[2][2] > 1e8) return false; hyperpoint h1, h2, h3; applymodel(tC0(T), h1); + if(std::isnan(h1[0]) || std::isnan(h1[1])) return false; + if(std::isinf(h1[0]) || std::isinf(h1[1])) return false; ld x = vid.xcenter + vid.radius * h1[0]; ld y = vid.ycenter + vid.radius * h1[1] * vid.stretch; if(x > vid.xres * 2) return false; @@ -715,13 +718,6 @@ bool in_smart_range(const transmatrix& T) { y + 2 * max(y1, y2) > 0; } -// in hyperbolic quotient geometries, relying on pathdist is not sufficient -bool in_qrange(const transmatrix& V) { - if(!quotient || !hyperbolic || vid.use_smart_range) return true; - return in_smart_range(V); - // return V[2][2] < cosh(crossf * get_sightrange_ambush()); - } - namespace gp { /* @@ -741,7 +737,7 @@ void drawrec(cell *c, const transmatrix& V) { gp::local_info draw_li; void drawrec(cell *c, const transmatrix& V, gp::loc at, int dir, int maindir) { - if(dodrawcell(c)) { + if(do_draw(c, V)) { /* auto li = get_local_info(c); if(fix6(dir) != fix6(li.total_dir)) printf("totaldir %d/%d\n", dir, li.total_dir); if(at != li.relative) printf("at %s/%s\n", disp(at), disp(li.relative)); @@ -749,8 +745,7 @@ void drawrec(cell *c, const transmatrix& V) { draw_li.relative = at; draw_li.total_dir = fixg6(dir); transmatrix V1 = V * Tf[draw_li.last_dir][at.first&31][at.second&31][fixg6(dir)]; - if(in_qrange(V1)) - drawcell(c, V1, 0, false); + drawcell(c, V1, 0, false); } for(int i=0; itype; i++) { cell *c2 = c->move(i); @@ -765,7 +760,7 @@ void drawrec(cell *c, const transmatrix& V) { draw_li.relative = loc(0,0); draw_li.total_dir = 0; draw_li.last_dir = -1; - if(dodrawcell(c)) + if(do_draw(c, V)) drawcell(c, V, 0, false); for(int i=0; itype; i++) { cell *c2 = c->move(i); @@ -780,23 +775,14 @@ void drawrec(cell *c, const transmatrix& V) { void drawrec(const heptspin& hs, hstate s, const transmatrix& V, int reclev) { - // calc_relative_matrix(cwt.c, hs.at); - + // calc_relative_matrix(cwt.c, hs.at); cell *c = hs.at->c7; transmatrix V10; const transmatrix& V1 = hs.mirrored ? (V10 = V * Mirror) : V; - bool draw = c->pathdist < PINFD; + bool draw = false; - if(cells_drawn > vid.cells_drawn_limit || reclev >= 10000 || std::isinf(V[2][2]) || std::isnan(V[2][2]) || V[2][2] > 1e8) - draw = false; - else if(vid.use_smart_range) { - draw = reclev < 2 ? true : in_smart_range(V); - if(draw && vid.use_smart_range == 2) - setdist(c, 7, NULL); - } - if(GOLDBERG) { gp::drawrec(c, actualV(hs, V1)); } @@ -805,27 +791,30 @@ void drawrec(const heptspin& hs, hstate s, const transmatrix& V, int reclev) { auto& hi = irr::periodmap[hs.at]; transmatrix V0 = actualV(hs, V1); auto& vc = irr::cells_of_heptagon[hi.base.at]; - for(int i=0; ic.fix(hs.spin + d); // createMov(c, ds); - if(c->move(ds) && c->c.spin(ds) == 0 && dodrawcell(c->move(ds))) { + if(c->move(ds) && c->c.spin(ds) == 0) { transmatrix V2 = V1 * hexmove[d]; - if(in_qrange(V2)) - drawcell(c->move(ds), V2, 0, hs.mirrored ^ c->c.mirror(ds)); + if(do_draw(c->move(ds), V2)) + draw = true, + drawcell(c->move(ds), V2, 0, hs.mirrored ^ c->c.mirror(ds)); } } } @@ -928,10 +917,8 @@ void drawEuclidean() { if(locald < centerd) centerd = locald, centerover = cw, View = Mat; } - if(i < 30 || in_smart_range(Mat)) { - if(vid.use_smart_range == 2) setdist(cw.at, 7, cw.at); - if(dodrawcell(cw.at)) - drawcell(cw.at, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored); + if(do_draw(cw.at, Mat)) { + drawcell(cw.at, cw.mirrored ? Mat * Mirror : Mat, cw.spin, cw.mirrored); for(int x=-1; x<=+1; x++) for(int y=-1; y<=+1; y++) { auto p = at + pair_to_vec(x, y); @@ -1353,4 +1340,37 @@ void fix_the_band(transmatrix& T) { } } +namespace dq { + set visited; + queue> drawqueue; + + void enqueue(heptagon *h, const transmatrix& T) { + if(!h || visited.count(h)) { return; } + visited.insert(h); + drawqueue.emplace(h, T, band_shift); + } + + } + +bool do_draw(cell *c) { + // do not display out of range cells, unless on torus + if(c->pathdist == PINFD && geometry != gTorus && vid.use_smart_range == 0) + return false; + // do not display not fully generated cells, unless a cheater + if(c->mpdist > 7 && !cheater && !autocheat) return false; + // in the Yendor Challenge, scrolling back is forbidden + if(c->cpdist > 7 && yendor::on && !cheater && !autocheat) return false; + + return true; + } + +bool do_draw(cell *c, const transmatrix& T) { + if(!do_draw(c)) return false; + if(cells_drawn > vid.cells_drawn_limit) return false; + bool usr = vid.use_smart_range || quotient || torus; + if(usr && cells_drawn >= 50 && !in_smart_range(T)) return false; + if(vid.use_smart_range == 2) setdist(c, 7, c); + return true; + } + }