1324{
1325 const double r0 = std::max(lim0,
f.front().x()), r1 = std::min(lim1,
f.back().x());
1326 if (r1 <= r0)
1327 return;
1328 const size_t ia = std::upper_bound(
f.begin(),
f.end(), r0, [](
double x,
const Vec2d &p) { return x < p.x(); }) -
f.begin();
1329 const size_t ib = std::lower_bound(
f.begin() + ia,
f.end(), r1, [](
const Vec2d &p,
double x) { return p.x() < x; }) -
f.begin();
1330 auto interpolate = [](
const Vec2d &a,
const Vec2d &b,
double x) {
return b.x() > a.x() ? a.y() + (x - a.x()) / (b.x() - a.x()) * (b.y() - a.y()) : b.y(); };
1331 std::vector<Vec2d> local{
Vec2d(r0, interpolate(
f[ia - 1],
f[ia], r0)) };
1332 local.insert(local.end(),
f.begin() + ia,
f.begin() + ib);
1333 local.emplace_back(r1, interpolate(
f[ib - 1],
f[ib], r1));
1334
1335 const double tol = 1.;
1336 auto beyond = [&c, side, tol](
const Vec2d &p) {
return side * (c.x() * p.x() + c.y() - p.y()) - tol; };
1337 std::vector<std::pair<double, double>> stretches;
1338 auto add = [&stretches](double x0, double x1) {
1339 if (!stretches.empty() && stretches.back().second >= x0)
1340 stretches.back().second = x1;
1341 else
1342 stretches.emplace_back(x0, x1);
1343 };
1344 for (
size_t i = 1; i <
local.size(); ++i) {
1346 if (q.x() <= p.x())
1347 continue;
1348 const double bp = beyond(p), bq = beyond(q);
1349 if (bp > 0. && bq > 0.)
1351 else if (bp > 0. || bq > 0.) {
1352 const double x = p.x() + bp / (bp - bq) * (q.x() - p.x());
1353 if (bp > 0.)
1355 else
1357 }
1358 }
1359 std::vector<std::pair<double, double>> keep;
1360 for (auto [x0, x1] : stretches) {
1361 if (x1 < w0 || x0 > w1)
1362 continue;
1363 if (drop_past_limits && ((x0 <= r0 && r0 == lim0) || (x1 >= r1 && r1 == lim1)))
1364 continue;
1365 keep.emplace_back(cut_at_window ? std::max(x0, w0) : x0, cut_at_window ? std::min(x1, w1) : x1);
1366 }
1367 if (keep.empty())
1368 return;
1369
1370 auto y_local = [&](double x) {
1371 size_t i = 1;
1372 while (i + 1 <
local.size() && local[i].x() < x)
1373 ++i;
1375 };
1376 std::vector<Vec2d> out(
f.begin(),
f.begin() + ia);
1377 auto push = [&out, tol](double x, double y) {
1378 if (out.empty() || x > out.back().x() || std::abs(y - out.back().y()) > 2. * tol)
1379 out.emplace_back(x, y);
1380 };
1381 size_t k = 0;
1382 for (
const Vec2d &p : local) {
1383 for (; k < keep.size() && keep[k].second < p.x(); ++k) {
1384 const auto [x0, x1] = keep[k];
1385 push(x0, y_local(x0));
1386 push(x0, c.x() * x0 + c.y());
1387 push(x1, c.x() * x1 + c.y());
1388 push(x1, y_local(x1));
1389 }
1390 if (k < keep.size() && keep[k].first <= p.x() && p.x() <= keep[k].second)
1391 continue;
1392 push(p.x(), p.y());
1393 }
1394 for (; k < keep.size(); ++k) {
1395 const auto [x0, x1] = keep[k];
1396 push(x0, y_local(x0));
1397 push(x0, c.x() * x0 + c.y());
1398 push(x1, c.x() * x1 + c.y());
1399 push(x1, y_local(x1));
1400 }
1401 for (
size_t i = ib; i <
f.size(); ++i)
1402 push(
f[i].x(),
f[i].y());
1404}
SpiralVase::SpiralPoint add(SpiralVase::SpiralPoint a, SpiralVase::SpiralPoint b)
Definition SpiralVase.cpp:26
@ local
Definition Time.hpp:13
Point interpolate(const Point &a, const Point &b, double t)
Definition ExclusionVolumeTravelAvoidance.cpp:158
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124
Eigen::Matrix< double, 2, 1, Eigen::DontAlign > Vec2d
Definition Point.hpp:67