If I create a surface using the code below and evaluate points on the surface’s boundary curves, I expected that the points that are found on the surface are within zero tolerance to the point on the boundary curve. The output of the code below, however, paints a different picture, where deviations up to 0.23 are found.
The problem is quite sensitive to 1) the location of the initial points and 2) the choice of knot style. But, even so, for a relatively simple surface like the one in the example, I don’t expect such large deviations.
output:
large distance! 0.0185262564697653
large distance! 0.233779029389498
large distance! 0.23783011958997
large distance! 0.0503318751917803
protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
Point3dList nort = new Point3dList(
new Point3d( 0, 0, 0),
new Point3d( 1, 0, 0),
new Point3d( 2, 0, 0),
new Point3d( 3, 0, 0),
new Point3d(10, 0, 0)
);
Transform rotate90 = Transform.Rotation(Math.PI/2, new Point3d(5,5,0));
Point3dList west = new Point3dList(nort);
west.Transform(rotate90);
Point3dList sout = new Point3dList(west);
sout.Transform(rotate90);
Point3dList east = new Point3dList(sout);
east.Transform(rotate90);
NurbsCurve cnort = Curve.CreateInterpolatedCurve(nort, 3, CurveKnotStyle.Uniform).ToNurbsCurve();
NurbsCurve cwest = Curve.CreateInterpolatedCurve(west, 3, CurveKnotStyle.Uniform).ToNurbsCurve();
NurbsCurve csout = Curve.CreateInterpolatedCurve(sout, 3, CurveKnotStyle.Uniform).ToNurbsCurve();
NurbsCurve ceast = Curve.CreateInterpolatedCurve(east, 3, CurveKnotStyle.Uniform).ToNurbsCurve();
Brep b = Brep.CreateEdgeSurface(new[] {cnort, cwest, csout, ceast});
NurbsSurface s = b.Surfaces[0].ToNurbsSurface();
Test(s, cnort, doc);
Test(s, cwest, doc);
Test(s, csout, doc);
Test(s, ceast, doc);
doc.Objects.Add(b);
return Result.Success;
}
private void Test(NurbsSurface s, NurbsCurve curve, RhinoDoc doc)
{
foreach (double t in Range(curve.Domain, 100))
{
Point3d pt = curve.PointAt(t);
double u, v;
if (s.ClosestPoint(pt, out u, out v))
{
Point3d onSrf = s.PointAt(u, v);
if (onSrf.DistanceTo(pt) > RhinoMath.ZeroTolerance)
{
RhinoApp.WriteLine("large distance! "+onSrf.DistanceTo(pt).ToString("g"));
doc.Objects.AddLine(pt, onSrf);
}
}
}
}
private IEnumerable Range(Interval interval, int nSteps)
{
yield return interval.T0;
double step = interval.Length/nSteps;
for (int i = 0; i < nSteps - 1; ++i)
yield return interval.T0 + i*step;
yield return interval.T1;
}