1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-23 21:07:17 +00:00

parser:: arcmcurv function

This commit is contained in:
Zeno Rogue 2022-04-24 20:53:08 +02:00
parent 920bf96088
commit f845523bcd

View File

@ -125,6 +125,8 @@ struct exp_parser {
char snext(int step=0) { skip_white(); return next(step); } char snext(int step=0) { skip_white(); return next(step); }
vector<pair<ld, ld>> parse_with_reps();
cld parse(int prio = 0); cld parse(int prio = 0);
ld rparse(int prio = 0) { return validate_real(parse(prio)); } ld rparse(int prio = 0) { return validate_real(parse(prio)); }
@ -171,6 +173,21 @@ string exp_parser::next_token() {
return token; return token;
} }
vector<pair<ld, ld>> exp_parser::parse_with_reps() {
vector<pair<ld, ld>> vals;
vals.emplace_back(rparse(0), 1);
while(true) {
skip_white();
if(eat(":^")) {
ld rep = rparse(0);
vals.back().second *= rep;
}
if(eat(",")) vals.emplace_back(rparse(0), 1);
else break;
}
return vals;
}
cld exp_parser::parse(int prio) { cld exp_parser::parse(int prio) {
cld res; cld res;
skip_white(); skip_white();
@ -240,24 +257,23 @@ cld exp_parser::parse(int prio) {
} }
#if CAP_ARCM #if CAP_ARCM
else if(eat("arcmedge(")) { else if(eat("arcmedge(")) {
if(!hyperbolic && !sphere) throw hr_parse_exception("arcmedge works only in hyperbolic and spherical geometry"); if(!hyperbolic && !sphere && !euclid) throw hr_parse_exception("arcmedge works only in isotropic geometry");
vector<pair<ld, ld>> vals; vector<pair<ld, ld>> vals = parse_with_reps();
vals.emplace_back(rparse(0), 1);
while(true) {
skip_white();
if(eat(":^")) {
ld rep = rparse(0);
vals.back().second *= rep;
}
if(eat(",")) vals.emplace_back(rparse(0), 1);
else break;
}
force_eat(")"); force_eat(")");
res = arcm::compute_edgelength(vals); res = euclid ? 1 : arcm::compute_edgelength(vals);
if(real(res) < 1e-10) throw hr_parse_exception("wrong geometry for this arcmedge"); if(real(res) < 1e-10) throw hr_parse_exception("wrong geometry for this arcmedge");
if (auto *distunit = hr::at_or_null(extra_params, "distunit")) if (auto *distunit = hr::at_or_null(extra_params, "distunit"))
res /= *distunit; res /= *distunit;
} }
else if(eat("arcmcurv(")) {
vector<pair<ld, ld>> vals = parse_with_reps();
force_eat(")");
ld total = 0;
for(auto p: vals) total += p.second * (180 - 360 / p.first);
total = (360 - total) * degree;
if(abs(total) < 1e-10) total = 0;
res = total;
}
#endif #endif
else if(eat("ideal_angle(")) { else if(eat("ideal_angle(")) {
ld edges = rparse(0); ld edges = rparse(0);