mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-27 01:14:52 +00:00
full suppport for affine geometry in arb
This commit is contained in:
parent
a282c767ed
commit
88381b9eef
@ -12,6 +12,8 @@ namespace hr {
|
|||||||
|
|
||||||
EX namespace arb {
|
EX namespace arb {
|
||||||
|
|
||||||
|
EX int affine_limit = 200;
|
||||||
|
|
||||||
#if HDR
|
#if HDR
|
||||||
|
|
||||||
struct shape {
|
struct shape {
|
||||||
@ -24,6 +26,7 @@ struct shape {
|
|||||||
int size() const { return isize(vertices); }
|
int size() const { return isize(vertices); }
|
||||||
void build_from_angles_edges();
|
void build_from_angles_edges();
|
||||||
vector<pair<int, int> > sublines;
|
vector<pair<int, int> > sublines;
|
||||||
|
vector<pair<ld, ld>> stretch_shear;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct arbi_tiling {
|
struct arbi_tiling {
|
||||||
@ -169,6 +172,7 @@ EX void load_tile(exp_parser& ep, bool unit) {
|
|||||||
cc.connections.resize(cc.size());
|
cc.connections.resize(cc.size());
|
||||||
for(int i=0; i<isize(cc.connections); i++)
|
for(int i=0; i<isize(cc.connections); i++)
|
||||||
cc.connections[i] = make_tuple(cc.id, i, false);
|
cc.connections[i] = make_tuple(cc.id, i, false);
|
||||||
|
cc.stretch_shear.resize(cc.size(), make_pair(1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void load(const string& fname) {
|
EX void load(const string& fname) {
|
||||||
@ -217,10 +221,17 @@ EX void load(const string& fname) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(ep.eat("e2.")) {
|
else if(ep.eat("e2.")) {
|
||||||
|
ginf[gArbitrary].g = giEuclid2;
|
||||||
|
ginf[gArbitrary].sides = 7;
|
||||||
|
set_flag(ginf[gArbitrary].flags, qBOUNDED, false);
|
||||||
|
set_flag(ginf[gArbitrary].flags, qAFFINE, false);
|
||||||
|
}
|
||||||
|
else if(ep.eat("a2.")) {
|
||||||
ginf[gArbitrary].g = giEuclid2;
|
ginf[gArbitrary].g = giEuclid2;
|
||||||
ginf[gArbitrary].sides = 7;
|
ginf[gArbitrary].sides = 7;
|
||||||
set_flag(ginf[gArbitrary].flags, qBOUNDED, false);
|
set_flag(ginf[gArbitrary].flags, qBOUNDED, false);
|
||||||
set_flag(ginf[gArbitrary].flags, qAFFINE, true);
|
set_flag(ginf[gArbitrary].flags, qAFFINE, true);
|
||||||
|
affine_limit = 200;
|
||||||
}
|
}
|
||||||
else if(ep.eat("h2.")) {
|
else if(ep.eat("h2.")) {
|
||||||
ginf[gArbitrary].g = giHyperb2;
|
ginf[gArbitrary].g = giHyperb2;
|
||||||
@ -254,6 +265,10 @@ EX void load(const string& fname) {
|
|||||||
}
|
}
|
||||||
else if(ep.eat("unittile(")) load_tile(ep, true);
|
else if(ep.eat("unittile(")) load_tile(ep, true);
|
||||||
else if(ep.eat("tile(")) load_tile(ep, false);
|
else if(ep.eat("tile(")) load_tile(ep, false);
|
||||||
|
else if(ep.eat("affine_limit(")) {
|
||||||
|
affine_limit = ep.iparse();
|
||||||
|
ep.force_eat(")");
|
||||||
|
}
|
||||||
else if(ep.eat("conway(\"")) {
|
else if(ep.eat("conway(\"")) {
|
||||||
string s = "";
|
string s = "";
|
||||||
while(true) {
|
while(true) {
|
||||||
@ -318,8 +333,44 @@ EX void load(const string& fname) {
|
|||||||
ep.force_eat(")");
|
ep.force_eat(")");
|
||||||
throw connection_debug_request(i);
|
throw connection_debug_request(i);
|
||||||
}
|
}
|
||||||
|
else if(ep.eat("stretch_shear(")) {
|
||||||
|
ld stretch = ep.rparse(0);
|
||||||
|
ep.force_eat(",");
|
||||||
|
ld shear = ep.rparse(0);
|
||||||
|
ep.force_eat(",");
|
||||||
|
int i = ep.iparse(0);
|
||||||
|
verify_index(i, c.shapes, ep);
|
||||||
|
ep.force_eat(",");
|
||||||
|
int j = ep.iparse(0);
|
||||||
|
verify_index(j, c.shapes[i], ep);
|
||||||
|
ep.force_eat(")");
|
||||||
|
auto& sh = c.shapes[i];
|
||||||
|
sh.stretch_shear[j] = {stretch, shear};
|
||||||
|
auto& co = sh.connections[j];
|
||||||
|
int i2 = get<0>(co);
|
||||||
|
int j2 = get<1>(co);
|
||||||
|
auto& xsh = c.shapes[i2];
|
||||||
|
ld scale = sh.edges[j] / xsh.edges[j2];
|
||||||
|
println(hlog, "scale = ", scale);
|
||||||
|
xsh.stretch_shear[j2] = {1/stretch, shear * (get<2>(co) ? 1 : -1) * stretch };
|
||||||
|
}
|
||||||
else throw hr_parse_exception("expecting command, " + ep.where());
|
else throw hr_parse_exception("expecting command, " + ep.where());
|
||||||
}
|
}
|
||||||
|
if(!(cgflags & qAFFINE)) {
|
||||||
|
for(int i=0; i<isize(c.shapes); i++) {
|
||||||
|
auto& sh = c.shapes[i];
|
||||||
|
for(int j=0; j<isize(sh.edges); j++) {
|
||||||
|
ld d1 = hdist(sh.vertices[j], sh.vertices[j+1]);
|
||||||
|
auto con = sh.connections[j];
|
||||||
|
int i2 = get<0>(con);
|
||||||
|
int j2 = get<1>(con);
|
||||||
|
auto& xsh = c.shapes[get<0>(con)];
|
||||||
|
ld d2 = hdist(xsh.vertices[j2], xsh.vertices[j2+1]);
|
||||||
|
if(abs(d1 - d2) > 1e-6)
|
||||||
|
throw hr_parse_exception(lalign(0, "connecting ", make_pair(i,j), " to ", make_pair(i2,j2), " of different lengths only possible in a2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arbi_tiling debugged;
|
arbi_tiling debugged;
|
||||||
@ -384,7 +435,9 @@ void connection_debugger() {
|
|||||||
dialog::addSelItem(cap, "go", '0' + k);
|
dialog::addSelItem(cap, "go", '0' + k);
|
||||||
|
|
||||||
dialog::add_action([k, last, con] {
|
dialog::add_action([k, last, con] {
|
||||||
|
if(euclid) cgflags |= qAFFINE;
|
||||||
debug_polys.emplace_back(last.first * get_adj(debugged, last.second, k, -1), get<0>(con));
|
debug_polys.emplace_back(last.first * get_adj(debugged, last.second, k, -1), get<0>(con));
|
||||||
|
if(euclid) cgflags &= ~qAFFINE;
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -443,6 +496,11 @@ EX transmatrix get_adj(arbi_tiling& c, int t, int dl, int xdl) {
|
|||||||
ld sca = hdist(vl, vr) / hdist(xvl, xvr);
|
ld sca = hdist(vl, vr) / hdist(xvl, xvr);
|
||||||
transmatrix Tsca = Id;
|
transmatrix Tsca = Id;
|
||||||
Tsca[0][0] = Tsca[1][1] = sca;
|
Tsca[0][0] = Tsca[1][1] = sca;
|
||||||
|
|
||||||
|
auto& ss = sh.stretch_shear[dl];
|
||||||
|
Tsca[0][1] = ss.first * ss.second * sca;
|
||||||
|
Tsca[1][1] *= ss.first;
|
||||||
|
|
||||||
Res = Res * Tsca;
|
Res = Res * Tsca;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,8 +560,6 @@ struct hrmap_arbi : hrmap {
|
|||||||
celllister cl(origin->c7, 1000, 200, NULL);
|
celllister cl(origin->c7, 1000, 200, NULL);
|
||||||
ginf[geometry].distlimit[0] = cgi.base_distlimit = cl.dists.back();
|
ginf[geometry].distlimit[0] = cgi.base_distlimit = cl.dists.back();
|
||||||
if(sphere) cgi.base_distlimit = SEE_ALL;
|
if(sphere) cgi.base_distlimit = SEE_ALL;
|
||||||
|
|
||||||
if(cgflags & qAFFINE) cgi.base_distlimit = 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~hrmap_arbi() {
|
~hrmap_arbi() {
|
||||||
@ -551,7 +607,7 @@ struct hrmap_arbi : hrmap {
|
|||||||
|
|
||||||
transmatrix goal = adj(h, d);
|
transmatrix goal = adj(h, d);
|
||||||
|
|
||||||
for(int i=0; i<200 && i < isize(v); i++) {
|
for(int i=0; i<affine_limit && i < isize(v); i++) {
|
||||||
transmatrix T = v[i].second;
|
transmatrix T = v[i].second;
|
||||||
heptagon *h2 = v[i].first;
|
heptagon *h2 = v[i].first;
|
||||||
if(eqmatrix(T, goal)) {
|
if(eqmatrix(T, goal)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user