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:
parent
920bf96088
commit
f845523bcd
42
util.cpp
42
util.cpp
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user