more precise torus-rug rendering

This commit is contained in:
Zeno Rogue 2017-11-07 14:39:26 +01:00
parent b5382c5670
commit f5a8b2a0c2
5 changed files with 85 additions and 69 deletions

View File

@ -720,6 +720,66 @@ fpattern& getcurrfp() {
return fp43;
}
// extra information for field quotient extra configuration
struct primeinfo {
int p;
int cells;
bool squared;
};
struct fgeomextra {
eGeometry base;
vector<primeinfo> primes;
int current_prime_id;
fgeomextra(eGeometry b, int i) : base(b), current_prime_id(i) {}
};
vector<fgeomextra> fgeomextras = {
fgeomextra(gNormal, 3),
fgeomextra(gOctagon, 1),
fgeomextra(g45, 0),
fgeomextra(g46, 3),
fgeomextra(g47, 0)
};
int current_extra = 0;
void nextPrime(fgeomextra& ex) {
dynamicval<eGeometry> g(geometry, ex.base);
int nextprime;
if(size(ex.primes))
nextprime = ex.primes.back().p + 1;
else
nextprime = 2;
while(true) {
fieldpattern::fpattern fp(0);
fp.Prime = nextprime;
if(fp.solve() == 0) {
fp.build();
ex.primes.emplace_back(primeinfo{nextprime, size(fp.matrices) / S7, (bool) fp.wsquare});
break;
}
nextprime++;
}
}
void nextPrimes(fgeomextra& ex) {
while(size(ex.primes) < 4)
nextPrime(ex);
}
void enableFieldChange() {
fgeomextra& gxcur = fgeomextras[current_extra];
fieldpattern::quotient_field_changed = true;
nextPrimes(gxcur);
dynamicval<eGeometry> g(geometry, gQuotient2);
ginf[geometry].sides = ginf[gxcur.base].sides;
ginf[geometry].vertex = ginf[gxcur.base].vertex;
ginf[geometry].distlimit = ginf[gxcur.base].distlimit;
fieldpattern::current_quotient_field.init(gxcur.primes[gxcur.current_prime_id].p);
}
}
#define currfp fieldpattern::getcurrfp()
@ -727,3 +787,4 @@ fpattern& getcurrfp() {
int currfp_gmul(int a, int b) { return currfp.gmul(a,b); }
int currfp_inverses(int i) { return currfp.inverses[i]; }
int currfp_distwall(int i) { return currfp.distwall[i]; }

View File

@ -29,67 +29,8 @@ string euchelp =
int ewhichscreen = 2;
// extra information for field quotient extra configuration
struct primeinfo {
int p;
int cells;
bool squared;
};
struct fgeomextra {
eGeometry base;
vector<primeinfo> primes;
int current_prime_id;
fgeomextra(eGeometry b, int i) : base(b), current_prime_id(i) {}
};
vector<fgeomextra> fgeomextras = {
fgeomextra(gNormal, 3),
fgeomextra(gOctagon, 1),
fgeomextra(g45, 0),
fgeomextra(g46, 3),
fgeomextra(g47, 0)
};
int current_extra = 0;
void nextPrime(fgeomextra& ex) {
dynamicval<eGeometry> g(geometry, ex.base);
int nextprime;
if(size(ex.primes))
nextprime = ex.primes.back().p + 1;
else
nextprime = 2;
while(true) {
fieldpattern::fpattern fp(0);
fp.Prime = nextprime;
if(fp.solve() == 0) {
fp.build();
ex.primes.emplace_back(primeinfo{nextprime, size(fp.matrices) / S7, (bool) fp.wsquare});
break;
}
nextprime++;
}
}
void nextPrimes(fgeomextra& ex) {
while(size(ex.primes) < 4)
nextPrime(ex);
}
void enableFieldChange() {
fgeomextra& gxcur = fgeomextras[current_extra];
fieldpattern::quotient_field_changed = true;
nextPrimes(gxcur);
dynamicval<eGeometry> g(geometry, gQuotient2);
ginf[geometry].sides = ginf[gxcur.base].sides;
ginf[geometry].vertex = ginf[gxcur.base].vertex;
ginf[geometry].distlimit = ginf[gxcur.base].distlimit;
fieldpattern::current_quotient_field.init(gxcur.primes[gxcur.current_prime_id].p);
}
void showQuotientConfig() {
using namespace fieldpattern;
gamescreen(2);
dialog::init(XLAT("advanced configuration"));
fgeomextra& gxcur = fgeomextras[current_extra];

View File

@ -1243,7 +1243,7 @@ void fullcenter();
void movecost(cell* from, cell *to);
void checkmove();
transmatrix eumove(int x, int y);
transmatrix eumove(ld x, ld y);
transmatrix eumovedir(int d);
int reptilemax();

View File

@ -363,7 +363,7 @@ void drawrec(const heptspin& hs, int lev, hstate s, const transmatrix& V) {
int mindx=-7, mindy=-7, maxdx=7, maxdy=7;
transmatrix eumove(int x, int y) {
transmatrix eumove(ld x, ld y) {
transmatrix Mat = Id;
Mat[2][2] = 1;
Mat[0][2] += (x + y * .5) * eurad;

28
rug.cpp
View File

@ -34,6 +34,7 @@ GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers)
namespace rug {
double rugzoom = .3;
int torus_precision = 2;
// hypersian rug datatypes and globals
//-------------------------------------
@ -204,7 +205,7 @@ void buildTorusRug() {
transmatrix z2 = inverse(z1);
printf("h1 = %s\n", display(z2 * hyperpoint {22,1,0}));
auto addToruspoint = [&] (int x, int y) {
auto addToruspoint = [&] (ld x, ld y) {
auto r = addRugpoint(C0, 0);
hyperpoint onscreen;
applymodel(tC0(eumove(x, y)), onscreen);
@ -226,15 +227,21 @@ void buildTorusRug() {
r->valid = true;
return r;
};
int rugmax = min(torus_precision, 16);
ld rmd = rugmax;
for(int i=0; i<qty; i++) {
int x = tps[i].x, y = tps[i].y;
auto r00 = addToruspoint(x, y);
auto r10 = addToruspoint(x+1, y);
auto r01 = addToruspoint(x, y+1);
auto rn1 = addToruspoint(x-1, y+1);
addTriangle(r00, r10, r01);
addTriangle(r00, r01, rn1);
rugpoint *rugarr[32][32];
for(int yy=0; yy<=rugmax; yy++)
for(int xx=0; xx<=rugmax; xx++)
rugarr[yy][xx] = addToruspoint(x+(xx-yy)/rmd, y+yy/rmd);
for(int yy=0; yy<rugmax; yy++)
for(int xx=0; xx<rugmax; xx++)
addTriangle(rugarr[yy][xx], rugarr[yy+1][xx], rugarr[yy+1][xx+1]),
addTriangle(rugarr[yy][xx], rugarr[yy][xx+1], rugarr[yy+1][xx+1]);
}
double maxz = 0;
@ -824,6 +831,11 @@ void show() {
dialog::addBoolItem(XLAT("render the texture only once"), (renderonce), 'o');
dialog::addBoolItem(XLAT("render texture without OpenGL"), (rendernogl), 'g');
dialog::addSelItem(XLAT("texture size"), its(texturesize)+"x"+its(texturesize), 's');
if(torus) {
if(torus_precision < 1) torus_precision = 1;
if(torus_precision > 16) torus_precision = 16;
dialog::addSelItem(XLAT("precision"), its(torus_precision), 'p');
}
dialog::display();
keyhandler = [] (int sym, int uni) {
#if ISPANDORA
@ -850,6 +862,8 @@ void show() {
}
else if(uni == 'o')
renderonce = !renderonce;
else if(uni == 'p' && torus_precision)
dialog::editNumber(torus_precision, 0, 16, 1, 2, "precision", "precision");
#if !ISPANDORA
else if(uni == 'g')
rendernogl = !rendernogl;