Different curve points in openNurbs and Rhino

rhino
curve
opennurbs

#1

Hi,
i have noticed a difference in the evaluated curve points of a NURBS curve with a unclamped uniform knot vector.
The curve is defined by:

  • Control points: CP1(0, 1, 0), CP2(1, 1, 0) and CP3 (1, 0, 0)
  • Degree: 2
  • Knots (incl superfluous knots): 0, 0.2, 0.4, 0.6, 0.8 and 1

Code:

ON_NurbsCurve curve;    
curve.m_order = 3;
curve.m_is_rat = true;
curve.m_dim = 3;
curve.m_cv_stride = curve.m_dim + 1;
curve.m_cv_count = 3;
curve.ReserveCVCapacity(curve.m_cv_count * curve.m_cv_stride);
curve.ReserveKnotCapacity(4);

curve.SetCV(0, ON_4dPoint(0, 1, 0, 1));
curve.SetCV(1, ON_4dPoint(1, 1, 0, 1));
curve.SetCV(2, ON_4dPoint(1, 0, 0, 1));

curve.SetKnot(0, 0.2);
curve.SetKnot(1, 0.4);
curve.SetKnot(2, 0.6);
curve.SetKnot(3, 0.8);

When i evalutate the curve point with the openNurbs SDK at t = 0 I get :
C(t= 0) = P(-3.5, -1.0, 0), which I don’t want to.

auto point = curve.PointAt(0); // P(-3.5, -1.0, 0)

When i check the same curve with Rhino, i get the correct value:

ON::Begin();
auto fp = ON::OpenFile("clamped.3dm", "wb");
if (curve.IsValid()) {
    ON_BinaryFile archive(ON::write3dm, fp);
    ON_WriteOneObjectArchive(archive, 0, curve);
}
ON::CloseFile(fp);
ON::End();

Do I need to add some operations in the openNurbs SDK?

Thanks!


(Chuck Welsh) #2

The domain of your curve is [0.4, 0.6], not [0,1]. Opennurbs lets you evaluate a curve outside it’s domain, resulting in a point on the extended curve. My guess (I haven’t been able to check yet) is that within Rhino, your parameter is restricted to the curve’s domain. This would give you the start of the curve if you evaluated at 0, same as if you used 0.4. I’ll verify as soon as I can.


#3

Hi,
you’re right:

auto point = curve.PointAt(0.4); // P(0.5, 1, 0)

When I set the domain explicit I get the value i wanted.

curve.SetDomain(0, 1);
auto point = curve.PointAt(0); // P(0.5, 1, 0)

But why is the domain: [0.4, 0.6]?

Thanks for your help!


(Chuck Welsh) #4

For knot vector {k0, k1, k2, …} , the domain is always [k(degree-1), k(cvcount)]. This is true whether the knot vector is clamped or not. In the clamped case, the first and last knots correspond to these values. In general, they do not.