mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-06-10 02:14:06 +00:00
fixed a bug which crashed spherical Archimedean tilings on Windows. Also more statistics on Archimedean tilings.
This commit is contained in:
parent
a1e532d5a0
commit
6c6dd85994
@ -66,6 +66,8 @@ struct archimedean_tiling {
|
|||||||
void regroup();
|
void regroup();
|
||||||
string world_size();
|
string world_size();
|
||||||
|
|
||||||
|
eGeometryClass get_class();
|
||||||
|
|
||||||
ld scale();
|
ld scale();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,6 +110,9 @@ void archimedean_tiling::make_match(int a, int i, int b, int j) {
|
|||||||
|
|
||||||
void archimedean_tiling::prepare() {
|
void archimedean_tiling::prepare() {
|
||||||
|
|
||||||
|
euclidean_angle_sum = 0;
|
||||||
|
for(int f: faces) euclidean_angle_sum += (f-2.) / f;
|
||||||
|
|
||||||
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));
|
errormsg = XLAT("currently no more than %1 edges", its(MAX_EDGE));
|
||||||
errors++;
|
errors++;
|
||||||
@ -252,9 +257,6 @@ void archimedean_tiling::prepare() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
regroup();
|
regroup();
|
||||||
|
|
||||||
euclidean_angle_sum = 0;
|
|
||||||
for(int f: faces) euclidean_angle_sum += (f-2.) / f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void archimedean_tiling::regroup() {
|
void archimedean_tiling::regroup() {
|
||||||
@ -299,12 +301,16 @@ void archimedean_tiling::regroup() {
|
|||||||
} )
|
} )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eGeometryClass archimedean_tiling::get_class() {
|
||||||
|
if(euclidean_angle_sum < 1.999999) return gcSphere;
|
||||||
|
else if(euclidean_angle_sum > 2.000001) return gcHyperbolic;
|
||||||
|
else return gcEuclid;
|
||||||
|
}
|
||||||
|
|
||||||
void archimedean_tiling::compute_geometry() {
|
void archimedean_tiling::compute_geometry() {
|
||||||
if(euclidean_angle_sum < 1.999999) ginf[gArchimedean].cclass = gcSphere;
|
ginf[gArchimedean].cclass = get_class();
|
||||||
else if(euclidean_angle_sum > 2.000001) ginf[gArchimedean].cclass = gcHyperbolic;
|
|
||||||
else ginf[gArchimedean].cclass = gcEuclid;
|
|
||||||
|
|
||||||
SDEBUG( printf("euclidean_angle_sum = %lf\n", double(euclidean_angle_sum)); )
|
SDEBUG( printf("euclidean_angle_sum = %f\n", float(euclidean_angle_sum)); )
|
||||||
|
|
||||||
dynamicval<eGeometry> dv(geometry, gArchimedean);
|
dynamicval<eGeometry> dv(geometry, gArchimedean);
|
||||||
|
|
||||||
@ -340,28 +346,34 @@ void archimedean_tiling::compute_geometry() {
|
|||||||
ld alpha_total = 0;
|
ld alpha_total = 0;
|
||||||
|
|
||||||
for(int i=0; i<N; i++) {
|
for(int i=0; i<N; i++) {
|
||||||
ld crmin = 0, crmax = sphere ? M_PI : 10;
|
ld crmin = 0, crmax = sphere ? M_PI/2 : 10;
|
||||||
|
ld el = 0;
|
||||||
for(int q=0; q<100; q++) {
|
for(int q=0; q<100; q++) {
|
||||||
circumradius[i] = (crmin + crmax) / 2;
|
circumradius[i] = (crmin + crmax) / 2;
|
||||||
hyperpoint p1 = xpush0(circumradius[i]);
|
hyperpoint p1 = xpush0(circumradius[i]);
|
||||||
hyperpoint p2 = spin(2 * M_PI / faces[i]) * p1;
|
hyperpoint p2 = spin(2 * M_PI / faces[i]) * p1;
|
||||||
inradius[i] = hdist0(mid(p1, p2));
|
inradius[i] = hdist0(mid(p1, p2));
|
||||||
if(hdist(p1, p2) > edgelength) crmax = circumradius[i];
|
el = hdist(p1, p2);
|
||||||
|
if(el > edgelength) crmax = circumradius[i];
|
||||||
else crmin = circumradius[i];
|
else crmin = circumradius[i];
|
||||||
}
|
}
|
||||||
|
if(el < edgelength - 1e-3) alpha_total += 100; // could not make an edge that long
|
||||||
hyperpoint h = xpush(edgelength/2) * xspinpush0(M_PI/2, inradius[i]);
|
hyperpoint h = xpush(edgelength/2) * xspinpush0(M_PI/2, inradius[i]);
|
||||||
alphas[i] = atan2(-h[1], h[0]);
|
ld a = atan2(-h[1], h[0]);
|
||||||
|
if(a < 0) a += 2 * M_PI;
|
||||||
|
alphas[i] = a;
|
||||||
|
// printf(" H = %s alp = %f\n", display(h), (float) atan2(-h[1], h[0]));
|
||||||
alpha_total += alphas[i];
|
alpha_total += alphas[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// printf("el = %lf alpha = %lf\n", double(edgelength), double(alpha_total));
|
// printf("el = %f alpha = %f\n", float(edgelength), float(alpha_total));
|
||||||
|
|
||||||
if(sphere ^ (alpha_total > M_PI)) elmin = edgelength;
|
if(sphere ^ (alpha_total > M_PI)) elmin = edgelength;
|
||||||
else elmax = edgelength;
|
else elmax = edgelength;
|
||||||
if(euclid) break;
|
if(euclid) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDEBUG( printf("computed edgelength = %lf\n", double(edgelength)); )
|
SDEBUG( printf("computed edgelength = %f\n", float(edgelength)); )
|
||||||
|
|
||||||
triangles.clear();
|
triangles.clear();
|
||||||
triangles.resize(2*N+2);
|
triangles.resize(2*N+2);
|
||||||
@ -384,7 +396,7 @@ void archimedean_tiling::compute_geometry() {
|
|||||||
|
|
||||||
SDEBUG( for(auto& ts: triangles) {
|
SDEBUG( for(auto& ts: triangles) {
|
||||||
printf("T");
|
printf("T");
|
||||||
for(auto& t: ts) printf(" %lf@%lf", double(t.first), double(t.second));
|
for(auto& t: ts) printf(" %f@%f", float(t.first), float(t.second));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
} )
|
} )
|
||||||
|
|
||||||
@ -1010,6 +1022,11 @@ void show() {
|
|||||||
|
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
dialog::addSelItem(XLAT("full angle"), fts(edited.euclidean_angle_sum * 180) + "°", 0);
|
dialog::addSelItem(XLAT("full angle"), fts(edited.euclidean_angle_sum * 180) + "°", 0);
|
||||||
|
dialog::addSelItem(XLAT("size of the world"), edited.world_size(), 0);
|
||||||
|
|
||||||
|
edited.compute_geometry();
|
||||||
|
dialog::addSelItem(XLAT("edge length"), fts(edited.edgelength) + (edited.get_class() == gcEuclid ? XLAT(" (arbitrary)") : ""), 0);
|
||||||
|
current.compute_geometry();
|
||||||
dialog::addBreak(100);
|
dialog::addBreak(100);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1048,6 +1065,9 @@ void show() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if(archimedean) {
|
if(archimedean) {
|
||||||
|
dialog::addSelItem(XLAT("size of the world"), current.world_size(), 0);
|
||||||
|
dialog::addSelItem(XLAT("edge length"), current.get_class() == gcEuclid ? (fts(current.edgelength) + XLAT(" (arbitrary)")) : fts6(current.edgelength), 0);
|
||||||
|
|
||||||
dialog::addItem(XLAT("color by symmetries"), 't');
|
dialog::addItem(XLAT("color by symmetries"), 't');
|
||||||
dialog::add_action([] () {
|
dialog::add_action([] () {
|
||||||
firstland = specialland = laCanvas;
|
firstland = specialland = laCanvas;
|
||||||
@ -1093,6 +1113,8 @@ void show() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string archimedean_tiling::world_size() {
|
string archimedean_tiling::world_size() {
|
||||||
|
if(get_class() == gcEuclid) return "∞";
|
||||||
|
|
||||||
int nom = 2 - N, denom = 2;
|
int nom = 2 - N, denom = 2;
|
||||||
for(int f: faces) {
|
for(int f: faces) {
|
||||||
int g = gcd(denom, f);
|
int g = gcd(denom, f);
|
||||||
@ -1110,11 +1132,13 @@ string archimedean_tiling::world_size() {
|
|||||||
anom /= g; adenom /= g;
|
anom /= g; adenom /= g;
|
||||||
if(adenom < 0) anom = -anom, adenom = -adenom;
|
if(adenom < 0) anom = -anom, adenom = -adenom;
|
||||||
string s;
|
string s;
|
||||||
if(anom < 0) s = "exp(∞)*", anom = -anom;
|
bool hyp = (anom < 0);
|
||||||
|
if(hyp) anom = -anom;
|
||||||
if(adenom > 1)
|
if(adenom > 1)
|
||||||
s += its(anom) + "/" + its(adenom);
|
s += its(anom) + "/" + its(adenom);
|
||||||
else
|
else
|
||||||
s += its(anom);
|
s += its(anom);
|
||||||
|
if(hyp) s += " exp(∞)";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,10 +355,9 @@ void showEuclideanMenu() {
|
|||||||
dialog::addSelItem(XLAT("quotient space"), XLAT(qstring), 0);
|
dialog::addSelItem(XLAT("quotient space"), XLAT(qstring), 0);
|
||||||
|
|
||||||
dialog::addSelItem(XLAT("size of the world"),
|
dialog::addSelItem(XLAT("size of the world"),
|
||||||
(archimedean && euclid) ? "∞" :
|
|
||||||
archimedean ? arcm::current.world_size() :
|
archimedean ? arcm::current.world_size() :
|
||||||
(archimedean && sphere) ? its(isize(currentmap->allcells())) :
|
(archimedean && sphere) ? its(isize(currentmap->allcells())) :
|
||||||
worldsize < 0 ? "exp(∞)*" + (nom%denom ? its(nom)+"/"+its(-denom) : its(-worldsize)):
|
worldsize < 0 ? (nom%denom ? its(nom)+"/"+its(-denom) : its(-worldsize)) + " exp(∞)":
|
||||||
worldsize == 0 ? "∞" :
|
worldsize == 0 ? "∞" :
|
||||||
its(worldsize),
|
its(worldsize),
|
||||||
'3');
|
'3');
|
||||||
|
1
util.cpp
1
util.cpp
@ -29,6 +29,7 @@ string its(int i) { char buf[64]; sprintf(buf, "%d", i); return buf; }
|
|||||||
string fts(float x) { char buf[64]; sprintf(buf, "%4.2f", x); return buf; }
|
string fts(float x) { char buf[64]; sprintf(buf, "%4.2f", x); return buf; }
|
||||||
string fts3(float x) { char buf[64]; sprintf(buf, "%5.3f", x); return buf; }
|
string fts3(float x) { char buf[64]; sprintf(buf, "%5.3f", x); return buf; }
|
||||||
string fts4(float x) { char buf[64]; sprintf(buf, "%6.4f", x); return buf; }
|
string fts4(float x) { char buf[64]; sprintf(buf, "%6.4f", x); return buf; }
|
||||||
|
string fts6(float x) { char buf[64]; sprintf(buf, "%8.6f", x); return buf; }
|
||||||
string ftsg(float x) { char buf[64]; sprintf(buf, "%4.2g", x); return buf; }
|
string ftsg(float x) { char buf[64]; sprintf(buf, "%4.2g", x); return buf; }
|
||||||
|
|
||||||
string ftssmart(ld x) {
|
string ftssmart(ld x) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user