nurbsCurve: different behaviour between Rhino.NET and RhinoCommon

Hello Forum,

I’m porting my old code from Rhino.NET to RhinoCommon and I found an issue on nurbsCurve. My Rhino version is 5 SR8 by now.

Given the points:

p0(0,0,0)
p1(1,1,0)
p2(2,0,0)
p(1.5, 0.3, 0)

I need to draw the nurbs starting at p0 with tangent p0 -> p1, ending at p2 with tangent p2 -> p1 and passing through p.

I did my homework and I came up with this solution: a rational nurbs curve with degree and order = 3, 4 knots and 3 control points

The knots vector must be:

[0,0,1,1]

the control points must be:

[0,0,0]
[0.612372435695795,0.612372435695795,0]
[2,0,0]

and the weights vector must be:

[1, 0.612372435695795, 1]

My RhinoCommon implementation is:

NurbsCurve nc0 = new NurbsCurve(3, true, 3, 3);
nc0.Knots[0] = 0;
nc0.Knots[1] = 0;
nc0.Knots[2] = 1;
nc0.Knots[3] = 1;
bool p0OK = nc0.Points.SetPoint(0, 0, 0, 0, 1);
bool p1OK = nc0.Points.SetPoint(1, 0.612372435695795, 0.612372435695795, 0, 0.612372435695795);
bool p2OK = nc0.Points.SetPoint(2, 2, 0, 0, 1);

and my Rhino.NET implementation is:

OnNurbsCurve nc1 = new OnNurbsCurve(3, true, 3, 3);
nc1.SetKnot(0, 0);
nc1.SetKnot(1, 0);
nc1.SetKnot(2, 1);
nc1.SetKnot(3, 1);
On4dPoint p04d2 = new On4dPoint(0, 0, 0, 1);
On4dPoint p14d2 = new On4dPoint(0.612372435695795, 0.612372435695795, 0, 0.612372435695795);
On4dPoint p24d2 = new On4dPoint(2, 0, 0, 1);
bool p0OK2 = nc1.SetCV(0, p04d2);
bool p1OK2 = nc1.SetCV(1, p14d2);
bool p2OK2 = nc1.SetCV(2, p24d2);
bool w0OK2 = nc1.SetWeight(0, 1.0);
bool w2OK2 = nc1.SetWeight(2, 1.0);

The problem is that they don’t match. In the picture you can see the construction triangle, the Rhino.NET based green nurbs and the RhinoCommon based red nurbs.

The green curve properly passes through p and has the correct tangents, while the red one not only doesn’t pass through p but also has wrong right tangent.

Bizarre is also the fact that if I look at the properties of both curves from Rhino I get “elliptic arc”. Isn’t an ellispse a conic and then a second degree curve?

Thanks. L

Hi @lscandella,

In RhinoCommon for Rhino 5, 4-D points were not treated as homogeneous points. Rather, they were treated as 3-D Euclidean points and the weight is taken into account when setting the point.

This has changed in RhinoCommon for Rhino 6. Here, 4-D points are assumed homogeneous. And, there are a number of new, well documented NurbsCurvePointList.SetPoint methods to help you correctly set control point locations.

In Rhino 5, you can use the utility function, below, to compensate for this. However, you will want to modify your code, when porting to Rhino 6, to use the correct version of NurbsCurvePointList.SetPoint.

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  NurbsCurve nc0 = new NurbsCurve(3, true, 3, 3);
  nc0.Knots[0] = 0;
  nc0.Knots[1] = 0;
  nc0.Knots[2] = 1;
  nc0.Knots[3] = 1;
  nc0.Points.SetPoint(0, CreateHomogeneousPoint(0, 0, 0, 1));
  nc0.Points.SetPoint(1, CreateHomogeneousPoint(0.612372435695795, 0.612372435695795, 0, 0.612372435695795));
  nc0.Points.SetPoint(2, CreateHomogeneousPoint(2, 0, 0, 1));
  doc.Objects.AddCurve(nc0);
  doc.Views.Redraw();

  return Result.Success;
}

private Point4d CreateHomogeneousPoint(double x, double y, double z, double w)
{
  if (w == 0.0) w = 1.0;
  var pt = new Point4d
  {
    X = x / w,
    Y = y / w,
    Z = z / w,
    W = w
  };
  return pt;
}

Hope this helps.

– Dale

Dale,

perfect on Rhino 5! I’ll test it on Rhino 6 as soon as I can

Thanks! L