diff --git a/rogueviz/ru/classes.cpp b/rogueviz/ru/classes.cpp index edd2177e..b55d0ab0 100644 --- a/rogueviz/ru/classes.cpp +++ b/rogueviz/ru/classes.cpp @@ -484,6 +484,16 @@ struct pendulum_platform : public moving_platform { string get_help() override { return "These pendulum platforms go back and forth between two locations, taking the shortest path possible."; } }; +struct ellipse_platform : public moving_platform { + xy a, b; + ld ratio, period, shift; + vector points; + vector lengthsum; + xy location_at(ld t) override; + string get_name() override { return "ellipse platform"; } + string get_help() override { return "These platforms go in an ellipse."; } + }; + struct rope_platform : public moving_platform { ld period, shift, dist, max_swing; xy location_at(ld t) override; diff --git a/rogueviz/ru/entity.cpp b/rogueviz/ru/entity.cpp index 3e1f6488..a8c969cb 100644 --- a/rogueviz/ru/entity.cpp +++ b/rogueviz/ru/entity.cpp @@ -623,6 +623,36 @@ xy pendulum_platform::location_at(ld t) { return from_hyper(rgpushxto0(h1) * rspintox(gpushxto0(h1) * h2) * xpush0(x)); } +xy ellipse_platform::location_at(ld t) { + if(points.empty()) { + auto h1 = to_hyper(a); + auto h2 = to_hyper(b); + auto m = mid(h1, h2); + ld wanted = hdist(h1, h2) * ratio; + for(int it=0; it<360; it++) { + auto p = [&] (ld x) { return rgpushxto0(m) * spin(it*1._deg) * xpush0(x); }; + ld x = binsearch(0, 5, [&] (ld x) { auto px = p(x); return hdist(h1, px) + hdist(h2, px) >= wanted; }); + points.push_back(p(x)); + } + int N = isize(points); + points.push_back(points[0]); + ld ls = 0; + for(int i=0; ia = get_xy(); b->b = get_xy(); b->period = get_ld(); b->shift = get_ld(); r.entities.emplace_back(std::move(b)); } + else if(cap == "ELLIPSE") { + auto b = std::make_unique(); + b->a = get_xy(); b->b = get_xy(); b->period = get_ld(); b->shift = get_ld(); b->ratio = get_ld(); + r.entities.emplace_back(std::move(b)); + } else if(cap == "HINT") { auto b = std::make_unique(); b->respawn = get_xy(); b->size = get_xy();