ON_NurbsCurve FittingCurve2d::initCPsNurbsCurve2D (int order, const vector_vec2d &cps) { int cp_red = order - 2; ON_NurbsCurve nurbs; if (cps.size () < 3 || cps.size () < (2 * cp_red + 1)) { printf ("[FittingCurve2d::initCPsNurbsCurve2D] Warning, number of control points too low.\n"); return nurbs; } int ncps = cps.size () + 2 * cp_red; // +2*cp_red for smoothness and +1 for closing nurbs = ON_NurbsCurve (2, false, order, ncps); nurbs.MakePeriodicUniformKnotVector (1.0 / (ncps - order + 1)); for (int j = 0; j < cps.size (); j++) nurbs.SetCV (cp_red + j, ON_3dPoint (cps[j] (0), cps[j] (1), 0.0)); // close nurbs nurbs.SetCV (cp_red + cps.size (), ON_3dPoint (cps[0] (0), cps[0] (1), 0.0)); // make smooth at closing point for (int j = 0; j < cp_red; j++) { ON_3dPoint cp; nurbs.GetCV (nurbs.CVCount () - 1 - cp_red + j, cp); nurbs.SetCV (j, cp); nurbs.GetCV (cp_red - j, cp); nurbs.SetCV (nurbs.CVCount () - 1 - j, cp); } return nurbs; }
ON_NurbsCurve FittingCurve2d::initCPsNurbsCurve2D (int order, const vector_vec2d &cps) { ON_NurbsCurve nurbs; if ((int)cps.size () < (2 * order)) { printf ("[FittingCurve2d::initCPsNurbsCurve2D] Warning, number of control points too low.\n"); return nurbs; } int cp_red = order - 2; int ncps = cps.size () + cp_red; nurbs = ON_NurbsCurve (2, false, order, ncps); nurbs.MakePeriodicUniformKnotVector (1.0 / (ncps - order + 1)); for (int j = 0; j < ncps; j++) nurbs.SetCV (j, ON_3dPoint (cps[j] (0), cps[j] (1), 0.0)); for (int j = 0; j < cp_red; j++) { ON_3dPoint cp; nurbs.GetCV (nurbs.m_cv_count - 1 - cp_red + j, cp); nurbs.SetCV (j, cp); nurbs.GetCV (cp_red - j, cp); nurbs.SetCV (nurbs.m_cv_count - 1 - j, cp); } return nurbs; }
ON_NurbsCurve FittingCurve2d::initNurbsCurve2D (int order, const vector_vec2d &data, int ncps, double radiusF) { if (data.empty ()) printf ("[FittingCurve2d::initNurbsCurve2D] Warning, no boundary parameters available\n"); Eigen::Vector2d mean = NurbsTools::computeMean (data); unsigned s = data.size (); double r (0.0); for (unsigned i = 0; i < s; i++) { Eigen::Vector2d d = data[i] - mean; double sn = d.squaredNorm (); if (sn > r) r = sn; } r = radiusF * sqrt (r); if (ncps < 2 * order) ncps = 2 * order; ON_NurbsCurve nurbs = ON_NurbsCurve (2, false, order, ncps); nurbs.MakePeriodicUniformKnotVector (1.0 / (ncps - order + 1)); double dcv = (2.0 * M_PI) / (ncps - order + 1); Eigen::Vector2d cv; for (int j = 0; j < ncps; j++) { cv (0) = r * sin (dcv * j); cv (1) = r * cos (dcv * j); cv = cv + mean; nurbs.SetCV (j, ON_3dPoint (cv (0), cv (1), 0.0)); } return nurbs; }
ON_NurbsCurve FittingCurve::initNurbsCurvePCA (int order, const vector_vec3d &data, int ncps, double rf) { if (data.empty ()) printf ("[FittingCurve::initNurbsCurvePCA] Warning, no boundary parameters available\n"); Eigen::Vector3d mean; Eigen::Matrix3d eigenvectors; Eigen::Vector3d eigenvalues; unsigned s = unsigned (data.size ()); NurbsTools::pca (data, mean, eigenvectors, eigenvalues); eigenvalues = eigenvalues / s; // seems that the eigenvalues are dependent on the number of points (???) double r = rf * sqrt (eigenvalues (0)); if (ncps < 2 * order) ncps = 2 * order; ON_NurbsCurve nurbs = ON_NurbsCurve (3, false, order, ncps); nurbs.MakePeriodicUniformKnotVector (1.0 / (ncps - order + 1)); double dcv = (2.0 * M_PI) / (ncps - order + 1); Eigen::Vector3d cv, cv_t; for (int j = 0; j < ncps; j++) { cv (0) = r * sin (dcv * j); cv (1) = r * cos (dcv * j); cv (2) = 0.0; cv_t = eigenvectors * cv + mean; nurbs.SetCV (j, ON_3dPoint (cv_t (0), cv_t (1), cv_t (2))); } return nurbs; }