Exemple #1
0
void
NurbsTools::pca (const vector_vec2d &data, Eigen::Vector2d &mean, Eigen::Matrix2d &eigenvectors,
                 Eigen::Vector2d &eigenvalues)
{
  if (data.empty ())
  {
    printf ("[NurbsTools::pca] Error, data is empty\n");
    abort ();
  }

  mean = computeMean (data);

  unsigned s = unsigned (data.size ());

  Eigen::MatrixXd Q (2, s);

  for (unsigned i = 0; i < s; i++)
    Q.col (i) << (data[i] - mean);

  Eigen::Matrix2d C = Q * Q.transpose ();

  Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> eigensolver (C);
  if (eigensolver.info () != Success)
  {
    printf ("[NurbsTools::pca] Can not find eigenvalues.\n");
    abort ();
  }

  for (int i = 0; i < 2; ++i)
  {
    eigenvalues (i) = eigensolver.eigenvalues () (1 - i);
    eigenvectors.col (i) = eigensolver.eigenvectors ().col (1 - i);
  }
}
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;
}
Exemple #3
0
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;
}
void
ClosingBoundary::sampleFromBoundary (ON_NurbsSurface *nurbs, vector_vec3d &point_list, vector_vec2d &param_list,
                                     unsigned samples)
{
  double ds = 1.0 / (samples - 1);

  double minU = nurbs->Knot (0, 0);
  double maxU = nurbs->Knot (0, nurbs->KnotCount (0) - 1);
  double minV = nurbs->Knot (1, 0);
  double maxV = nurbs->Knot (1, nurbs->KnotCount (1) - 1);

  Eigen::Vector2d params;
  Eigen::Vector3d point;

  double points[3];

  // WEST
  params (0) = minU;
  for (unsigned i = 0; i < samples; i++)
  {
    params (1) = minV + (maxV - minV) * ds * i;
    nurbs->Evaluate (params (0), params (1), 0, 3, points);
    point_list.push_back (Eigen::Vector3d (points[0], points[1], points[2]));
    param_list.push_back (params);
  }

  // EAST
  params (0) = maxU;
  for (unsigned i = 0; i < samples; i++)
  {
    params (1) = minV + (maxV - minV) * ds * i;
    nurbs->Evaluate (params (0), params (1), 0, 3, points);
    point_list.push_back (Eigen::Vector3d (points[0], points[1], points[2]));
    param_list.push_back (params);
  }

  // SOUTH
  params (1) = minV;
  for (unsigned i = 0; i < samples; i++)
  {
    params (0) = minU + (maxU - minU) * ds * i;
    nurbs->Evaluate (params (0), params (1), 0, 3, points);
    point_list.push_back (Eigen::Vector3d (points[0], points[1], points[2]));
    param_list.push_back (params);
  }

  // NORTH
  params (1) = maxV;
  for (unsigned i = 0; i < samples; i++)
  {
    params (0) = minU + (maxU - minU) * ds * i;
    nurbs->Evaluate (params (0), params (1), 0, 3, points);
    point_list.push_back (Eigen::Vector3d (points[0], points[1], points[2]));
    param_list.push_back (params);
  }
}
Exemple #5
0
unsigned
NurbsTools::getClosestPoint (const Eigen::Vector2d &p, const vector_vec2d &data)
{
  if (data.empty ())
    throw std::runtime_error ("[NurbsTools::getClosestPoint(2d)] Data empty.\n");

  size_t idx = 0;
  double dist2 (DBL_MAX);
  for (size_t i = 0; i < data.size (); i++)
  {
    double d2 = (data[i] - p).squaredNorm ();
    if (d2 < dist2)
    {
      idx = i;
      dist2 = d2;
    }
  }
  return idx;
}
Exemple #6
0
unsigned
NurbsTools::getClosestPoint (const ON_2dPoint &p, const vector_vec2d &data)
{
  if (data.empty ())
    throw std::runtime_error ("[NurbsTools::getClosestPoint(2d)] Data empty.\n");

  unsigned idx (0);
  double dist2 (DBL_MAX);
  for (unsigned i = 0; i < data.size (); i++)
  {
    ON_2dVector v = (data[i] - p);
    double d2 = ON_DotProduct(v, v);  // Was the squaredNorm in Eigen
    if (d2 < dist2)
    {
      idx = i;
      dist2 = d2;
    }
  }
  return idx;
}
Exemple #7
0
ON_2dVector
NurbsTools::computeMean (const vector_vec2d &data)
{
  ON_2dVector u (0.0, 0.0);

  unsigned s = data.size ();
  double ds = 1.0 / s;

  for (unsigned i = 0; i < s; i++)
    u += (data[i] * ds);

  return u;
}
Exemple #8
0
Eigen::Vector2d
NurbsTools::computeMean (const vector_vec2d &data)
{
  Eigen::Vector2d u (0.0, 0.0);

  size_t s = data.size ();
  double ds = 1.0 / double (s);

  for (size_t i = 0; i < s; i++)
    u += (data[i] * ds);

  return u;
}
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;
}
Exemple #10
0
unsigned
NurbsTools::getClosestPoint (const ON_2dPoint &p, const ON_2dVector &dir, const vector_vec2d &data,
			     unsigned &idxcp)
{
  if (data.empty ())
    throw std::runtime_error ("[NurbsTools::getClosestPoint(2d)] Data empty.\n");

  unsigned idx (0);
  idxcp = 0;
  double dist2 (0.0);
  double dist2cp (DBL_MAX);
  for (unsigned i = 0; i < data.size (); i++)
  {
    ON_2dVector v = (data[i] - p);
    double d2 = ON_DotProduct(v, v);

    if (d2 < dist2cp)
    {
      idxcp = i;
      dist2cp = d2;
    }

    if (NEAR_ZERO(d2, SMALL_FASTF))
      return i;

    v.Unitize();

    double d1 = ON_DotProduct(dir, v);
    if (d1 / d2 > dist2)
    {
      idx = i;
      dist2 = d1 / d2;
    }
  }
  return idx;
}
Exemple #11
0
unsigned
NurbsTools::getClosestPoint (const Eigen::Vector2d &p, const Eigen::Vector2d &dir, const vector_vec2d &data,
                             unsigned &idxcp)
{
  if (data.empty ())
    throw std::runtime_error ("[NurbsTools::getClosestPoint(2d)] Data empty.\n");

  size_t idx = 0;
  idxcp = 0;
  double dist2 (0.0);
  double dist2cp (DBL_MAX);
  for (size_t i = 0; i < data.size (); i++)
  {
    Eigen::Vector2d v = (data[i] - p);
    double d2 = v.squaredNorm ();

    if (d2 < dist2cp)
    {
      idxcp = i;
      dist2cp = d2;
    }

    if (d2 == 0.0)
      return i;

    v.normalize ();

    double d1 = dir.dot (v);
    if (d1 / d2 > dist2)
    {
      idx = i;
      dist2 = d1 / d2;
    }
  }
  return idx;
}
Exemple #12
0
Eigen::Vector2d
NurbsTools::computeVariance (const Eigen::Vector2d &mean, const vector_vec2d &data)
{
  Eigen::Vector2d var (0.0, 0.0);

  size_t s = data.size ();
  double ds = 1.0 / double (s);

  for (size_t i = 0; i < s; i++)
  {
    Eigen::Vector2d v = data[i] - mean;
    var += Eigen::Vector2d (v (0) * v (0) * ds, v (1) * v (1) * ds);
  }

  return var;
}