| 283 | |
| 284 | @mark.parametrize(("penalty", "lam"), [(3, 1e-9), (4, 1e-9), (5, 1e-9), (2, 0)]) |
| 285 | def test_periodic_approximate(penalty, lam): |
| 286 | |
| 287 | EPS = 1e-6 if lam == 0 else 1e-3 |
| 288 | |
| 289 | circ = circle(1) |
| 290 | pts_ = circ.sample(100)[0] |
| 291 | pts = np.array([list(p) for p in pts_]) |
| 292 | |
| 293 | crv = periodicApproximate(pts, lam=lam, penalty=penalty) |
| 294 | e = crv.edge() |
| 295 | |
| 296 | assert e.isValid() |
| 297 | assert e.Length() == approx(2 * np.pi, rel=EPS) |
| 298 | |
| 299 | # check params |
| 300 | us0 = circ.params(pts_) |
| 301 | us1 = e.params(pts_) |
| 302 | |
| 303 | # NB: I'm skipping the first and last point to not handle wrap around |
| 304 | assert np.allclose(us0[1:-1], np.array(us1)[1:-1] * 2 * np.pi, rtol=EPS) |
| 305 | # special case for wrap around |
| 306 | for ix in (0, -1): |
| 307 | delta = us0[ix] - np.array(us1[ix]) * 2 * np.pi |
| 308 | assert abs(delta) < EPS or abs(delta) - 2 * np.pi < EPS |
| 309 | |
| 310 | # multiple approximate |
| 311 | crvs = periodicApproximate([pts, pts]) |
| 312 | |
| 313 | for crv in crvs: |
| 314 | e = crv.edge() |
| 315 | |
| 316 | assert e.isValid() |
| 317 | assert e.Length() == approx(2 * np.pi, rel=EPS) |
| 318 | |
| 319 | |
| 320 | def test_periodic_loft(circles, trimmed_circles): |