mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 09:50:34 +00:00
inverse tessellation operators
This commit is contained in:
parent
db96f3499c
commit
1f1e7d9bbf
11
cell.cpp
11
cell.cpp
@ -219,6 +219,9 @@ EX cell *createMov(cell *c, int d) {
|
||||
}
|
||||
hybrid::link();
|
||||
}
|
||||
else if(INVERSE) {
|
||||
return gp::inverse_move(c, d);
|
||||
}
|
||||
#endif
|
||||
#if CAP_ARCM
|
||||
else if(arcm::in() && PURE) {
|
||||
@ -289,7 +292,8 @@ EX void initcells() {
|
||||
DEBB(DF_INIT, ("initcells"));
|
||||
|
||||
hrmap* res = callhandlers((hrmap*)nullptr, hooks_newmap);
|
||||
if(res) currentmap = res;
|
||||
if(res) currentmap = res;
|
||||
else if(INVERSE) currentmap = gp::new_inverse();
|
||||
else if(fake::in()) currentmap = fake::new_map();
|
||||
else if(asonov::in()) currentmap = asonov::new_map();
|
||||
else if(nonisotropic || hybri) currentmap = nisot::new_map();
|
||||
@ -475,6 +479,11 @@ EX int celldist(cell *c) {
|
||||
#endif
|
||||
if(arcm::in() || ctof(c)) return c->master->distance;
|
||||
#if CAP_GP
|
||||
if(INVERSE) {
|
||||
cell *c1 = gp::get_mapped(c);
|
||||
return UIU(gp::compute_dist(c1, celldist)) / 2;
|
||||
/* TODO */
|
||||
}
|
||||
if(GOLDBERG) return gp::compute_dist(c, celldist);
|
||||
#endif
|
||||
int dx[MAX_S3];
|
||||
|
@ -737,7 +737,7 @@ enum eGeometry {
|
||||
|
||||
enum eGeometryClass { gcHyperbolic, gcEuclid, gcSphere, gcSolNIH, gcNil, gcProduct, gcSL2 };
|
||||
|
||||
enum class eVariation { bitruncated, pure, goldberg, irregular, dual };
|
||||
enum class eVariation { bitruncated, pure, goldberg, irregular, dual, untruncated, warped, unrectified };
|
||||
|
||||
typedef flagtype modecode_t;
|
||||
|
||||
|
@ -3558,7 +3558,7 @@ EX namespace windmap {
|
||||
// cw.spin = 0;
|
||||
neighbors.emplace_back();
|
||||
auto &v = neighbors.back();
|
||||
if(NONSTDVAR && !sphere && !arcm::in() && !hybri)
|
||||
if(NONSTDVAR && !sphere && !arcm::in() && !hybri && !INVERSE)
|
||||
for(int l=0; l<S7; l++) {
|
||||
v.push_back(getId(cw + cth + l + wstep + cth));
|
||||
}
|
||||
|
@ -675,7 +675,7 @@ void geometry_information::generate_floorshapes() {
|
||||
}
|
||||
#endif
|
||||
|
||||
else if(GOLDBERG) { /* will be generated on the fly */ }
|
||||
else if(GOLDBERG_INV) { /* will be generated on the fly */ }
|
||||
|
||||
else if(inforder::mixed()) { /* will be generated on the fly */ }
|
||||
|
||||
@ -800,22 +800,38 @@ EX namespace gp {
|
||||
|
||||
int get_plainshape_id(cell *c) {
|
||||
int siid, sidir;
|
||||
if(geosupport_threecolor() == 2) {
|
||||
auto si = patterns::getpatterninfo(c, patterns::PAT_COLORING, patterns::SPF_NO_SUBCODES);
|
||||
siid = si.id>>2;
|
||||
// if(siid == 2) si.dir++;
|
||||
// if(siid != pattern_threecolor(c)) printf("threecolor mismatch\n");
|
||||
// if(pattern_threecolor(createMov(c, c->fixd(si.dir))) != (siid+1)%3) printf("threecolor mismatch direction\n");
|
||||
sidir = c->c.fix(si.dir);
|
||||
cell *c1 = c;
|
||||
auto f = [&] {
|
||||
if(geosupport_threecolor() == 2) {
|
||||
auto si = patterns::getpatterninfo(c1, patterns::PAT_COLORING, patterns::SPF_NO_SUBCODES);
|
||||
siid = si.id>>2;
|
||||
// if(siid == 2) si.dir++;
|
||||
// if(siid != pattern_threecolor(c)) printf("threecolor mismatch\n");
|
||||
// if(pattern_threecolor(createMov(c, c->fixd(si.dir))) != (siid+1)%3) printf("threecolor mismatch direction\n");
|
||||
sidir = c1->c.fix(si.dir);
|
||||
}
|
||||
else if(geosupport_football() == 2) {
|
||||
siid = !pseudohept(c1);
|
||||
sidir = !ishex1(c1);
|
||||
}
|
||||
else if(geosupport_chessboard()) {
|
||||
siid = !chessvalue(c1);
|
||||
sidir = 0;
|
||||
}
|
||||
else {
|
||||
siid = 0;
|
||||
sidir = 0;
|
||||
}
|
||||
};
|
||||
if(INVERSE && gp::variation_for(gp::param) == eVariation::goldberg) {
|
||||
c1 = gp::get_mapped(c);
|
||||
UIU(f());
|
||||
}
|
||||
else if(geosupport_football() == 2) {
|
||||
siid = !pseudohept(c);
|
||||
sidir = !ishex1(c);
|
||||
}
|
||||
else {
|
||||
else if(INVERSE) {
|
||||
siid = 0;
|
||||
sidir = 0;
|
||||
}
|
||||
else f();
|
||||
auto& id = cgi.gpdata->pshid[siid][sidir][draw_li.relative.first&31][draw_li.relative.second&31][gmod(draw_li.total_dir, S6)];
|
||||
if(id == -1 && sphere && isize(cgi.shFloor.b) > 0) {
|
||||
forCellEx(c1, c) if(!gmatrix0.count(c1)) return 0;
|
||||
@ -862,7 +878,7 @@ EX int shvid(cell *c) {
|
||||
cell *c1 = hybrid::get_where(c).first;
|
||||
return PIU( shvid(c1) );
|
||||
}
|
||||
else if(GOLDBERG)
|
||||
else if(GOLDBERG_INV)
|
||||
return gp::get_plainshape_id(c);
|
||||
else if(IRREGULAR)
|
||||
return irr::cellindex[c];
|
||||
|
12
geom-exp.cpp
12
geom-exp.cpp
@ -1081,6 +1081,18 @@ int read_geom_args() {
|
||||
shift(); gp::param.second = argi();
|
||||
set_variation(eVariation::goldberg);
|
||||
}
|
||||
else if(argis("-unrectified")) {
|
||||
PHASEFROM(2);
|
||||
set_variation(eVariation::unrectified);
|
||||
}
|
||||
else if(argis("-untruncated")) {
|
||||
PHASEFROM(2);
|
||||
set_variation(eVariation::untruncated);
|
||||
}
|
||||
else if(argis("-warped")) {
|
||||
PHASEFROM(2);
|
||||
set_variation(eVariation::warped);
|
||||
}
|
||||
#endif
|
||||
#if CAP_FIELD
|
||||
else if(argis("-fi")) {
|
||||
|
11
geometry.cpp
11
geometry.cpp
@ -487,6 +487,13 @@ void geometry_information::prepare_basics() {
|
||||
|
||||
if(arcm::in() && !prod)
|
||||
ginf[gArchimedean].cclass = gcHyperbolic;
|
||||
|
||||
dynamicval<eVariation> gv(variation, variation);
|
||||
bool inv = INVERSE;
|
||||
if(INVERSE) {
|
||||
variation = gp::variation_for(gp::param);
|
||||
println(hlog, "bitruncated = ", BITRUNCATED);
|
||||
}
|
||||
|
||||
if(hybri) {
|
||||
auto t = this;
|
||||
@ -582,7 +589,7 @@ void geometry_information::prepare_basics() {
|
||||
base_distlimit = ginf[geometry].distlimit[!BITRUNCATED];
|
||||
|
||||
#if CAP_GP
|
||||
gp::compute_geometry();
|
||||
gp::compute_geometry(inv);
|
||||
#endif
|
||||
#if CAP_IRR
|
||||
irr::compute_geometry();
|
||||
@ -1014,7 +1021,7 @@ EX string cgi_string() {
|
||||
return s;
|
||||
}
|
||||
|
||||
if(GOLDBERG) V("GP", its(gp::param.first) + "," + its(gp::param.second));
|
||||
if(GOLDBERG_INV) V("GP", its(gp::param.first) + "," + its(gp::param.second));
|
||||
if(IRREGULAR) V("IRR", its(irr::irrid));
|
||||
|
||||
if(arcm::in()) V("ARCM", arcm::current.symbol);
|
||||
|
@ -501,6 +501,37 @@ EX hyperpoint randomPointIn(int t) {
|
||||
EX hyperpoint get_corner_position(cell *c, int cid, ld cf IS(3)) {
|
||||
#if CAP_GP
|
||||
if(GOLDBERG) return gp::get_corner_position(c, cid, cf);
|
||||
if(UNTRUNCATED) {
|
||||
cell *c1 = gp::get_mapped(c);
|
||||
cellwalker cw(c1, cid*2);
|
||||
if(!gp::untruncated_shift(c)) cw--;
|
||||
hyperpoint h = UIU(nearcorner(c1, cw.spin));
|
||||
return mid_at_actual(h, 3/cf);
|
||||
}
|
||||
if(UNRECTIFIED) {
|
||||
cell *c1 = gp::get_mapped(c);
|
||||
hyperpoint h = UIU(nearcorner(c1, cid));
|
||||
return mid_at_actual(h, 3/cf);
|
||||
}
|
||||
if(WARPED) {
|
||||
int sh = gp::untruncated_shift(c);
|
||||
cell *c1 = gp::get_mapped(c);
|
||||
if(sh == 2) {
|
||||
cellwalker cw(c, cid);
|
||||
hyperpoint h1 = UIU(tC0(currentmap->adj(c1, cid)));
|
||||
cw--;
|
||||
hyperpoint h2 = UIU(tC0(currentmap->adj(c1, cw.spin)));
|
||||
hyperpoint h = mid(h1, h2);
|
||||
return mid_at_actual(h, 3/cf);
|
||||
}
|
||||
else {
|
||||
cellwalker cw(c1, cid*2);
|
||||
if(!gp::untruncated_shift(c)) cw--;
|
||||
hyperpoint h = UIU(nearcorner(c1, cw.spin));
|
||||
h = mid(h, C0);
|
||||
return mid_at_actual(h, 3/cf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if CAP_IRR
|
||||
if(IRREGULAR) {
|
||||
@ -560,7 +591,7 @@ EX bool approx_nearcorner = false;
|
||||
/** /brief get the coordinates of the center of c->move(i) */
|
||||
|
||||
EX hyperpoint nearcorner(cell *c, int i) {
|
||||
if(GOLDBERG) {
|
||||
if(GOLDBERG_INV) {
|
||||
cellwalker cw(c, i);
|
||||
cw += wstep;
|
||||
transmatrix cwm = currentmap->adj(c, i);
|
||||
@ -657,14 +688,19 @@ EX hyperpoint nearcorner(cell *c, int i) {
|
||||
|
||||
EX hyperpoint farcorner(cell *c, int i, int which) {
|
||||
#if CAP_GP
|
||||
if(GOLDBERG) {
|
||||
if(GOLDBERG_INV) {
|
||||
cellwalker cw(c, i);
|
||||
cw += wstep;
|
||||
if(!cw.mirrored) cw += (which?-1:2);
|
||||
else cw += (which?2:-1);
|
||||
transmatrix cwm = currentmap->adj(c, i);
|
||||
auto li1 = gp::get_local_info(cw.at);
|
||||
return cwm * get_corner_position(li1, cw.spin);
|
||||
if(gp::variation_for(gp::param) == eVariation::goldberg) {
|
||||
auto li1 = gp::get_local_info(cw.at);
|
||||
return cwm * get_corner_position(li1, cw.spin);
|
||||
}
|
||||
else {
|
||||
return cwm * get_corner_position(cw.at, cw.spin, 3);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if CAP_IRR
|
||||
|
398
goldberg.cpp
398
goldberg.cpp
@ -10,6 +10,11 @@
|
||||
#include "hyper.h"
|
||||
namespace hr {
|
||||
|
||||
#if HDR
|
||||
struct hrmap;
|
||||
extern hrmap *currentmap;
|
||||
#endif
|
||||
|
||||
EX namespace gp {
|
||||
|
||||
#if HDR
|
||||
@ -34,6 +39,15 @@ EX namespace gp {
|
||||
loc operator*(int i) {
|
||||
return loc(first*i, second*i);
|
||||
}
|
||||
|
||||
int operator %(int i) {
|
||||
return gmod(first, i) + gmod(second, i);
|
||||
}
|
||||
|
||||
loc operator /(int i) {
|
||||
return loc(first/i, second/i);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct local_info {
|
||||
@ -96,6 +110,10 @@ EX namespace gp {
|
||||
}
|
||||
|
||||
EX local_info get_local_info(cell *c) {
|
||||
if(INVERSE) {
|
||||
c = get_mapped(c);
|
||||
return UIU(get_local_info(c));
|
||||
}
|
||||
local_info li;
|
||||
if(c == c->master->c7) {
|
||||
li.relative = loc(0,0);
|
||||
@ -609,9 +627,9 @@ EX namespace gp {
|
||||
|
||||
map<pair<int, int>, loc> center_locs;
|
||||
|
||||
EX void compute_geometry() {
|
||||
EX void compute_geometry(bool inv) {
|
||||
center_locs.clear();
|
||||
if(GOLDBERG) {
|
||||
if(GOLDBERG_INV || inv) {
|
||||
if(!cgi.gpdata) cgi.gpdata = make_shared<geometry_information::gpdata_t>();
|
||||
gp::clear_plainshapes();
|
||||
int x = param.first;
|
||||
@ -622,6 +640,7 @@ EX namespace gp {
|
||||
cgi.gpdata->area = x * x + y * y;
|
||||
next = point3(x+y/2., -y * sqrt(3) / 2, 0);
|
||||
ld scale = 1 / hypot_d(2, next);
|
||||
if(!GOLDBERG) scale = 1;
|
||||
cgi.crossf *= scale;
|
||||
cgi.hepvdist *= scale;
|
||||
cgi.hexhexdist *= scale;
|
||||
@ -662,6 +681,14 @@ EX namespace gp {
|
||||
return v;
|
||||
}
|
||||
|
||||
EX eVariation variation_for(loc xy) {
|
||||
if(xy.first == 1 && xy.second == 0)
|
||||
return eVariation::pure;
|
||||
if(xy.first == 1 && xy.second == 1 && S3 == 3)
|
||||
return eVariation::bitruncated;
|
||||
return eVariation::goldberg;
|
||||
}
|
||||
|
||||
void whirl_set(loc xy) {
|
||||
xy = internal_representation(xy);
|
||||
if(xy.second && xy.second != xy.first && nonorientable) {
|
||||
@ -713,31 +740,56 @@ EX namespace gp {
|
||||
}
|
||||
#endif
|
||||
if(min_quality == 0 && min_quality_chess == 0) {
|
||||
dialog::addBoolItem(XLAT("pure"), univ_param() == loc(1,0) && !IRREGULAR, 'a');
|
||||
dialog::addBoolItem(XLAT("pure"), PURE || (GOLDBERG && univ_param() == loc(1,0)), 'a');
|
||||
dialog::lastItem().value = "GP(1,0)";
|
||||
dialog::add_action_confirmed([] { whirl_set(loc(1, 0)); });
|
||||
}
|
||||
|
||||
if(min_quality_chess == 0)
|
||||
if(min_quality_chess == 0) {
|
||||
dialog::addBoolItem(XLAT("bitruncated"), BITRUNCATED, 'b');
|
||||
dialog::add_action_confirmed([] {
|
||||
if(S3 == 4) {
|
||||
if(!BITRUNCATED) {
|
||||
stop_game();
|
||||
set_variation(eVariation::bitruncated);
|
||||
start_game();
|
||||
}
|
||||
}
|
||||
else
|
||||
whirl_set(loc(1, 1));
|
||||
});
|
||||
}
|
||||
|
||||
dialog::lastItem().value = S3 == 3 ? "GP(1,1)" : XLAT(BITRUNCATED ? "ON" : "OFF");
|
||||
|
||||
if(min_quality == 0 || min_quality_chess) {
|
||||
dialog::addBoolItem(XLAT(S3 == 3 ? "chamfered" : "expanded"), univ_param() == loc(2,0), 'c');
|
||||
dialog::addBoolItem(XLAT(S3 == 3 ? "chamfered" : "expanded"), univ_param() == loc(2,0) && GOLDBERG, 'c');
|
||||
dialog::lastItem().value = "GP(2,0)";
|
||||
dialog::add_action_confirmed([] {
|
||||
whirl_set(loc(2, 0));
|
||||
});
|
||||
}
|
||||
|
||||
if(S3 == 3) {
|
||||
dialog::addBoolItem(XLAT("2x bitruncated"), univ_param() == loc(3,0), 'd');
|
||||
dialog::addBoolItem(XLAT("2x bitruncated"), GOLDBERG && univ_param() == loc(3,0), 'd');
|
||||
dialog::lastItem().value = "GP(3,0)";
|
||||
dialog::add_action_confirmed([] {
|
||||
whirl_set(loc(3, 0));
|
||||
});
|
||||
}
|
||||
else {
|
||||
dialog::addBoolItem(XLAT("rectified"), param == loc(1,1) && GOLDBERG, 'd');
|
||||
dialog::lastItem().value = "GP(1,1)";
|
||||
dialog::add_action_confirmed([] {
|
||||
whirl_set(loc(1, 1));
|
||||
});
|
||||
}
|
||||
|
||||
dialog::addBreak(100);
|
||||
dialog::addSelItem("x", its(config.first), 'x');
|
||||
dialog::add_action([] { dialog::editNumber(config.first, 0, 8, 1, 1, "x", helptext()); });
|
||||
dialog::addSelItem("y", its(config.second), 'y');
|
||||
dialog::add_action([] { dialog::editNumber(config.second, 0, 8, 1, 1, "y", helptext()); });
|
||||
|
||||
if(config.second && config.second != config.first && nonorientable) {
|
||||
dialog::addInfo(XLAT("This does not work in non-orientable geometries"));
|
||||
@ -748,6 +800,9 @@ EX namespace gp {
|
||||
dialog::addInfo(XLAT("This pattern needs x-y divisible by 2"));
|
||||
else
|
||||
dialog::addBoolItem(XLAT("select"), param == internal_representation(config) && !IRREGULAR, 'f');
|
||||
dialog::add_action_confirmed([] { whirl_set(config); });
|
||||
|
||||
dialog::addBreak(100);
|
||||
|
||||
if(irr::supports(geometry)) {
|
||||
dialog::addBoolItem(XLAT("irregular"), IRREGULAR, 'i');
|
||||
@ -760,52 +815,81 @@ EX namespace gp {
|
||||
if(!IRREGULAR) irr::visual_creator();
|
||||
}));
|
||||
}
|
||||
|
||||
dialog::addBreak(100);
|
||||
int style = 0;
|
||||
auto v0 = variation_for(param);
|
||||
bool bad_bi = BITRUNCATED && a4;
|
||||
if(!bad_bi) {
|
||||
dynamicval<eVariation> v(variation, v0);
|
||||
if(geosupport_football() == 2) style = 3;
|
||||
if(geosupport_chessboard()) style = 2;
|
||||
}
|
||||
if(style == 2) {
|
||||
dialog::addBoolItem(XLAT("inverse rectify"), UNRECTIFIED, 'r');
|
||||
dialog::add_action_confirmed([v0] {
|
||||
if(UNRECTIFIED) set_variation(v0);
|
||||
else set_variation(eVariation::unrectified);
|
||||
start_game();
|
||||
});
|
||||
}
|
||||
else if(style == 3) {
|
||||
dialog::addBoolItem(XLAT("inverse truncate"), UNTRUNCATED, 't');
|
||||
dialog::add_action_confirmed([v0] {
|
||||
if(UNTRUNCATED) set_variation(v0);
|
||||
else set_variation(eVariation::untruncated);
|
||||
start_game();
|
||||
});
|
||||
dialog::addBoolItem(XLAT("warped version"), WARPED, 'w');
|
||||
dialog::add_action_confirmed([v0] {
|
||||
if(WARPED) set_variation(v0);
|
||||
else set_variation(eVariation::warped);
|
||||
start_game();
|
||||
});
|
||||
}
|
||||
|
||||
dialog::addBreak(100);
|
||||
dialog::addItem(XLAT("swap x and y"), 'z');
|
||||
dialog::add_action([] { swap(config.first, config.second); });
|
||||
|
||||
bool have_dual = !bad_bi && !IRREGULAR && !WARPED;
|
||||
if(S3 == 3 && UNTRUNCATED && (univ_param()*loc(1,1)) % 3) have_dual = false;
|
||||
if(S3 == 4 && UNRECTIFIED && (univ_param()*loc(1,1)) % 2) have_dual = false;
|
||||
|
||||
if(have_dual) {
|
||||
dialog::addItem(XLAT("dual of current"), 'D');
|
||||
dialog::add_action([] {
|
||||
auto p = univ_param();
|
||||
if(S3 == 3 && !UNTRUNCATED) {
|
||||
println(hlog, "set param to ", p * loc(1,1));
|
||||
whirl_set(p * loc(1, 1));
|
||||
set_variation(eVariation::untruncated);
|
||||
start_game();
|
||||
}
|
||||
else if(S3 == 4 && !UNRECTIFIED) {
|
||||
whirl_set(p * loc(1, 1));
|
||||
set_variation(eVariation::unrectified);
|
||||
start_game();
|
||||
}
|
||||
else if(S3 == 3 && UNTRUNCATED) {
|
||||
println(hlog, "whirl_set to ", (p * loc(1,1)) / 3);
|
||||
whirl_set((p * loc(1,1)) / 3);
|
||||
}
|
||||
else if(S3 == 4 && UNRECTIFIED) {
|
||||
whirl_set((p * loc(1,1)) / 2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dialog::addBreak(100);
|
||||
dialog::addHelp();
|
||||
dialog::add_action([] { gotoHelp(helptext()); });
|
||||
dialog::addBack();
|
||||
dialog::display();
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
if(uni == 'a') dialog::do_if_confirmed([] {
|
||||
whirl_set(loc(1, 0));
|
||||
});
|
||||
else if(uni == 'b') dialog::do_if_confirmed([] {
|
||||
if(S3 == 4) {
|
||||
if(!BITRUNCATED) {
|
||||
stop_game();
|
||||
set_variation(eVariation::bitruncated);
|
||||
start_game();
|
||||
}
|
||||
}
|
||||
else
|
||||
whirl_set(loc(1, 1));
|
||||
});
|
||||
else if(uni == 'c') dialog::do_if_confirmed([] {
|
||||
whirl_set(loc(2, 0));
|
||||
});
|
||||
else if(uni == 'd') dialog::do_if_confirmed([] {
|
||||
whirl_set(S3 == 3 ? loc(3, 0) : loc(1,1));
|
||||
});
|
||||
else if(uni == 'f') dialog::do_if_confirmed([] {
|
||||
whirl_set(config);
|
||||
});
|
||||
else if(uni == 'x')
|
||||
dialog::editNumber(config.first, 0, 8, 1, 1, "x", helptext());
|
||||
else if(uni == 'y')
|
||||
dialog::editNumber(config.second, 0, 8, 1, 1, "y", helptext());
|
||||
else if(uni == 'z')
|
||||
swap(config.first, config.second);
|
||||
else if(uni == '?' || sym == SDLK_F1 || uni == 'h' || uni == '2')
|
||||
gotoHelp(helptext());
|
||||
else if(doexiton(sym, uni))
|
||||
popScreen();
|
||||
};
|
||||
}
|
||||
|
||||
EX loc univ_param() {
|
||||
if(GOLDBERG) return param;
|
||||
if(GOLDBERG_INV) return param;
|
||||
else if(PURE) return loc(1,0);
|
||||
else return loc(1,1);
|
||||
}
|
||||
@ -892,6 +976,7 @@ EX namespace gp {
|
||||
}
|
||||
|
||||
EX int compute_dist(cell *c, int master_function(cell*)) {
|
||||
if(!GOLDBERG) return master_function(c);
|
||||
auto li = get_local_info(c);
|
||||
be_in_triangle(li);
|
||||
|
||||
@ -934,6 +1019,10 @@ EX namespace gp {
|
||||
EX array<heptagon*, 3> get_masters(cell *c) {
|
||||
if(0);
|
||||
#if CAP_GP
|
||||
else if(INVERSE) {
|
||||
c = get_mapped(c);
|
||||
return UIU(get_masters(c));
|
||||
}
|
||||
else if(GOLDBERG) {
|
||||
auto li = get_local_info(c);
|
||||
be_in_triangle(li);
|
||||
@ -963,23 +1052,232 @@ EX namespace gp {
|
||||
else if(BITRUNCATED)
|
||||
return XLAT("bitruncated");
|
||||
#if CAP_GP
|
||||
else if(param == loc(1, 0))
|
||||
else if(GOLDBERG && param == loc(1, 0))
|
||||
return XLAT("pure");
|
||||
else if(param == loc(1, 1) && S3 == 3)
|
||||
else if(GOLDBERG && param == loc(1, 1) && S3 == 3)
|
||||
return XLAT("bitruncated");
|
||||
else if(param == loc(1, 1) && S3 == 4)
|
||||
else if(GOLDBERG && param == loc(1, 1) && S3 == 4)
|
||||
return XLAT("rectified");
|
||||
else if(param == loc(2, 0))
|
||||
else if(UNRECTIFIED && param == loc(1, 1) && S3 == 4)
|
||||
return XLAT("dual");
|
||||
else if(UNTRUNCATED && param == loc(1, 1) && S3 == 3)
|
||||
return XLAT("dual");
|
||||
else if(GOLDBERG && param == loc(2, 0))
|
||||
return S3 == 3 ? XLAT("chamfered") : XLAT("expanded");
|
||||
else if(param == loc(3, 0) && S3 == 3)
|
||||
else if(GOLDBERG && param == loc(3, 0) && S3 == 3)
|
||||
return XLAT("2x bitruncated");
|
||||
else {
|
||||
auto p = human_representation(param);
|
||||
return "GP(" + its(p.first) + "," + its(p.second) + ")";
|
||||
string s = "GP(" + its(p.first) + "," + its(p.second) + ")";
|
||||
if(UNRECTIFIED) return XLAT("unrectified") + " " + s;
|
||||
if(WARPED) return XLAT("warped") + " " + s;
|
||||
if(UNTRUNCATED) return XLAT("untruncated") + " " + s;
|
||||
return s;
|
||||
}
|
||||
#else
|
||||
else return "UNSUPPORTED";
|
||||
#endif
|
||||
}
|
||||
|
||||
/* inverse map */
|
||||
|
||||
EX hrmap *pmap;
|
||||
// EX geometry_information *underlying_cgip;
|
||||
|
||||
struct hrmap_inverse : hrmap {
|
||||
hrmap *underlying_map;
|
||||
|
||||
map<cell*, cell*> mapping;
|
||||
map<cell*, int> shift;
|
||||
|
||||
template<class T> auto in_underlying(const T& t) -> decltype(t()) {
|
||||
dynamicval<hrmap*> gpm(pmap, this);
|
||||
dynamicval<eVariation> gva(variation, variation_for(param));
|
||||
dynamicval<hrmap*> gu(currentmap, underlying_map);
|
||||
// dynamicval<geometry_information*> gc(cgip, underlying_cgip);
|
||||
return t();
|
||||
}
|
||||
|
||||
cell* get_mapped(cell *underlying_cell, int set_shift) {
|
||||
if(mapping.count(underlying_cell))
|
||||
return mapping[underlying_cell];
|
||||
int d = underlying_cell->type;
|
||||
if(UNTRUNCATED) d /= 2;
|
||||
if(WARPED && set_shift < 2) d /= 2;
|
||||
cell *c = newCell(d, underlying_cell->master);
|
||||
mapping[underlying_cell] = c;
|
||||
if(!UNRECTIFIED) shift[c] = set_shift;
|
||||
mapping[c] = underlying_cell;
|
||||
return c;
|
||||
}
|
||||
|
||||
~hrmap_inverse() {
|
||||
in_underlying([this] { delete underlying_map; });
|
||||
}
|
||||
|
||||
heptagon *getOrigin() override { return in_underlying([this] { return underlying_map->getOrigin(); }); }
|
||||
|
||||
cell *gs;
|
||||
|
||||
cell* gamestart() override {
|
||||
return gs;
|
||||
}
|
||||
|
||||
hrmap_inverse() {
|
||||
if(0) {
|
||||
println(hlog, "making ucgi");
|
||||
dynamicval<eVariation> gva(variation, variation_for(param));
|
||||
check_cgi();
|
||||
cgi.require_basics();
|
||||
// underlying_cgip = cgip;
|
||||
println(hlog, "done ucgi");
|
||||
}
|
||||
bool warped = WARPED;
|
||||
in_underlying([&,this] {
|
||||
initcells();
|
||||
underlying_map = currentmap;
|
||||
gs = currentmap->gamestart();
|
||||
if(!warped) gs = gs->cmove(0);
|
||||
});
|
||||
if(UNTRUNCATED) gs = get_mapped(gs, 1);
|
||||
else gs = get_mapped(gs, 2);
|
||||
for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL;
|
||||
}
|
||||
|
||||
cell *create_move(cell *parent, int d) {
|
||||
if(UNRECTIFIED) {
|
||||
cellwalker cw(mapping[parent], d);
|
||||
in_underlying([&] {
|
||||
cw += wstep;
|
||||
cw --;
|
||||
cw += wstep;
|
||||
cw --;
|
||||
});
|
||||
cw.at = get_mapped(cw.at, 0);
|
||||
parent->c.connect(d, cw.at, cw.spin, cw.mirrored);
|
||||
return cw.at;
|
||||
}
|
||||
if(UNTRUNCATED) {
|
||||
cellwalker cw(mapping[parent], 2*d+shift[parent]);
|
||||
in_underlying([&] {
|
||||
cw += wstep;
|
||||
});
|
||||
cw.at = get_mapped(cw.at, cw.spin & 1);
|
||||
parent->c.connect(d, cw.at, cw.spin / 2, cw.mirrored);
|
||||
return cw.at;
|
||||
}
|
||||
if(WARPED) {
|
||||
int sh = shift[parent];
|
||||
if(sh == 2) {
|
||||
cellwalker cw(mapping[parent], d);
|
||||
in_underlying([&] { cw += wstep; });
|
||||
cw.at = get_mapped(cw.at, cw.spin & 1);
|
||||
parent->c.connect(d, cw.at, cw.spin / 2, cw.mirrored);
|
||||
return cw.at;
|
||||
}
|
||||
else {
|
||||
cellwalker cw(mapping[parent], 2*d+sh);
|
||||
in_underlying([&] {
|
||||
cw += wstep;
|
||||
});
|
||||
cw.at = get_mapped(cw.at, 2);
|
||||
parent->c.connect(d, cw.at, cw.spin, cw.mirrored);
|
||||
return cw.at;
|
||||
}
|
||||
}
|
||||
throw "unimplemented";
|
||||
}
|
||||
|
||||
transmatrix adj(cell *c, int d) override {
|
||||
transmatrix T;
|
||||
if(UNRECTIFIED) {
|
||||
cellwalker cw(mapping[c], d);
|
||||
in_underlying([&] {
|
||||
T = currentmap->adj(cw.at, cw.spin);
|
||||
cw += wstep;
|
||||
cw --;
|
||||
T = T * currentmap->adj(cw.at, cw.spin);
|
||||
});
|
||||
}
|
||||
if(UNTRUNCATED) {
|
||||
cellwalker cw(mapping[c], 2*d+shift[c]);
|
||||
in_underlying([&] { T = currentmap->adj(cw.at, cw.spin); });
|
||||
}
|
||||
if(WARPED) {
|
||||
int sh = shift[c];
|
||||
if(sh == 2) {
|
||||
auto c1 = mapping[c];
|
||||
in_underlying([&] { T = currentmap->adj(c1, d); });
|
||||
}
|
||||
else {
|
||||
cellwalker cw(mapping[c], 2*d+shift[c]);
|
||||
in_underlying([&] { T = currentmap->adj(cw.at, cw.spin); });
|
||||
}
|
||||
}
|
||||
return T;
|
||||
}
|
||||
|
||||
void draw() override {
|
||||
|
||||
dq::clear_all();
|
||||
|
||||
auto enqueue = (quotient ? dq::enqueue_by_matrix_c : dq::enqueue_c);
|
||||
enqueue(centerover, cview());
|
||||
|
||||
while(!dq::drawqueue_c.empty()) {
|
||||
auto& p = dq::drawqueue_c.front();
|
||||
cell *c = get<0>(p);
|
||||
transmatrix V = get<1>(p);
|
||||
dynamicval<ld> b(band_shift, get<2>(p));
|
||||
bandfixer bf(V);
|
||||
auto c1 = get_mapped(c, 0);
|
||||
|
||||
in_underlying([&] {
|
||||
if(GOLDBERG) {
|
||||
gp::draw_li = gp::get_local_info(c1);
|
||||
}
|
||||
else {
|
||||
gp::draw_li.relative.first = shvid(c1);
|
||||
gp::draw_li.relative.second = shift[c];
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
dq::drawqueue_c.pop();
|
||||
|
||||
if(!do_draw(c, V)) continue;
|
||||
drawcell(c, V);
|
||||
|
||||
for(int i=0; i<c->type; i++) if(c->cmove(i))
|
||||
enqueue(c->move(i), V * adj(c, i));
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
EX hrmap* new_inverse() { return new hrmap_inverse; }
|
||||
|
||||
hrmap_inverse* inv_map() { return (hrmap_inverse*)currentmap; }
|
||||
|
||||
EX hrmap* get_underlying_map() { return inv_map()->underlying_map; }
|
||||
EX cell* get_mapped(cell *c) { return inv_map()->get_mapped(c, 0); }
|
||||
EX int untruncated_shift(cell *c) { return inv_map()->shift[c]; }
|
||||
|
||||
EX cell *inverse_move(cell *c, int d) { return inv_map()->create_move(c, d); }
|
||||
|
||||
#if HDR
|
||||
template<class T> auto in_underlying_geometry(const T& f) -> decltype(f()) {
|
||||
if(!INVERSE) return f();
|
||||
dynamicval<hrmap*> gpm(pmap, currentmap);
|
||||
dynamicval<eVariation> gva(variation, variation_for(param));
|
||||
dynamicval<hrmap*> gu(currentmap, get_underlying_map());
|
||||
// dynamicval<geometry_information*> gc(cgip, underlying_cgip);
|
||||
return f();
|
||||
}
|
||||
|
||||
#define UIU(x) hr::gp::in_underlying_geometry([&] { return (x); })
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
}}
|
||||
|
8
hyper.h
8
hyper.h
@ -176,6 +176,14 @@ void addMessage(string s, char spamtype = 0);
|
||||
#define SG3 (S3==3?3:2)
|
||||
#define SG2 (S3==3?2:1)
|
||||
|
||||
#define GOLDBERG_INV (GOLDBERG || INVERSE)
|
||||
|
||||
#define INVERSE among(variation, eVariation::unrectified, eVariation::warped, eVariation::untruncated )
|
||||
|
||||
#define UNRECTIFIED (variation == eVariation::unrectified)
|
||||
#define WARPED (variation == eVariation::warped)
|
||||
#define UNTRUNCATED (variation == eVariation::untruncated)
|
||||
|
||||
#define GOLDBERG (variation == eVariation::goldberg)
|
||||
#define IRREGULAR (variation == eVariation::irregular)
|
||||
#define PURE (variation == eVariation::pure)
|
||||
|
@ -278,7 +278,7 @@ EX bool haveOrbPower() {
|
||||
cell *c = dcal[i];
|
||||
if(itemclass(c->item) == IC_ORB) return true;
|
||||
}
|
||||
else if(sphere_narcm && WDIM == 2) for(int i=0; i<spherecells(); i++) {
|
||||
else if(sphere_narcm && WDIM == 2 && !INVERSE) for(int i=0; i<spherecells(); i++) {
|
||||
cell *c = getDodecahedron(i)->c7;
|
||||
if(itemclass(c->item) == IC_ORB) return true;
|
||||
forCellEx(c2, c) if(itemclass(c2->item) == IC_ORB) return true;
|
||||
|
18
pattern2.cpp
18
pattern2.cpp
@ -86,6 +86,11 @@ EX int chessvalue(cell *c) {
|
||||
if(arcm::in())
|
||||
return arcm::chessvalue(c);
|
||||
else
|
||||
#endif
|
||||
#if CAP_GP
|
||||
if(WARPED)
|
||||
return gp::untruncated_shift(c) == 2;
|
||||
else
|
||||
#endif
|
||||
return celldist(c) & 1;
|
||||
}
|
||||
@ -269,7 +274,7 @@ EX int fiftyval200(cell *c) {
|
||||
// zebraval
|
||||
|
||||
int dir_bitrunc457(cell *c) {
|
||||
if(GOLDBERG) return c->master->zebraval / 10;
|
||||
if(GOLDBERG_INV) return c->master->zebraval / 10;
|
||||
int wset = 0;
|
||||
int has1 = 0;
|
||||
for(int i=0; i<4; i++) {
|
||||
@ -291,6 +296,10 @@ int val46(cell *c);
|
||||
EX int zebra40(cell *c) {
|
||||
if(euclid) return pattern_threecolor(c);
|
||||
else if(IRREGULAR) return c->master->zebraval/10;
|
||||
else if(INVERSE) {
|
||||
cell *c1 = gp::get_mapped(c);
|
||||
return UIU(zebra40(c1));
|
||||
}
|
||||
else if(a46) {
|
||||
int v = val46(c);
|
||||
if(v<4) return v;
|
||||
@ -384,7 +393,7 @@ EX int fieldval_uniq(cell *c) {
|
||||
else if(IRREGULAR) return irr::cellindex[c];
|
||||
#endif
|
||||
#if CAP_GP
|
||||
else if(GOLDBERG) return (get_code(gp::get_local_info(c)) << 8) | (c->master->fieldval / S7);
|
||||
else if(GOLDBERG_INV) return (get_code(gp::get_local_info(c)) << 8) | (c->master->fieldval / S7);
|
||||
#endif
|
||||
if(ctof(c)) return c->master->fieldval;
|
||||
else return createMov(c, 0)->master->fieldval + 256 * createMov(c,2)->master->fieldval + (1<<16) * createMov(c,4)->master->fieldval;
|
||||
@ -1228,6 +1237,8 @@ EX bool geosupport_chessboard() {
|
||||
(arcm::in() && PURE) ? arcm::current.support_chessboard() :
|
||||
(arcm::in() && DUAL) ? arcm::current.support_threecolor_bitruncated() :
|
||||
#endif
|
||||
WARPED ? true :
|
||||
INVERSE ? false :
|
||||
(bt::in() || kite::in()) ? 0 :
|
||||
(S3 >= OINF) ? true :
|
||||
(valence() % 2 == 0);
|
||||
@ -1241,6 +1252,7 @@ EX int geosupport_threecolor() {
|
||||
if(arcm::in() && BITRUNCATED) return arcm::current.support_threecolor_bitruncated();
|
||||
if(arcm::in() && DUAL) return 0; // it sometimes does support threecolor, but it can be obtained in other ways then
|
||||
#endif
|
||||
if(INVERSE) return 0;
|
||||
if(BITRUNCATED && S3 == 3) {
|
||||
if(S7 % 2) return 1;
|
||||
return 2;
|
||||
@ -1256,6 +1268,7 @@ EX int geosupport_threecolor() {
|
||||
EX int geosupport_football() {
|
||||
// always works in bitrunc geometries
|
||||
if(BITRUNCATED) return 2;
|
||||
if(INVERSE) return 0;
|
||||
if(bt::in() || kite::in()) return 0;
|
||||
|
||||
#if CAP_ARCM
|
||||
@ -1431,6 +1444,7 @@ EX bool pseudohept(cell *c) {
|
||||
#endif
|
||||
if(arb::in()) return arb::pseudohept(c);
|
||||
#if CAP_GP
|
||||
if(INVERSE) return false;
|
||||
if(GOLDBERG && gp_threecolor() == 2)
|
||||
return gp::pseudohept_val(c) == 0;
|
||||
if(GOLDBERG && gp_threecolor() == 1 && (S7&1) && (S3 == 3))
|
||||
|
@ -167,6 +167,7 @@ struct hrmap_spherical : hrmap_standard {
|
||||
#endif
|
||||
swap(gmatrix, gmatrix0);
|
||||
just_gmatrix = true;
|
||||
dynamicval<cell*> cco(centerover, gamestart());
|
||||
draw();
|
||||
just_gmatrix = false;
|
||||
swap(gmatrix, gmatrix0);
|
||||
|
@ -968,6 +968,7 @@ EX void saveStats(bool emergency IS(false)) {
|
||||
if(dpgen::in) return;
|
||||
if(experimental) return;
|
||||
if(ginf[geometry].xcode == no_code) return;
|
||||
if(INVERSE) return;
|
||||
if(!gold()) return;
|
||||
|
||||
remove_emergency_save();
|
||||
|
Loading…
Reference in New Issue
Block a user