Offset a curve with respect to some vector

I’m trying to offset a curve relative to some vector. I am expecting a result curve such that when viewed down on the curve from the vector, each point on the curve is the offset distance away from the input curve. But with both attempts shown in the code below, I get a curve equivalent to offsetting the input curve relative to the world z-axis. Is this a bug?

Vector3d v = new Vector3d(0.5, 0, 0.5);
v.Unitize();

curve.Offset(new Plane(Point3d.Origin, v), 0.25, 0.002, CurveOffsetCornerStyle.Round);

Point3d guidePt = curve.PointAtStart + Vector3d.CrossProduct(curve.TangentAtStart, v);
curve.Offset(guidePt, v, 0.25, 0.002, CurveOffsetCornerStyle.Round);

edit – some curves offset as expected. arcs do not

Hi @jakemurphy0118,

Does the Offset command do what you want?

– Dale

Sometimes. I am writing code to drive a CNC tool along a curve. I imagined that Curve.Offset with reference to a normal vector or plane would offset the curve such that a tool at any point on the result curve, oriented with the normal vector, would just touch the original curve. In other words, if both curves were projected onto the ‘offset plane’, they would be no more than offset distance away from each other.

I ran a test by offsetting some different curves relative to a vector (0.5, 0, 0.5) and compared them with to the same curves offset relative to (0,0,1). Some do not offset correctly relative to (0.5, 0, 0.5), they are identical to curves offset if you use (0,0,1) as a normal. Attached is the file showing this. Black curves are input. Red curves are offset using RhinoCommon’s Curve.Offset with (0.5, 0, 0.5) as normal. Blue curves are offset using the ‘Offset’ command in Rhino based on the World Top CPlane.
OffsetDemo.3dm (54.6 KB)
I guess I’m wondering if this is really the intended behavior and if so is there a way to pre-process the curves such that they will offset as described. Or maybe I’m making a mistake. Thanks in advance.

Hi @jakemurphy0118,

I’m not sure I fully understand. But, extruding the input curve along the vector, offsetting the surface, and then intersecting the results with an oriented plane at the offset distance should give you want you want, right?

– Dale

No, let me attempt to describe the behavior I need from offsetting a curve relative to a vector by and offset distance:

each point p on a continuous, differentiable curve gets mapped to a point
p_offset = p + offsetDistance * (±)(tangentAtP cross offsetVector)

The tricky areas to deal with are at kinks or more generally where the radius of curvature is smaller than the offset distance since the output will be self-intersecting if projected onto the offset plane. The desired output would handle these situations similar to the 2D case where kinks are dealt with by extending the offset sections and trimming their intersections and where it seems like high curvature regions are handled properly.

What I find incorrect about the Curve.Offset method as it works now is that when I offset a closed planar curve relative to some vector that is not parallel with the world z-axis vector, it produces the same output as if I used the world z-axis. But if the curve is non-planar, the output is different.

Its as if the method I described above is being used for non-planar curves and line curves (minus handling kinks and high curvature) but in the case where the input curve is planar but not a line curve, it is offset using the normal of the plane the curve lies in.

Are you really just trying to Translate the curve by the vector? (edit - never mind. I obviously didn’t see most of the thread from my phone)

Well I haven’t figured out anything that works for all curves but this is the idea I was going for. I don’t really understand why this isn’t the result from Curve.Offset relative to some vector.OffsetDemo2.3dm (185.5 KB)

@jakemurphy0118 I believe your description of the expected output is correct. I’ll take a closer look on Monday to see what’s going on. Can you get what you want using the Offset command after changing the CPlane to have the desired normal, and setting the InCPlane option to true? You also might want to take a look at RibbonOffset in the v7 WIP.

@chuck I ended up doing something similar it sounds to what RibbonOffset does by projecting the curve to a plane with the desired normal before offsetting the curve. That way the kinks are handled by the Offset command. I only needed an approximate poly-line as a result which made ‘un-doing’ the projection easier.
This avoids the issue I was having with planar Nurbs Curves and Arc Curves in planes not co-planar with the projection plane. Sorry if I was confusing. I do think there might be an issue with Offset in those cases just described.

@jakemurphy0118 I’ve attached your file with the CPlane in the top view changed to match your vector. Command Offset, with CPlane=yes, with selection done in that viewport, gives the same curves that you showed in your example. The command calls the same low level code as the RhinoCommon call. We’re looking into whether there is a mistake in the way the low level code is accessed.OffsetDemo2_CPlane.3dm (184.7 KB)

The SDK wrapper is ignoring the input direction when the curve is planar. Not sure why. I’ll see what can be done. Thanks for the report.