parser:: arcmcurv function

This commit is contained in:
Zeno Rogue 2022-04-24 20:53:08 +02:00
parent 920bf96088
commit f845523bcd
1 changed files with 29 additions and 13 deletions

View File

@ -125,6 +125,8 @@ struct exp_parser {
char snext(int step=0) { skip_white(); return next(step); }
vector<pair<ld, ld>> parse_with_reps();
cld parse(int prio = 0);
ld rparse(int prio = 0) { return validate_real(parse(prio)); }
@ -171,6 +173,21 @@ string exp_parser::next_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 res;
skip_white();
@ -240,24 +257,23 @@ cld exp_parser::parse(int prio) {
}
#if CAP_ARCM
else if(eat("arcmedge(")) {
if(!hyperbolic && !sphere) throw hr_parse_exception("arcmedge works only in hyperbolic and spherical geometry");
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;
}
if(!hyperbolic && !sphere && !euclid) throw hr_parse_exception("arcmedge works only in isotropic geometry");
vector<pair<ld, ld>> vals = parse_with_reps();
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 (auto *distunit = hr::at_or_null(extra_params, "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
else if(eat("ideal_angle(")) {
ld edges = rparse(0);