379 {
382
383 auto& ctr = sl::contour(sh);
384 if(ctr.empty()) return {{0, 0}, 0};
385
386 auto bb = sl::boundingBox(sh);
387 auto capprx = bb.center();
388 auto rapprx = pl::distance(bb.minCorner(), bb.maxCorner());
389
390
391 opt::StopCriteria stopcr;
392 stopcr.max_iterations = 30;
393 stopcr.relative_score_difference = 1e-3;
394 opt::TOptimizer<opt::Method::L_SUBPLEX> solver(stopcr);
395
396 std::vector<double> dists(ctr.size(), 0);
397
398 auto result = solver.optimize_min(
399 [capprx, rapprx, &ctr, &dists](double xf, double yf) {
400 auto xt = Coord( std::round(getX(capprx) + rapprx*xf) );
401 auto yt = Coord( std::round(getY(capprx) + rapprx*yf) );
402
404
405 unsigned i = 0;
406 for(auto v : ctr) {
407 dists[i++] = pl::distance(v, centr);
408 }
409
410 auto mit = std::max_element(dists.begin(), dists.end());
411
412 assert(mit != dists.end());
413
414 return *mit;
415 },
416 opt::initvals(0.0, 0.0),
417 opt::bound(-1.0, 1.0), opt::bound(-1.0, 1.0)
418 );
419
420 double oxf = std::get<0>(result.optimum);
421 double oyf = std::get<1>(result.optimum);
422 auto xt =
Coord( std::round(
getX(capprx) + rapprx*oxf) );
423 auto yt =
Coord( std::round(
getY(capprx) + rapprx*oyf) );
424
426 auto r = result.score;
427
428 return {cc, r};
429}
TCoord< P > getX(const P &p)
Definition geometry_traits.hpp:424
typename PointType< remove_cvref_t< Shape > >::Type TPoint
TPoint<ShapeClass> as shorthand for typename PointType<ShapeClass>::Type.
Definition geometry_traits.hpp:46
typename CoordType< remove_cvref_t< GeomType > >::Type TCoord
TCoord<GeomType> as shorthand for typename CoordType<GeomType>::Type.
Definition geometry_traits.hpp:56
TCoord< PointImpl > Coord
Definition libnest2d.hpp:30
TCoord< P > getY(const P &p)
Definition geometry_traits.hpp:427
Kernel::Point_2 Point
Definition point_areas.cpp:20