mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 09:50:34 +00:00
struct archimedean_tiling
This commit is contained in:
parent
4d31e5a544
commit
c54d4ec59d
285
archimedean.cpp
285
archimedean.cpp
@ -9,24 +9,56 @@ static const int sfLINE = 2;
|
||||
static const int sfCHESS = 4;
|
||||
static const int sfTHREE = 8;
|
||||
|
||||
// Marek-snub
|
||||
vector<int> faces = {3, 6, 6, 6};
|
||||
vector<int> adj = {1, 0, 2, 3};
|
||||
vector<bool> invert = {false, false, true, false};
|
||||
vector<int> nflags = {sfPH | sfLINE, 0, 0, 0};
|
||||
struct archimedean_tiling {
|
||||
|
||||
bool have_ph, have_line, have_symmetry, have_chessboard;
|
||||
string symbol;
|
||||
|
||||
vector<int> faces;
|
||||
vector<int> adj;
|
||||
vector<bool> invert;
|
||||
vector<int> nflags;
|
||||
|
||||
int repetition = 1;
|
||||
int N;
|
||||
bool have_ph, have_line, have_symmetry, have_chessboard;
|
||||
|
||||
ld euclidean_angle_sum;
|
||||
int repetition = 1;
|
||||
int N;
|
||||
|
||||
vector<int> flags;
|
||||
ld euclidean_angle_sum;
|
||||
|
||||
vector<vector<pair<int, int>>> adjacent;
|
||||
vector<int> flags;
|
||||
|
||||
vector<vector<pair<ld, ld>>> triangles;
|
||||
vector<vector<pair<int, int>>> adjacent;
|
||||
vector<vector<pair<ld, ld>>> triangles;
|
||||
|
||||
void make_match(int a, int i, int b, int j);
|
||||
void prepare();
|
||||
void compute_geometry();
|
||||
|
||||
void parse();
|
||||
void parse(string s) { symbol = s; parse(); }
|
||||
|
||||
ld edgelength;
|
||||
|
||||
vector<ld> inradius, circumradius, alphas;
|
||||
|
||||
int matches[30][30];
|
||||
int periods[30];
|
||||
int tilegroup[30], groupoffset[30], tilegroups;
|
||||
|
||||
int errors;
|
||||
string errormsg;
|
||||
|
||||
pair<int, int>& get_adj(heptagon *h, int cid);
|
||||
pair<ld, ld>& get_triangle(heptagon *h, int cid);
|
||||
pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta = 0);
|
||||
pair<int, int>& get_adj(const pair<int, int>& p, int delta = 0);
|
||||
|
||||
int support_threecolor();
|
||||
int support_graveyard();
|
||||
bool support_chessboard();
|
||||
};
|
||||
|
||||
archimedean_tiling current;
|
||||
|
||||
// id of vertex in the archimedean tiling
|
||||
// odd numbers = reflected tiles
|
||||
@ -46,28 +78,12 @@ short& parent_index_of(heptagon *h) {
|
||||
// total number of neighbors
|
||||
|
||||
int neighbors_of(heptagon *h) {
|
||||
return isize(triangles[id_of(h)]);
|
||||
return isize(current.triangles[id_of(h)]);
|
||||
}
|
||||
|
||||
ld edgelength;
|
||||
|
||||
vector<ld> inradius, circumradius, alphas;
|
||||
|
||||
int matches[30][30];
|
||||
int periods[30];
|
||||
int tilegroup[30], groupoffset[30], tilegroups;
|
||||
|
||||
int gcd(int x, int y) { return x ? gcd(y%x, x) : y < 0 ? -y : y; }
|
||||
|
||||
int errors;
|
||||
string errormsg;
|
||||
|
||||
pair<int, int>& get_adj(heptagon *h, int cid);
|
||||
pair<ld, ld>& get_triangle(heptagon *h, int cid);
|
||||
pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta = 0);
|
||||
pair<int, int>& get_adj(const pair<int, int>& p, int delta = 0);
|
||||
|
||||
void make_match(int a, int i, int b, int j) {
|
||||
void archimedean_tiling::make_match(int a, int i, int b, int j) {
|
||||
if(isize(adjacent[a]) != isize(adjacent[b])) {
|
||||
SDEBUG(printf("(error here)"));
|
||||
errormsg = XLAT("polygons match incorrectly");
|
||||
@ -79,9 +95,9 @@ void make_match(int a, int i, int b, int j) {
|
||||
periods[a] = periods[b] = gcd(matches[a][b] - (j-i), periods[a]);
|
||||
}
|
||||
|
||||
void prepare() {
|
||||
void archimedean_tiling::prepare() {
|
||||
|
||||
for(int i: faces) if(i >= MAX_EDGE) {
|
||||
for(int i: faces) if(i > MAX_EDGE) {
|
||||
errormsg = XLAT("currently no more than %1 edges", its(MAX_EDGE));
|
||||
errors++;
|
||||
return;
|
||||
@ -244,6 +260,9 @@ void prepare() {
|
||||
|
||||
euclidean_angle_sum = 0;
|
||||
for(int f: faces) euclidean_angle_sum += (f-2.) / f;
|
||||
}
|
||||
|
||||
void archimedean_tiling::compute_geometry() {
|
||||
if(euclidean_angle_sum < 1.999999) ginf[gArchimedean].cclass = gcSphere;
|
||||
else if(euclidean_angle_sum > 2.000001) ginf[gArchimedean].cclass = gcHyperbolic;
|
||||
else ginf[gArchimedean].cclass = gcEuclid;
|
||||
@ -287,7 +306,7 @@ void prepare() {
|
||||
SDEBUG( printf("computed edgelength = %lf\n", double(edgelength)); )
|
||||
|
||||
triangles.clear();
|
||||
triangles.resize(M);
|
||||
triangles.resize(2*N+2);
|
||||
for(int i=0; i<N; i++) for(int j=0; j<2; j++)
|
||||
for(int k=0; k<faces[i]; k++)
|
||||
triangles[2*i+j].emplace_back(2*M_PI/faces[i], circumradius[i]);
|
||||
@ -338,7 +357,7 @@ struct hrmap_archimedean : hrmap {
|
||||
|
||||
parent_index_of(origin) = 0;
|
||||
id_of(origin) = 0;
|
||||
origin->c7 = newCell(isize(adjacent[0]), origin);
|
||||
origin->c7 = newCell(isize(current.adjacent[0]), origin);
|
||||
|
||||
heptagon *alt = NULL;
|
||||
|
||||
@ -411,8 +430,8 @@ void connectHeptagons(heptagon *h, int i, heptspin hs) {
|
||||
}
|
||||
h->c.connect(i, hs);
|
||||
|
||||
auto p = get_adj(h, i);
|
||||
if(tilegroup[p.first] != tilegroup[id_of(hs.at)])
|
||||
auto p = current.get_adj(h, i);
|
||||
if(current.tilegroup[p.first] != current.tilegroup[id_of(hs.at)])
|
||||
printf("should merge %d %d\n", p.first, id_of(hs.at));
|
||||
// heptagon *hnew = build_child(h, d, get_adj(h, d).first, get_adj(h, d).second);
|
||||
}
|
||||
@ -421,7 +440,7 @@ void create_adjacent(heptagon *h, int d) {
|
||||
|
||||
SDEBUG( printf("%p.%d ~ ?\n", h, d); )
|
||||
|
||||
auto& t1 = get_triangle(h, d);
|
||||
auto& t1 = current.get_triangle(h, d);
|
||||
|
||||
// * spin(-tri[id][pi+i].first) * xpush(t.second) * pispin * spin(tri[id'][p'+d'].first)
|
||||
|
||||
@ -444,7 +463,7 @@ void create_adjacent(heptagon *h, int d) {
|
||||
for(auto& p: altmap[alt]) if(intval(p.second * C0, T * C0) < 1e-6) {
|
||||
SDEBUG( printf("cell found: %p\n", p.first); )
|
||||
for(int d2=0; d2<p.first->c7->type; d2++) {
|
||||
auto& t2 = get_triangle(p.first, d2);
|
||||
auto& t2 = current.get_triangle(p.first, d2);
|
||||
transmatrix T1 = T * spin(M_PI + t2.first);
|
||||
SDEBUG( printf("compare: %s", display(T1 * xpush0(1))); )
|
||||
SDEBUG( printf(":: %s\n", display(p.second * xpush0(1))); )
|
||||
@ -456,11 +475,11 @@ void create_adjacent(heptagon *h, int d) {
|
||||
SDEBUG( printf("but rotation not found\n"));
|
||||
}
|
||||
|
||||
auto& t2 = get_triangle(get_adj(h, d));
|
||||
auto& t2 = current.get_triangle(current.get_adj(h, d));
|
||||
transmatrix T1 = T * spin(M_PI + t2.first);
|
||||
fixmatrix(T1);
|
||||
|
||||
heptagon *hnew = build_child(h, d, get_adj(h, d).first, get_adj(h, d).second);
|
||||
heptagon *hnew = build_child(h, d, current.get_adj(h, d).first, current.get_adj(h, d).second);
|
||||
altmap[alt].emplace_back(hnew, T1);
|
||||
archimedean_gmatrix[hnew] = make_pair(alt, T1);
|
||||
}
|
||||
@ -474,29 +493,29 @@ void enqueue(heptagon *h, const transmatrix& T) {
|
||||
drawqueue.emplace(h, T);
|
||||
}
|
||||
|
||||
pair<ld, ld>& get_triangle(heptagon *h, int cid) {
|
||||
pair<ld, ld>& archimedean_tiling::get_triangle(heptagon *h, int cid) {
|
||||
return triangles[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
||||
}
|
||||
|
||||
pair<int, int>& get_adj(heptagon *h, int cid) {
|
||||
pair<int, int>& archimedean_tiling::get_adj(heptagon *h, int cid) {
|
||||
return adjacent[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
||||
}
|
||||
|
||||
pair<int, int>& get_adj(const pair<int, int>& p, int delta) {
|
||||
pair<int, int>& archimedean_tiling::get_adj(const pair<int, int>& p, int delta) {
|
||||
return adjacent[p.first][(p.second + delta + MODFIXER) % isize(adjacent[p.first])];
|
||||
}
|
||||
|
||||
pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta) {
|
||||
pair<ld, ld>& archimedean_tiling::get_triangle(const pair<int, int>& p, int delta) {
|
||||
return triangles[p.first][(p.second + delta + MODFIXER) % isize(adjacent[p.first])];
|
||||
}
|
||||
|
||||
transmatrix adjcell_matrix(heptagon *h, int d) {
|
||||
auto& t1 = get_triangle(h, d);
|
||||
auto& t1 = current.get_triangle(h, d);
|
||||
|
||||
heptagon *h2 = h->move(d);
|
||||
|
||||
int d2 = h->c.spin(d);
|
||||
auto& t2 = get_triangle(h2, d2);
|
||||
auto& t2 = current.get_triangle(h2, d2);
|
||||
|
||||
return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first);
|
||||
}
|
||||
@ -512,16 +531,16 @@ void draw() {
|
||||
heptagon *h = p.first;
|
||||
transmatrix V = p.second;
|
||||
int id = id_of(h);
|
||||
int S = isize(triangles[id]);
|
||||
int S = isize(current.triangles[id]);
|
||||
|
||||
if(!nonbitrunc || id < 2*N) {
|
||||
if(!nonbitrunc || id < 2*current.N) {
|
||||
if(!dodrawcell(h->c7)) continue;
|
||||
drawcell(h->c7, V, 0, false);
|
||||
}
|
||||
|
||||
for(int i=0; i<S; i++) {
|
||||
h->cmove(i);
|
||||
if(nonbitrunc && id >= 2*N && h->move(i) && id_of(h->move(i)) >= 2*N) continue;
|
||||
if(nonbitrunc && id >= 2*current.N && h->move(i) && id_of(h->move(i)) >= 2*current.N) continue;
|
||||
enqueue(h->move(i), V * adjcell_matrix(h, i));
|
||||
}
|
||||
idx++;
|
||||
@ -549,16 +568,16 @@ transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||
}
|
||||
|
||||
int fix(heptagon *h, int spin) {
|
||||
int type = isize(adjacent[id_of(h)]);
|
||||
int type = isize(current.adjacent[id_of(h)]);
|
||||
spin %= type;
|
||||
if(spin < 0) spin += type;
|
||||
return spin;
|
||||
}
|
||||
|
||||
void parse_symbol(string s) {
|
||||
void archimedean_tiling::parse() {
|
||||
int at = 0;
|
||||
|
||||
auto peek = [&] () { if(at == isize(s)) return char(0); else return s[at]; };
|
||||
auto peek = [&] () { if(at == isize(symbol)) return char(0); else return symbol[at]; };
|
||||
auto isnumber = [&] () { char p = peek(); return p >= '0' && p <= '9'; };
|
||||
auto read_number = [&] () { int result = 0; while(isnumber()) result = 10 * result + peek() - '0', at++; return result; };
|
||||
|
||||
@ -601,11 +620,18 @@ int readArgs() {
|
||||
|
||||
if(0) ;
|
||||
else if(argis("-symbol")) {
|
||||
targetgeometry = gArchimedean;
|
||||
if(targetgeometry != geometry)
|
||||
stop_game_and_switch_mode(rg::geometry);
|
||||
showstartmenu = false;
|
||||
shift(); parse_symbol(args());
|
||||
archimedean_tiling at;
|
||||
shift(); at.parse(args());
|
||||
if(at.errors) {
|
||||
printf("error: %s\n", at.errormsg.c_str());
|
||||
}
|
||||
else {
|
||||
targetgeometry = gArchimedean;
|
||||
if(targetgeometry != geometry)
|
||||
stop_game_and_switch_mode(rg::geometry);
|
||||
current = at;
|
||||
showstartmenu = false;
|
||||
}
|
||||
}
|
||||
else if(argis("-dgeom")) debug_geometry = true;
|
||||
else return 1;
|
||||
@ -618,7 +644,7 @@ auto hook =
|
||||
addHook(hooks_args, 100, readArgs);
|
||||
#endif
|
||||
|
||||
int support_threecolor() {
|
||||
int archimedean_tiling::support_threecolor() {
|
||||
if(nonbitrunc)
|
||||
return
|
||||
(isize(faces) == 3 && faces[0] % 2 == 0 && faces[1] % 2 == 0 && faces[2] % 2 == 0 && tilegroup[N*2] == 3) ? 2 :
|
||||
@ -628,36 +654,36 @@ int support_threecolor() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
int support_graveyard() {
|
||||
int archimedean_tiling::support_graveyard() {
|
||||
if(!nonbitrunc) return 2;
|
||||
return
|
||||
isize(arcm::faces) == 3 && arcm::faces[0] % 2 == 0 ? 2 :
|
||||
arcm::have_ph ? 1 :
|
||||
isize(faces) == 3 && faces[0] % 2 == 0 ? 2 :
|
||||
have_ph ? 1 :
|
||||
0;
|
||||
}
|
||||
|
||||
bool support_chessboard() {
|
||||
bool archimedean_tiling::support_chessboard() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool pseudohept(int id) {
|
||||
return flags[id] & arcm::sfPH;
|
||||
return current.flags[id] & arcm::sfPH;
|
||||
}
|
||||
|
||||
bool chessvalue(cell *c) {
|
||||
return flags[id_of(c->master)] & arcm::sfCHESS;
|
||||
return current.flags[id_of(c->master)] & arcm::sfCHESS;
|
||||
}
|
||||
|
||||
bool linespattern(cell *c) {
|
||||
return flags[id_of(c->master)] & arcm::sfLINE;
|
||||
return current.flags[id_of(c->master)] & arcm::sfLINE;
|
||||
}
|
||||
|
||||
int threecolor(int id) {
|
||||
if(nonbitrunc)
|
||||
return tilegroup[id];
|
||||
return current.tilegroup[id];
|
||||
else {
|
||||
if(support_threecolor() == 2) return id < N * 2 ? (id&1) : 2;
|
||||
return tilegroup[id];
|
||||
if(current.support_threecolor() == 2) return id < current.N * 2 ? (id&1) : 2;
|
||||
return current.tilegroup[id];
|
||||
}
|
||||
}
|
||||
|
||||
@ -729,87 +755,84 @@ vector<string> samples = {
|
||||
|
||||
int lastsample = 0;
|
||||
|
||||
struct prepared_sample {
|
||||
string s;
|
||||
ld angle_sum;
|
||||
int flags;
|
||||
};
|
||||
|
||||
|
||||
vector<prepared_sample> prepsamples;
|
||||
vector<archimedean_tiling> tilings;
|
||||
|
||||
int spos = 0;
|
||||
|
||||
string current_symbol;
|
||||
string active_symbol;
|
||||
int editpos = 0;
|
||||
|
||||
bool manual_edit;
|
||||
archimedean_tiling edited;
|
||||
|
||||
void enable() {
|
||||
bool symbol_editing;
|
||||
|
||||
void enable(archimedean_tiling& arct) {
|
||||
stop_game();
|
||||
if(geometry != gArchimedean) targetgeometry = gArchimedean, stop_game_and_switch_mode(rg::geometry);
|
||||
nonbitrunc = true; need_reset_geometry = true;
|
||||
parse_symbol(current_symbol);
|
||||
current = arct;
|
||||
start_game();
|
||||
}
|
||||
|
||||
void show() {
|
||||
if(lastsample < isize(samples) && geometry != gArchimedean) {
|
||||
if(lastsample < isize(samples)) {
|
||||
string s = samples[lastsample++];
|
||||
parse_symbol(s);
|
||||
if(errors) {
|
||||
printf("WARNING: %d errors on %s\n", errors, s.c_str());
|
||||
archimedean_tiling tested;
|
||||
tested.parse(s);
|
||||
if(tested.errors) {
|
||||
printf("WARNING: %d errors on %s '%s'\n", tested.errors, s.c_str(), tested.errormsg.c_str());
|
||||
}
|
||||
else {
|
||||
prepared_sample ps;
|
||||
ps.s = s;
|
||||
ps.flags = 0;
|
||||
ps.angle_sum = euclidean_angle_sum * 180;
|
||||
if(support_graveyard()) ps.flags |= sfPH;
|
||||
if(support_threecolor()) ps.flags |= sfTHREE;
|
||||
if(support_chessboard()) ps.flags |= sfCHESS;
|
||||
prepsamples.push_back(ps);
|
||||
tilings.push_back(move(tested));
|
||||
sort(tilings.begin(), tilings.end(), [] (archimedean_tiling& s1, archimedean_tiling& s2) {
|
||||
if(s1.euclidean_angle_sum < s2.euclidean_angle_sum - 1e-6) return true;
|
||||
if(s2.euclidean_angle_sum < s1.euclidean_angle_sum - 1e-6) return false;
|
||||
return s1.symbol < s2.symbol;
|
||||
});
|
||||
}
|
||||
}
|
||||
sort(prepsamples.begin(), prepsamples.end(), [] (prepared_sample& s1, prepared_sample& s2) {
|
||||
if(s1.angle_sum < s2.angle_sum - 1e-6) return true;
|
||||
if(s2.angle_sum < s1.angle_sum - 1e-6) return false;
|
||||
return s1.s < s2.s;
|
||||
});
|
||||
cmode = sm::SIDE | sm::MAYDARK;
|
||||
gamescreen(0);
|
||||
dialog::init(XLAT("Archimedean tilings"));
|
||||
if(current_symbol == "")
|
||||
|
||||
if(symbol_editing) {
|
||||
string cs = edited.symbol;
|
||||
if(editpos < 0) editpos = 0;
|
||||
if(editpos > isize(cs)) editpos = isize(cs);
|
||||
cs.insert(editpos, "°");
|
||||
dialog::addSelItem("edit", cs, '/');
|
||||
dialog::add_action([] () {
|
||||
symbol_editing = false;
|
||||
if(!edited.errors) enable(edited);
|
||||
});
|
||||
dialog::addBreak(100);
|
||||
if(edited.errors)
|
||||
dialog::addInfo(edited.errormsg, 0xFF0000);
|
||||
else
|
||||
dialog::addInfo(XLAT("OK"), 0x00FF00);
|
||||
dialog::addBreak(100);
|
||||
dialog::addSelItem(XLAT("full angle"), fts(edited.euclidean_angle_sum * 180) + "°", 0);
|
||||
dialog::addBreak(100);
|
||||
}
|
||||
else {
|
||||
string cs = archimedean ? current.symbol : XLAT("OFF");
|
||||
dialog::addSelItem("edit", cs, '/');
|
||||
dialog::add_action([] () {
|
||||
symbol_editing = true;
|
||||
edited = current;
|
||||
editpos = isize(current.symbol);
|
||||
edited.parse();
|
||||
});
|
||||
dialog::addBreak(100);
|
||||
else
|
||||
dialog::addSelItem("edit", current_symbol, '/');
|
||||
dialog::add_action([] () {
|
||||
manual_edit = !manual_edit;
|
||||
if(manual_edit) active_symbol = current_symbol;
|
||||
if(!manual_edit) {
|
||||
parse_symbol(current_symbol);
|
||||
if(errors) parse_symbol(current_symbol = active_symbol);
|
||||
else {
|
||||
parse_symbol(active_symbol);
|
||||
enable();
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog::addBreak(100);
|
||||
if(!manual_edit) {
|
||||
for(int i=0; i<10; i++) {
|
||||
int j = i + spos;
|
||||
if(j >= isize(prepsamples)) continue;
|
||||
auto &ps = prepsamples[j];
|
||||
dialog::addSelItem(ps.s, fts(ps.angle_sum) + "°", 'a' + i);
|
||||
dialog::add_action([&] () {
|
||||
current_symbol = ps.s;
|
||||
enable();
|
||||
});
|
||||
if(j >= isize(tilings)) continue;
|
||||
auto &ps = tilings[j];
|
||||
dialog::addSelItem(ps.symbol, fts(ps.euclidean_angle_sum * 180) + "°", 'a' + i);
|
||||
dialog::add_action([&] () { enable(ps); });
|
||||
}
|
||||
dialog::addItem(XLAT("next page"), '-');
|
||||
dialog::add_action([] () {
|
||||
if(spos + 10 >= isize(prepsamples))
|
||||
if(spos + 10 >= isize(tilings))
|
||||
spos = 0;
|
||||
else spos += 10;
|
||||
});
|
||||
@ -820,14 +843,20 @@ void show() {
|
||||
dialog::display();
|
||||
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
if(manual_edit && sym == SDLK_RETURN) sym = uni = '/';
|
||||
if(symbol_editing && sym == SDLK_RETURN) sym = uni = '/';
|
||||
if(sym == SDLK_LEFT) editpos--;
|
||||
if(sym == SDLK_RIGHT) editpos++;
|
||||
dialog::handleNavigation(sym, uni);
|
||||
if(manual_edit && uni == 8 && current_symbol != "") {
|
||||
current_symbol = current_symbol.substr(0, isize(current_symbol) - 1);
|
||||
if(symbol_editing && uni == 8 && editpos > 0) {
|
||||
edited.symbol.replace(editpos-1, 1, "");
|
||||
editpos--;
|
||||
edited.parse(edited.symbol);
|
||||
return;
|
||||
}
|
||||
if(manual_edit && uni >= 32 && uni < 128) {
|
||||
current_symbol += uni;
|
||||
if(symbol_editing && uni >= 32 && uni < 128) {
|
||||
edited.symbol.insert(editpos, 1, uni);
|
||||
editpos++;
|
||||
edited.parse(edited.symbol);
|
||||
return;
|
||||
}
|
||||
if(doexiton(sym, uni)) popScreen();
|
||||
|
2
cell.cpp
2
cell.cpp
@ -799,7 +799,7 @@ cell *createMov(cell *c, int d) {
|
||||
}
|
||||
}
|
||||
else if(nonbitrunc && archimedean) {
|
||||
if(arcm::id_of(c->master) <= arcm::N * 2) {
|
||||
if(arcm::id_of(c->master) <= arcm::current.N * 2) {
|
||||
heptspin hs = heptspin(c->master, d) + wstep + 2 + wstep + 1;
|
||||
c->c.connect(d, hs.at->c7, hs.spin, hs.mirrored);
|
||||
}
|
||||
|
@ -486,9 +486,10 @@ void generate_floorshapes() {
|
||||
cell model;
|
||||
model.master = &master;
|
||||
arcm::parent_index_of(&master) = 0;
|
||||
for(int i=0; i<2*arcm::N + (nonbitrunc ? 0 : 2); i++) {
|
||||
auto &ac = arcm::current;
|
||||
for(int i=0; i<2*ac.N + (nonbitrunc ? 0 : 2); i++) {
|
||||
arcm::id_of(&master) = i;
|
||||
model.type = isize(arcm::triangles[i]);
|
||||
model.type = isize(ac.triangles[i]);
|
||||
if(geosupport_graveyard() == 2)
|
||||
generate_floorshapes_for(i, &model, !arcm::pseudohept(i), i/2);
|
||||
else
|
||||
|
@ -164,7 +164,7 @@ void precalc() {
|
||||
|
||||
gp::compute_geometry();
|
||||
irr::compute_geometry();
|
||||
if(archimedean) arcm::prepare();
|
||||
if(archimedean) arcm::current.compute_geometry();
|
||||
}
|
||||
|
||||
transmatrix xspinpush(ld dir, ld dist) {
|
||||
|
@ -390,8 +390,9 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
|
||||
return mid_at_actual(vertices[cid], 3/cf);
|
||||
}
|
||||
if(archimedean) {
|
||||
if(arcm::id_of(c->master) >= arcm::N*2) return C0;
|
||||
auto& t = arcm::get_triangle(c->master, cid);
|
||||
auto &ac = arcm::current;
|
||||
if(arcm::id_of(c->master) >= ac.N*2) return C0;
|
||||
auto& t = ac.get_triangle(c->master, cid);
|
||||
return xspinpush0(-t.first, t.second * 3 / cf);
|
||||
}
|
||||
if(nonbitrunc) {
|
||||
@ -451,10 +452,11 @@ hyperpoint nearcorner(cell *c, int i) {
|
||||
return mid_at(C0, nc, .94);
|
||||
}
|
||||
if(archimedean) {
|
||||
auto& t = arcm::get_triangle(c->master, i);
|
||||
auto &ac = arcm::current;
|
||||
auto& t = ac.get_triangle(c->master, i);
|
||||
int id = arcm::id_of(c->master);
|
||||
int id1 = arcm::get_adj(arcm::get_adj(c->master, i), -2).first;
|
||||
return xspinpush0(-t.first - M_PI / c->type, arcm::inradius[id/2] + arcm::inradius[id1/2]);
|
||||
int id1 = ac.get_adj(ac.get_adj(c->master, i), -2).first;
|
||||
return xspinpush0(-t.first - M_PI / c->type, ac.inradius[id/2] + ac.inradius[id1/2]);
|
||||
}
|
||||
if(binarytiling) {
|
||||
ld yx = log(2) / 2;
|
||||
@ -504,11 +506,12 @@ hyperpoint farcorner(cell *c, int i, int which) {
|
||||
if(binarytiling)
|
||||
return nearcorner(c, (i+which) % c->type); // lazy
|
||||
if(archimedean) {
|
||||
auto& t = arcm::get_triangle(c->master, i);
|
||||
auto &ac = arcm::current;
|
||||
auto& t = ac.get_triangle(c->master, i);
|
||||
int id = arcm::id_of(c->master);
|
||||
auto id1 = arcm::get_adj(arcm::get_adj(c->master, i), -2).first;
|
||||
int n1 = isize(arcm::adjacent[id1]);
|
||||
return spin(-t.first - M_PI / c->type) * xpush(arcm::inradius[id/2] + arcm::inradius[id1/2]) * xspinpush0(M_PI + M_PI/n1*(which?3:-3), arcm::circumradius[id1/2]);
|
||||
auto id1 = ac.get_adj(ac.get_adj(c->master, i), -2).first;
|
||||
int n1 = isize(ac.adjacent[id1]);
|
||||
return spin(-t.first - M_PI / c->type) * xpush(ac.inradius[id/2] + ac.inradius[id1/2]) * xspinpush0(M_PI + M_PI/n1*(which?3:-3), ac.circumradius[id1/2]);
|
||||
}
|
||||
|
||||
return cellrelmatrix(c, i) * get_corner_position(c->move(i), (cellwalker(c, i) + wstep + (which?2:-1)).spin);
|
||||
|
@ -236,7 +236,7 @@ void drawLightning(const transmatrix& V) {
|
||||
|
||||
ld displayspin(cell *c, int d) {
|
||||
if(archimedean) {
|
||||
auto& t1 = arcm::get_triangle(c->master, d);
|
||||
auto& t1 = arcm::current.get_triangle(c->master, d);
|
||||
return -(t1.first + M_PI / c->type);
|
||||
}
|
||||
else if(irr::on) {
|
||||
|
@ -505,14 +505,14 @@ ld master_to_c7_angle() {
|
||||
transmatrix actualV(const heptspin& hs, const transmatrix& V) {
|
||||
if(irr::on)
|
||||
return V * spin(M_PI + 2 * M_PI / S7 * (hs.spin + irr::periodmap[hs.at].base.spin));
|
||||
if(archimedean) return V * spin(-arcm::triangles[arcm::id_of(hs.at)][hs.spin].first);
|
||||
if(archimedean) return V * spin(-arcm::current.triangles[arcm::id_of(hs.at)][hs.spin].first);
|
||||
if(binarytiling) return V;
|
||||
return (hs.spin || nonbitrunc) ? V * spin(hs.spin*2*M_PI/S7 + master_to_c7_angle()) : V;
|
||||
}
|
||||
|
||||
transmatrix applyspin(const heptspin& hs, const transmatrix& V) {
|
||||
if(binarytiling) return V;
|
||||
if(archimedean) return V * spin(arcm::triangles[arcm::id_of(hs.at)][hs.spin].first);
|
||||
if(archimedean) return V * spin(arcm::current.triangles[arcm::id_of(hs.at)][hs.spin].first);
|
||||
return hs.spin ? V * spin(hs.spin*2*M_PI/S7) : V;
|
||||
}
|
||||
|
||||
|
@ -480,7 +480,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
else
|
||||
v = 6;
|
||||
}
|
||||
else if(archimedean && arcm::have_line)
|
||||
else if(archimedean && arcm::current.have_line)
|
||||
v = arcm::linespattern(c) ? 24 : 16;
|
||||
else if(torus || hyperbolic_not37 || quotient || archimedean) {
|
||||
v = hrand(100) < 25 ? 24 : 16;
|
||||
@ -543,7 +543,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
case laZebra:
|
||||
if(d==8) {
|
||||
if(torus) ;
|
||||
else if(archimedean && arcm::have_line)
|
||||
else if(archimedean && arcm::current.have_line)
|
||||
c->wall = arcm::linespattern(c) ? waTrapdoor : waNone;
|
||||
else if(euclid && !archimedean) {
|
||||
int x,y;
|
||||
@ -565,7 +565,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
case laWineyard:
|
||||
if(d==8) {
|
||||
if(torus) ;
|
||||
else if(archimedean && arcm::have_line)
|
||||
else if(archimedean && arcm::current.have_line)
|
||||
c->wall = arcm::linespattern(c) ? waVinePlant : waNone;
|
||||
else if(euclid && !archimedean) {
|
||||
int x,y;
|
||||
|
29
pattern2.cpp
29
pattern2.cpp
@ -893,13 +893,20 @@ namespace patterns {
|
||||
return si;
|
||||
}
|
||||
|
||||
if(archimedean && pat == 0) {
|
||||
si.id = pseudohept(c); si.symmetries = 1;
|
||||
si.reflect = false; si.dir = 0;
|
||||
return si;
|
||||
}
|
||||
|
||||
if(archimedean && pat == PAT_SIBLING) {
|
||||
int id = arcm::id_of(c->master);
|
||||
si.id = arcm::tilegroup[id];
|
||||
si.symmetries = arcm::periods[si.id];
|
||||
si.dir = arcm::groupoffset[id];
|
||||
if((sub & SPF_EXTRASYM) && arcm::have_symmetry && arcm::tilegroup[id^1] < arcm::tilegroup[id])
|
||||
si.id = arcm::tilegroup[id^1],
|
||||
auto& ca = arcm::current;
|
||||
si.id = ca.tilegroup[id];
|
||||
si.symmetries = ca.periods[si.id];
|
||||
si.dir = ca.groupoffset[id];
|
||||
if((sub & SPF_EXTRASYM) && ca.have_symmetry && ca.tilegroup[id^1] < ca.tilegroup[id])
|
||||
si.id = ca.tilegroup[id^1],
|
||||
si.reflect = true;
|
||||
return si;
|
||||
}
|
||||
@ -1066,7 +1073,7 @@ int geosupport_threecolor() {
|
||||
return 2;
|
||||
if(a46 && nonbitrunc)
|
||||
return 1;
|
||||
if(archimedean) return arcm::support_threecolor();
|
||||
if(archimedean) return arcm::current.support_threecolor();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1074,7 +1081,7 @@ int geosupport_graveyard() {
|
||||
// always works in bitrunc geometries
|
||||
if(!nonbitrunc) return 2;
|
||||
|
||||
if(archimedean) return arcm::support_graveyard();
|
||||
if(archimedean) return arcm::current.support_graveyard();
|
||||
|
||||
if(irr::on) return irr::bitruncations_performed ? 2 : 1;
|
||||
|
||||
@ -1206,6 +1213,8 @@ bool kraken_pseudohept(cell *c) {
|
||||
return ishept(c);
|
||||
else if(irr::on)
|
||||
return c->type != 6;
|
||||
else if(archimedean)
|
||||
return c->type == isize(arcm::current.triangles[0]);
|
||||
else if(!euclid && S3 == 3 && !(S7&1) && gp_threecolor() == 1)
|
||||
return ishept(c);
|
||||
else
|
||||
@ -1234,7 +1243,7 @@ namespace patterns {
|
||||
|
||||
int generateCanvas(cell *c) {
|
||||
if(whichCanvas == 'A' && archimedean)
|
||||
return distcolors[arcm::tilegroup[arcm::id_of(c->master)] & 7];
|
||||
return distcolors[arcm::current.tilegroup[arcm::id_of(c->master)] & 7];
|
||||
if(whichCanvas == 'C' && hyperbolic) {
|
||||
using namespace fieldpattern;
|
||||
int z = currfp.getdist(fieldval(c), make_pair(0,false));
|
||||
@ -1481,7 +1490,7 @@ namespace patterns {
|
||||
if(stdhyperbolic || euclid)
|
||||
dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == PAT_PALACE), PAT_PALACE);
|
||||
|
||||
if((nonbitrunc && S3 == 4) || (archimedean && arcm::support_chessboard()))
|
||||
if((nonbitrunc && S3 == 4) || (archimedean && arcm::current.support_chessboard()))
|
||||
dialog::addBoolItem(XLAT("chessboard"), (whichPattern == PAT_CHESS), PAT_CHESS);
|
||||
|
||||
if(a38 || a46 || euclid || S3 == 4 || S7 == 4)
|
||||
@ -1539,7 +1548,7 @@ namespace patterns {
|
||||
if(euclid && among(whichPattern, PAT_COLORING, 0) && !archimedean)
|
||||
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
|
||||
|
||||
if(archimedean && arcm::have_symmetry && whichPattern == PAT_SIBLING)
|
||||
if(archimedean && arcm::current.have_symmetry && whichPattern == PAT_SIBLING)
|
||||
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
|
||||
|
||||
if(whichPattern == PAT_SINGLETYPE) {
|
||||
|
@ -1328,7 +1328,7 @@ transmatrix ddi(int a, ld x) { return xspinpush(a * M_PI / S42, x); }
|
||||
|
||||
void drawTentacle(hpcshape &h, ld rad, ld var, ld divby) {
|
||||
double tlength = max(crossf, hexhexdist * gp::scale * irr::scale);
|
||||
if(archimedean) tlength = arcm::edgelength;
|
||||
if(archimedean) tlength = arcm::current.edgelength;
|
||||
int max = int(20 * pow(2, vid.linequality));
|
||||
for(ld i=0; i<=max; i++)
|
||||
hpcpush(ddi(S21, rad + var * sin(i * M_PI/divby)) * ddi(0, tlength * i/max) * C0);
|
||||
@ -1632,11 +1632,10 @@ void buildpolys() {
|
||||
}
|
||||
|
||||
if(archimedean) {
|
||||
triangleside = arcm::edgelength;
|
||||
triangleside = xcrossf = arcm::current.edgelength;
|
||||
goldbf = 1;
|
||||
scalef = arcm::edgelength / hcrossf7;
|
||||
scalef = xcrossf / hcrossf7;
|
||||
floorrad0 = floorrad1 = triangleside * .45;
|
||||
xcrossf = arcm::edgelength;
|
||||
zhexf = xcrossf * .55;
|
||||
}
|
||||
|
||||
@ -1995,7 +1994,7 @@ void buildpolys() {
|
||||
if(a47 && !nonbitrunc) spzoom6 *= .85;
|
||||
|
||||
if(archimedean)
|
||||
shFullFloor.configure(arcm::edgelength/2, arcm::edgelength/2);
|
||||
shFullFloor.configure(arcm::current.edgelength/2, arcm::current.edgelength/2);
|
||||
else
|
||||
shFullFloor.configure(hexvdist, rhexf);
|
||||
shFloor.configure(floorrad0, floorrad1);
|
||||
|
Loading…
Reference in New Issue
Block a user