Issue with creating the correct curve from points

Hello!

I am currently facing an issue which I think might have to do with knots, but I am not sure.

In a nutshell I am trying to create a curve from the following code:

int degree = 3;
ON_NurbsCurve curve1(degree,true,degree+1,4);
for (std::size_t i=0; i<4; ++i)
{
    curve1.SetCV(i, ON_3dPoint(i, sin(i), 0.0));
    curve1.SetWeight(i, 1.0);
}
curve1.MakeClampedUniformKnotVector();

The above code creates a sin curve using 4 cv points. The output is correct, as shown below:
Capture1

The curve reaches x=3, which is expected.

However, when I increase the number of cv points, I get a weird result (see code below).

int degree = 3;
ON_NurbsCurve curve2(degree,true,degree+1,5);
for (std::size_t i=0; i<5; ++i)
{
    curve2.SetCV(i, ON_3dPoint(i, sin(i), 0.0));
    curve2.SetWeight(i, 1.0);
}
curve2.MakeClampedUniformKnotVector();

The result is incorrect because the curve stops at x=2 instead of x=4, as shown below:
Capture2

What am I missing in this example? What is the problem?

Hi @Constantinos_Glynos,

See below:

CRhinoCommand::result CCommandTest::RunCommand(
  const CRhinoCommandContext& context
)
{
  const int dimension = 3;
  const bool bIsRational = false;
  const int degree = 3;
  const int order = degree + 1;

  CRhinoGetInteger gn;
  gn.SetCommandPrompt(L"Number of points");
  gn.SetLowerLimit(order, FALSE);
  gn.GetInteger();
  if (gn.CommandResult() != CRhinoCommand::success)
    return gn.CommandResult();

  const int cv_count = gn.Number();
  if (cv_count < order)
    return CRhinoCommand::failure;

  ON_NurbsCurve nurb(dimension, bIsRational, order, cv_count);
  for (int i = 0; i < cv_count; i++)
    nurb.SetCV(i, ON_3dPoint((double)i, sin(i), 0.0));
  nurb.MakeClampedUniformKnotVector();

  if (nurb.IsValid())
  {
    context.m_doc.AddCurveObject(nurb);
    context.m_doc.Redraw();
  }

  return CRhinoCommand::success;
}

– Dale

Thank you very much for your reply!

Other than the Rhino stuff, which shouldn’t affect the NURBS curve, I am not sure what the difference is here? The following part from your code example matches to the one I have in OP and the variables you have used to initialize the nurb object are the same as I have used. What’s the difference?

ON_NurbsCurve nurb(dimension, bIsRational, order, cv_count);
for (int i = 0; i < cv_count; i++)
  nurb.SetCV(i, ON_3dPoint((double)i, sin(i), 0.0));
nurb.MakeClampedUniformKnotVector();

I tried your code and evaluated the NURBS curve at t=0.0, t=0.25, t=0.5, t=0.75, and t=1.0. I would expect that t=1.0 means the end point of the NURBS curve. But this is not the case. The results I got are:

t = 0, result = [0,0,0]
t = 0.25, result = [0.664062,0.489039,0]
t = 0.5, result = [1.1875,0.731358,0]
t = 0.75, result = [1.61719,0.783072,0]
t = 1.0, result = [2,0.700296,0]

Can you please advise?

Hi @Constantinos_Glynos,

Your code was creating a rational NURBS curve. My sample code creates a non-rational NURBS curve.

Your assuming the NURBS curve’s domain is normalized. Best to verify using ON_NurbsCurve::Domain.

– Dale

The key to this was the Domain(). Indeed, the domain was not normalized. Now I am getting the correct results. Thank you for your answer!