conical spirals and bands

This commit is contained in:
Zeno Rogue 2018-12-21 14:42:59 +01:00
parent e2b262979b
commit 3d76e90584
4 changed files with 95 additions and 7 deletions

View File

@ -391,6 +391,10 @@ namespace conformal {
int spiral_id = 7;
cld spiral_multiplier;
ld right_spiral_multiplier = 1;
ld spiral_cone = 360;
ld spiral_cone_rad;
bool ring_not_spiral;
void configure() {
ld ball = -vid.ballangle * degree;
@ -404,7 +408,15 @@ namespace conformal {
ld b = spiral_angle * degree;
ld cos_spiral = cos(b);
ld sin_spiral = sin(b);
spiral_multiplier = cld(cos_spiral, sin_spiral) * M_PI * cos_spiral;
spiral_cone_rad = spiral_cone * degree;
ring_not_spiral = abs(cos_spiral) < 1e-3;
if(ring_not_spiral) {
cos_spiral = 0;
sin_spiral = 1;
spiral_multiplier = cld(0, right_spiral_multiplier * spiral_cone_rad / 2);
}
else
spiral_multiplier = cld(cos_spiral, sin_spiral) * cld(spiral_cone_rad * cos_spiral / 2., 0);
}
if(euclid) {
hyperpoint h = tC0(eumove(spiral_x, spiral_y));
@ -756,7 +768,7 @@ namespace conformal {
});
}
if(pmodel == mdBall || pmodel == mdHyperboloid || pmodel == mdHemisphere) {
if(pmodel == mdBall || pmodel == mdHyperboloid || pmodel == mdHemisphere || (pmodel == mdSpiral && spiral_cone != 360)) {
dialog::addSelItem(XLAT("camera rotation in 3D models"), fts3(vid.ballangle), 'b');
dialog::add_action(config_camera_rotation);
}
@ -811,6 +823,18 @@ namespace conformal {
dialog::add_action([](){
dialog::editNumber(spiral_angle, 0, 360, 15, 0, XLAT("spiral angle"), "");
});
if(ring_not_spiral) {
dialog::addSelItem(XLAT("spiral multiplier"), fts(right_spiral_multiplier), 'M');
dialog::add_action([](){
dialog::editNumber(right_spiral_multiplier, 0, 10, -.1, 1, XLAT("spiral multiplier"), "");
});
}
dialog::addSelItem(XLAT("spiral cone"), fts(spiral_cone), 'C');
dialog::add_action([](){
dialog::editNumber(spiral_cone, 0, 360, -45, 360, XLAT("spiral cone"), "");
});
}
if(pmodel == mdSpiral && euclid) {
@ -1097,6 +1121,13 @@ namespace conformal {
else if(argis("-sang")) {
PHASEFROM(2);
shift_arg_formula(conformal::spiral_angle);
if(conformal::spiral_angle == 90) {
shift_arg_formula(conformal::right_spiral_multiplier);
}
}
else if(argis("-scone")) {
PHASEFROM(2);
shift_arg_formula(conformal::spiral_cone);
}
else if(argis("-sxy")) {
PHASEFROM(2);

View File

@ -1331,6 +1331,7 @@ namespace conformal {
extern ld model_transition;
extern ld top_z;
extern ld spiral_angle, spiral_x, spiral_y;
extern ld spiral_cone;
// screen coordinates to logical coordinates: apply_orientation(x,y)
// logical coordinates back to screen coordinates: apply_orientation(y,x)
@ -4620,6 +4621,8 @@ void show_color_dialog();
extern ld band_shift;
int cone_side(const hyperpoint H);
void fix_the_band(transmatrix& T);
struct bandfixer {

View File

@ -569,12 +569,26 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
if(hyperbolic) makeband(H, ret, band_conformal);
else ret = H;
z = cld(ret[0], ret[1]) * conformal::spiral_multiplier;
z = exp(z);
ret[0] = real(z);
ret[1] = imag(z);
if(conformal::spiral_cone < 360) {
ld alpha = imag(z) * 360 / conformal::spiral_cone;
ld r = real(z);
r = exp(r);
ret[0] = -sin(alpha) * r;
ret[1] = cos(alpha) * r;
ret[2] = (r-1) * sqrt( pow(360/conformal::spiral_cone, 2) - 1);
conformal::apply_ball(ret[2], ret[1]);
}
else {
z = exp(z);
ret[0] = real(z);
ret[1] = imag(z);
if(vid.skiprope)
ret = mobius(ret, vid.skiprope, 1);
if(vid.skiprope)
ret = mobius(ret, vid.skiprope, 1);
}
}
case mdGUARD: break;
@ -1502,6 +1516,14 @@ bool do_draw(cell *c, const transmatrix& T) {
ld iz = imag(z) + 1.14279e-2; // make it never fall exactly on PI
if(iz < -M_PI || iz >= M_PI) return false;
}
if(hyperbolic && pmodel == mdSpiral && conformal::ring_not_spiral) {
cld z;
hyperpoint H = tC0(T);
hyperpoint ret;
makeband(H, ret, band_conformal);
z = cld(ret[0], ret[1]) * conformal::spiral_multiplier;
if(imag(z) < -conformal::spiral_cone_rad/2-1e-5 || imag(z) >= conformal::spiral_cone_rad/2-1e-5) return false;
}
if(cells_drawn > vid.cells_drawn_limit) return false;
bool usr = vid.use_smart_range || quotient || euwrap;
if(usr && cells_drawn >= 50 && !in_smart_range(T)) return false;
@ -1509,4 +1531,32 @@ bool do_draw(cell *c, const transmatrix& T) {
return true;
}
int cone_side(const hyperpoint H) {
hyperpoint ret;
if(hyperbolic) makeband(H, ret, band_conformal);
else ret = H;
cld z = cld(ret[0], ret[1]) * conformal::spiral_multiplier;
auto zth = [&] (cld z) {
ld alpha = imag(z) * 360 / conformal::spiral_cone;
ld r = real(z);
r = exp(r);
hyperpoint ret;
ret[0] = -sin(alpha) * r;
ret[1] = cos(alpha) * r;
ret[2] = (r-1) * sqrt( pow(360/conformal::spiral_cone, 2) - 1);
conformal::apply_ball(ret[2], ret[1]);
return ret;
};
hyperpoint ret0 = zth(z);
hyperpoint ret1 = zth(z + cld(1e-3, 0));
hyperpoint ret2 = zth(z + cld(0, 1e-3));
return (ret1[1] - ret0[1]) * (ret2[0] - ret0[0]) < (ret2[1] - ret0[1]) * (ret1[0] - ret0[0]) ? 1 : -1;
}
}

View File

@ -198,6 +198,7 @@ bool two_sided_model() {
if(pmodel == mdDisk) return sphere;
if(pmodel == mdHemisphere) return true;
if(pmodel == mdRotatedHyperboles) return true;
if(pmodel == mdSpiral && conformal::spiral_cone < 360) return true;
return false;
}
@ -219,6 +220,9 @@ int get_side(const hyperpoint& H) {
applymodel(H, res);
return res[2] < 0 ? -1 : 1;
}
if(pmodel == mdSpiral && conformal::spiral_cone < 360) {
return cone_side(H);
}
return 0;
}