mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-22 23:17:04 +00:00
model orientation
This commit is contained in:
parent
04c41d38ed
commit
a9535878c4
@ -208,7 +208,8 @@ void initConfig() {
|
||||
addsaver(conformal::bandsegment, "band segment");
|
||||
addsaver(conformal::rotation, "conformal rotation");
|
||||
addsaver(conformal::do_rotate, "conformal rotation mode", 1);
|
||||
addsaver(conformal::lower_halfplane, "lower halfplane", false);
|
||||
addsaver(conformal::model_orientation, "model orientation", 0);
|
||||
addsaver(conformal::halfplane_scale, "halfplane scale", 1);
|
||||
addsaver(conformal::autoband, "automatic band");
|
||||
addsaver(conformal::autobandhistory, "automatic band history");
|
||||
addsaver(conformal::dospiral, "do spiral");
|
||||
@ -1486,6 +1487,11 @@ int read_config_args() {
|
||||
else if(argis("-PM")) {
|
||||
PHASEFROM(2); shift(); pmodel = eModel(argi());
|
||||
}
|
||||
else if(argis("-hp")) {
|
||||
PHASEFROM(2);
|
||||
shift(); conformal::model_orientation = argf();
|
||||
shift(); conformal::halfplane_scale = argf();
|
||||
}
|
||||
else if(argis("-zoom")) {
|
||||
PHASEFROM(2); shift(); vid.scale = argf();
|
||||
}
|
||||
|
@ -97,12 +97,18 @@ namespace polygonal {
|
||||
void drawBoundary(int color) {
|
||||
queuereset(mdDisk, PPR::CIRCLE);
|
||||
|
||||
ld C, S;
|
||||
auto& ho = conformal::model_orientation;
|
||||
if(ho == 0) C = 1, S = 0;
|
||||
else if(ho == 180) C = -1, S = 0;
|
||||
else C = cos(ho * M_PI/180), S = sin(ho * M_PI / 180);
|
||||
|
||||
for(int r=0; r<=2000; r++) {
|
||||
cld z = exp(cld(0, 2*M_PI * r / 2000.0));
|
||||
pair<xld,xld> z2 = compute(real(z), imag(z), deg);
|
||||
hyperpoint h;
|
||||
h[0] = z2.first * vid.radius;
|
||||
h[1] = z2.second * vid.radius;
|
||||
h[0] = (z2.first * C - z2.second * S) * vid.radius;
|
||||
h[1] = (z2.second * C + z2.first * S) * vid.radius;
|
||||
h[2] = stereo::scrdist;
|
||||
curvepoint(h);
|
||||
}
|
||||
@ -288,7 +294,10 @@ namespace conformal {
|
||||
int bandsegment = 16000;
|
||||
ld rotation = 0;
|
||||
int do_rotate = 1;
|
||||
bool lower_halfplane;
|
||||
ld model_orientation, halfplane_scale;
|
||||
ld ocos, osin;
|
||||
bool model_straight;
|
||||
|
||||
bool autoband = false;
|
||||
bool autobandhistory = false;
|
||||
bool dospiral = true;
|
||||
@ -401,6 +410,13 @@ namespace conformal {
|
||||
|
||||
movetophase();
|
||||
}
|
||||
|
||||
void configure() {
|
||||
ocos = cos(model_orientation * M_PI / 180);
|
||||
osin = sin(model_orientation * M_PI / 180);
|
||||
model_straight = (ocos > 1 - 1e-9);
|
||||
if(conformal::on) conformal::apply();
|
||||
}
|
||||
|
||||
ld measureLength() {
|
||||
ld r = bandhalf * vid.scale;
|
||||
@ -580,6 +596,11 @@ namespace conformal {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool model_has_orientation() {
|
||||
return
|
||||
among(pmodel, mdHalfplane, mdPolynomial, mdPolygonal, mdTwoPoint) || mdBandAny();
|
||||
}
|
||||
|
||||
void model_menu() {
|
||||
cmode = sm::SIDE | sm::MAYDARK | sm::CENTER;
|
||||
gamescreen(0);
|
||||
@ -608,6 +629,9 @@ namespace conformal {
|
||||
if(pmodel == mdDisk || pmodel == mdBall || pmodel == mdHyperboloid) {
|
||||
dialog::addSelItem(XLAT("Projection at the ground level"), fts3(vid.alpha), 'p');
|
||||
}
|
||||
|
||||
if(model_has_orientation())
|
||||
dialog::addSelItem(XLAT("model orientation"), fts(model_orientation), 'l');
|
||||
|
||||
if(pmodel == mdPolynomial) {
|
||||
dialog::addSelItem(XLAT("coefficient"),
|
||||
@ -617,8 +641,9 @@ namespace conformal {
|
||||
dialog::addSelItem(XLAT("which coefficient"), its(polygonal::coefid), 'n');
|
||||
}
|
||||
|
||||
if(pmodel == mdHalfplane)
|
||||
dialog::addBoolItem(XLAT("lower half-plane"), lower_halfplane, 'l');
|
||||
if(pmodel == mdHalfplane) {
|
||||
dialog::addSelItem(XLAT("half-plane scale"), fts(halfplane_scale), 'b');
|
||||
}
|
||||
|
||||
if(pmodel == mdBall)
|
||||
dialog::addSelItem(XLAT("projection in ball model"), fts3(vid.ballproj), 'x');
|
||||
@ -638,7 +663,7 @@ namespace conformal {
|
||||
}
|
||||
|
||||
if(pmodel == mdTwoPoint) {
|
||||
dialog::addSelItem(XLAT("parameter"), fts3(vid.twopoint_param), 'l');
|
||||
dialog::addSelItem(XLAT("parameter"), fts3(vid.twopoint_param), 'b');
|
||||
}
|
||||
|
||||
dialog::addSelItem(XLAT("vertical stretch"), fts3(vid.stretch), 's');
|
||||
@ -679,14 +704,14 @@ namespace conformal {
|
||||
editScale();
|
||||
else if(uni == 'p')
|
||||
projectionDialog();
|
||||
else if(uni == 'b')
|
||||
config_camera_rotation();
|
||||
#if CAP_RUG
|
||||
else if(uni == 'u')
|
||||
pushScreen(rug::show);
|
||||
#endif
|
||||
else if(uni == 'l' && pmodel == mdHalfplane)
|
||||
lower_halfplane = !lower_halfplane;
|
||||
else if(uni == 'l' && model_has_orientation())
|
||||
dialog::editNumber(model_orientation, 0, 360, 90, 0, XLAT("model orientation"), "");
|
||||
else if(uni == 'b' && pmodel == mdHalfplane)
|
||||
dialog::editNumber(model_orientation, 0, 2, 0.25, 1, XLAT("halfplane scale"), "");
|
||||
else if(uni == 's') {
|
||||
dialog::editNumber(vid.stretch, 0, 10, .1, 1, XLAT("vertical stretch"),
|
||||
"Vertical stretch factor."
|
||||
@ -720,7 +745,7 @@ namespace conformal {
|
||||
);
|
||||
dialog::scaleLog();
|
||||
}
|
||||
else if(uni == 'l' && pmodel == mdTwoPoint) {
|
||||
else if(uni == 'b' && pmodel == mdTwoPoint) {
|
||||
dialog::editNumber(vid.twopoint_param, 0, 10, .1, 1, XLAT("parameter"),
|
||||
"This model maps the world so that the distances from two points "
|
||||
"are kept. This parameter gives the distance from the two points to "
|
||||
@ -728,6 +753,8 @@ namespace conformal {
|
||||
);
|
||||
dialog::scaleLog();
|
||||
}
|
||||
else if(uni == 'b')
|
||||
config_camera_rotation();
|
||||
else if(uni == 'x' && pmodel == mdBall)
|
||||
dialog::editNumber(vid.ballproj, 0, 100, .1, 0, XLAT("projection in ball model"),
|
||||
"This parameter affects the ball model the same way as the projection parameter affects the disk model.");
|
||||
|
@ -485,9 +485,9 @@ void mainloopiter() {
|
||||
#endif
|
||||
|
||||
optimizeview();
|
||||
|
||||
if(conformal::on) conformal::apply();
|
||||
|
||||
conformal::configure();
|
||||
|
||||
ticks = SDL_GetTicks();
|
||||
callhooks(hooks_fixticks);
|
||||
|
||||
|
10
graph.cpp
10
graph.cpp
@ -5470,8 +5470,9 @@ void drawfullmap() {
|
||||
ptds.clear();
|
||||
|
||||
if(pmodel == mdTwoPoint) {
|
||||
queuechr(xpush0(+vid.twopoint_param), vid.xres / 100, 'X', 0xFF0000);
|
||||
queuechr(xpush0(-vid.twopoint_param), vid.xres / 100, 'X', 0xFF0000);
|
||||
ld a = -conformal::model_orientation * M_PI / 180;
|
||||
queuechr(xspinpush0(a, +vid.twopoint_param), vid.xres / 100, 'X', 0xFF0000);
|
||||
queuechr(xspinpush0(a, -vid.twopoint_param), vid.xres / 100, 'X', 0xFF0000);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5493,11 +5494,14 @@ void drawfullmap() {
|
||||
ld x = sin(a * vid.twopoint_param * b / 90);
|
||||
ld y = 0;
|
||||
ld z = -sqrt(1 - x*x);
|
||||
conformal::apply_orientation(y, x);
|
||||
hyperpoint h1;
|
||||
applymodel(hpxyz(x,y,z), h1);
|
||||
|
||||
conformal::apply_orientation(h1[0], h1[1]);
|
||||
h1[1] = abs(h1[1]) * b;
|
||||
curvepoint(h1 * vid.radius);
|
||||
conformal::apply_orientation(h1[1], h1[0]);
|
||||
curvepoint(h1);
|
||||
}
|
||||
|
||||
queuecurve(ringcolor, 0, PPR::CIRCLE);
|
||||
|
14
hyper.h
14
hyper.h
@ -1275,7 +1275,18 @@ namespace conformal {
|
||||
extern bool includeHistory;
|
||||
extern ld rotation;
|
||||
extern int do_rotate;
|
||||
extern bool lower_halfplane;
|
||||
extern ld model_orientation;
|
||||
extern ld halfplane_scale;
|
||||
extern ld ocos, osin;
|
||||
extern bool model_straight;
|
||||
|
||||
// screen coordinates to logical coordinates: apply_orientation(x,y)
|
||||
// logical coordinates back to screen coordinates: apply_orientation(y,x)
|
||||
template<class A>
|
||||
void apply_orientation(A& x, A& y) { if(!model_straight) tie(x,y) = make_pair(x*ocos + y*osin, y*ocos - x*osin); }
|
||||
|
||||
void configure();
|
||||
|
||||
extern bool autoband;
|
||||
extern bool autobandhistory;
|
||||
extern bool dospiral;
|
||||
@ -1299,6 +1310,7 @@ namespace conformal {
|
||||
|
||||
void progress_screen();
|
||||
void progress(string str);
|
||||
bool model_has_orientation();
|
||||
}
|
||||
|
||||
namespace polygonal {
|
||||
|
39
hypgraph.cpp
39
hypgraph.cpp
@ -268,7 +268,9 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
apply_depth(ret, y * zf / M_PI);
|
||||
}
|
||||
else {
|
||||
ld x, y, yf, zf;
|
||||
conformal::apply_orientation(H[0], H[1]);
|
||||
|
||||
ld x, y, yf, zf=0;
|
||||
y = asin_auto(H[1]);
|
||||
x = asin_auto_clamp(H[0] / cos_auto(y));
|
||||
if(sphere) {
|
||||
@ -331,9 +333,11 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
printf("unknown model\n");
|
||||
}
|
||||
}
|
||||
ret = hpxyz(x / M_PI, y * yf / M_PI, 0);
|
||||
ld yzf = y * zf; y *= yf;
|
||||
conformal::apply_orientation(y, x);
|
||||
ret = hpxyz(x / M_PI, y / M_PI, 0);
|
||||
if(zlev_used && stereo::active())
|
||||
apply_depth(ret, y * zf / M_PI);
|
||||
apply_depth(ret, yzf / M_PI);
|
||||
}
|
||||
ghcheck(ret, H);
|
||||
return;
|
||||
@ -365,7 +369,12 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
tz = H[2]+vid.alpha;
|
||||
|
||||
if(pmodel == mdPolygonal || pmodel == mdPolynomial) {
|
||||
|
||||
conformal::apply_orientation(H[0], H[1]);
|
||||
|
||||
pair<long double, long double> p = polygonal::compute(H[0]/tz, H[1]/tz);
|
||||
|
||||
conformal::apply_orientation(p.second, p.first);
|
||||
ret[0] = p.first;
|
||||
ret[1] = p.second;
|
||||
ret[2] = 0;
|
||||
@ -379,21 +388,25 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
ld x0, y0;
|
||||
x0 = H[0] / tz;
|
||||
y0 = H[1] / tz;
|
||||
if(conformal::lower_halfplane) x0 = -x0, y0 = -y0;
|
||||
|
||||
conformal::apply_orientation(x0, y0);
|
||||
|
||||
y0 += 1;
|
||||
double rad = x0*x0 + y0*y0;
|
||||
y0 /= rad;
|
||||
x0 /= rad;
|
||||
y0 -= .5;
|
||||
|
||||
if(conformal::lower_halfplane) x0 = -x0, y0 = -y0;
|
||||
y0 /= -rad;
|
||||
x0 /= -rad;
|
||||
y0 += .5;
|
||||
|
||||
ret[0] = x0;
|
||||
conformal::apply_orientation(y0, x0);
|
||||
|
||||
auto& ps = conformal::halfplane_scale;
|
||||
x0 *= ps, y0 *= ps;
|
||||
|
||||
ret[0] = -conformal::osin + x0;
|
||||
if(wmspatial || mmspatial) {
|
||||
if(conformal::lower_halfplane) y0 /= zlev;
|
||||
else y0 *= zlev;
|
||||
y0 = y0 * pow(zlev, conformal::ocos);
|
||||
}
|
||||
ret[1] = (conformal::lower_halfplane?-1:1) - y0;
|
||||
ret[1] = conformal::ocos + y0;
|
||||
ret[2] = 0;
|
||||
if(zlev != 1 && stereo::active())
|
||||
apply_depth(ret, -y0 * geom3::factor_to_lev(zlev));
|
||||
|
4
init.cpp
4
init.cpp
@ -300,8 +300,8 @@ void mobile_draw(MOBPAR_FORMAL) {
|
||||
|
||||
// if(debfile) fprintf(debfile, "d1\n"), fflush(debfile);
|
||||
frames++;
|
||||
if(conformal::on) conformal::apply();
|
||||
|
||||
conformal::configure();
|
||||
|
||||
if(ticks > lastt) tortoise::updateVals(ticks - lastt);
|
||||
|
||||
if(clicked && !lclicked) touchedAt = ticks;
|
||||
|
42
polygons.cpp
42
polygons.cpp
@ -584,14 +584,24 @@ void fixMercator(bool tinf) {
|
||||
else
|
||||
mercator_period = 2 * vid.radius;
|
||||
|
||||
if(!conformal::model_straight)
|
||||
for(auto& g: glcoords)
|
||||
conformal::apply_orientation(g[0], g[1]);
|
||||
|
||||
if(pmodel == mdSinusoidal)
|
||||
for(int i = 0; i<isize(glcoords); i++)
|
||||
glcoords[i][mercator_coord] /= cos(glcoords[i][1] / vid.radius / vid.stretch * M_PI);
|
||||
|
||||
|
||||
ld hperiod = mercator_period / 2;
|
||||
|
||||
|
||||
mercator_coord = 0;
|
||||
ld cmin = -vid.xcenter, cmax = vid.xres - vid.xcenter, dmin = -vid.ycenter, dmax = vid.yres - vid.ycenter;
|
||||
|
||||
auto dist = [] (ld a, ld b) { return max(b, a-b); };
|
||||
|
||||
ld chypot = hypot(dist(vid.xres, vid.xcenter), dist(vid.yres, vid.ycenter));
|
||||
|
||||
ld cmin = -chypot/2, cmax = chypot/2, dmin = -chypot, dmax = chypot;
|
||||
|
||||
if(mercator_coord)
|
||||
swap(cmin, dmin), swap(cmax, dmax);
|
||||
if(pmodel == mdSinusoidal)
|
||||
@ -638,6 +648,9 @@ void fixMercator(bool tinf) {
|
||||
if(pmodel == mdSinusoidal)
|
||||
for(int i = 0; i<isize(glcoords); i++)
|
||||
glcoords[i][mercator_coord] *= cos(glcoords[i][1] / vid.radius / vid.stretch * M_PI);
|
||||
if(!conformal::model_straight)
|
||||
for(auto& g: glcoords)
|
||||
conformal::apply_orientation(g[1], g[0]);
|
||||
}
|
||||
else {
|
||||
if(tinf) {
|
||||
@ -671,6 +684,9 @@ void fixMercator(bool tinf) {
|
||||
auto& v = glcoords[isize(glcoords)-u][1-mercator_coord];
|
||||
v = v < 0 ? dmin : dmax;
|
||||
}
|
||||
if(!conformal::model_straight)
|
||||
for(auto& g: glcoords)
|
||||
conformal::apply_orientation(g[1], g[0]);
|
||||
/* printf("cycling %d -> %d\n", base, qglcoords);
|
||||
for(int a=0; a<qglcoords; a++)
|
||||
printf("[%3d] %10.5lf %10.5lf\n", a, glcoords[a][0], glcoords[a][1]); */
|
||||
@ -761,10 +777,14 @@ void dqi_poly::draw() {
|
||||
// (which corresponds to the segment between the antipodes of foci)
|
||||
// if yes, switch cpha to the opposite
|
||||
hyperpoint h2 = V * glhr::gltopoint((*tab)[offset+(i+1)%cnt]);
|
||||
if(h1[1] * h2[1] > 0) continue;
|
||||
ld c1 = h1[1], c2 = -h2[1];
|
||||
|
||||
hyperpoint ah1 = h1, ah2 = h2;
|
||||
conformal::apply_orientation(ah1[0], ah1[1]);
|
||||
conformal::apply_orientation(ah2[0], ah2[1]);
|
||||
if(ah1[1] * ah2[1] > 0) continue;
|
||||
ld c1 = ah1[1], c2 = -ah2[1];
|
||||
if(c1 < 0) c1 = -c1, c2 = -c2;
|
||||
hyperpoint h = h1 * c1 + h2 * c2;
|
||||
hyperpoint h = ah1 * c1 + ah2 * c2;
|
||||
h /= hypot3(h);
|
||||
if(h[2] < 0 && abs(h[0]) < sin(vid.twopoint_param)) cpha = 1-cpha, pha = 2;
|
||||
}
|
||||
@ -936,9 +956,13 @@ void dqi_poly::draw() {
|
||||
|
||||
if(l || lastl) {
|
||||
for(int i=0; i<isize(glcoords); i++) {
|
||||
if(pmodel == mdSinusoidal)
|
||||
mercator_period = 2 * vid.radius * cos(glcoords[i][1] / vid.radius / vid.stretch * M_PI);
|
||||
glcoords[i][mercator_coord] += mercator_period * (l - lastl);
|
||||
if(pmodel == mdSinusoidal) {
|
||||
ld y = glcoords[i][1], x = glcoords[i][0];
|
||||
conformal::apply_orientation(x, y);
|
||||
mercator_period = 2 * vid.radius * cos(y / vid.radius / vid.stretch * M_PI);
|
||||
}
|
||||
glcoords[i][mercator_coord] += conformal::ocos * mercator_period * (l - lastl);
|
||||
glcoords[i][1-mercator_coord] += conformal::osin * mercator_period * (l - lastl);
|
||||
}
|
||||
lastl = l;
|
||||
}
|
||||
|
@ -421,6 +421,7 @@ vector<animatable_parameter> animatable_parameters = {
|
||||
animatable_parameter(vid.ballproj),
|
||||
animatable_parameter(surface::dini_b),
|
||||
animatable_parameter(surface::hyper_b),
|
||||
animatable_parameter(conformal::halfplane_scale),
|
||||
};
|
||||
|
||||
ld anim_param = 0;
|
||||
@ -507,8 +508,12 @@ void apply() {
|
||||
rug::apply_rotation(rug::currentrot * rotmatrix(rug_rotation2 * 2 * M_PI * t / period, 0, 1) * inverse(rug::currentrot));
|
||||
}
|
||||
}
|
||||
if(ballangle_rotation)
|
||||
vid.ballangle += ballangle_rotation * 360 * t / period;
|
||||
if(ballangle_rotation) {
|
||||
if(conformal::model_has_orientation())
|
||||
conformal::model_orientation += ballangle_rotation * 360 * t / period;
|
||||
else
|
||||
vid.ballangle += ballangle_rotation * 360 * t / period;
|
||||
}
|
||||
if(paramstate == 2 && anim_param) {
|
||||
ld phase = (1 + sin(anim_param * 2 * M_PI * ticks / period)) / 2;
|
||||
for(auto& ap: animatable_parameters) if(ap.values[0] != ap.values[1]) {
|
||||
@ -540,6 +545,10 @@ string animfile = "animation-%04d.png";
|
||||
bool record_animation() {
|
||||
for(int i=0; i<noframes; i++) {
|
||||
ticks = i * period / noframes;
|
||||
if(conformal::on) {
|
||||
conformal::phase = isize(conformal::v) * i * 1. / noframes;
|
||||
conformal::movetophase();
|
||||
}
|
||||
|
||||
char buf[1000];
|
||||
snprintf(buf, 1000, animfile.c_str(), i);
|
||||
@ -735,7 +744,9 @@ void show() {
|
||||
});
|
||||
}
|
||||
#endif
|
||||
if(among(pmodel, mdHyperboloid, mdHemisphere, mdBall))
|
||||
if(conformal::model_has_orientation())
|
||||
animator(XLAT("model rotation"), ballangle_rotation, 'r');
|
||||
else if(among(pmodel, mdHyperboloid, mdHemisphere, mdBall))
|
||||
animator(XLAT("3D rotation"), ballangle_rotation, 'r');
|
||||
|
||||
animator(XLAT("animate parameter change"), anim_param, 'P');
|
||||
|
Loading…
Reference in New Issue
Block a user