With the sample code reported in this article, you can offset a curve that lies on a non-planar surface.
First of all, it creates a ruled surface normal to the surface on which the curve lies. Then, it offsets the ruled surface and then it finds the offset curve as the intersection between the starting surface and the offsetted ruled surface.
The method proposed in this article makes use of some parameters, such as the height of the ruled surface and the offset tolerance, that are not constant and must be adapted based on the geometry of the specific surface.
The code is reported below. The referenced *.eye file is attached to this article.
// offset parameters
const double offsetAmount = 10;
const double ruledHeight = 2;
const double tolerance = 0.1;
// loads the geometry
ReadFile rda = new ReadFile(@"C:\devDept\curveOnSurfaceOffset.eye");
rda.DoWork();
rda.OpenTo(design1);
Surface surface = (Surface) design1.Entities[0];
Curve curve = (Curve) design1.Entities[1];
// creates the ruled surface
curve.Regen(0.01);
Point3D[] firstCurveVertex = new Point3D[curve.Vertices.Length];
Point3D[] secondCurveVertex = new Point3D[curve.Vertices.Length];
for (var i = 0; i < curve.Vertices.Length; i++)
{
Point3D pt = curve.Vertices[i];
surface.Project(pt, out Point2D proj);
Vector3D normal = surface.NormalAt(proj.X, proj.Y);
normal.Normalize();
firstCurveVertex[i] = pt - ruledHeight * normal;
secondCurveVertex[i] = pt + ruledHeight * normal;
}
Curve cv1 = Curve.CubicSplineInterpolation(firstCurveVertex);
Curve cv2 = Curve.CubicSplineInterpolation(secondCurveVertex);
Surface ruled = Surface.Ruled(cv1, cv2);
// offsets the ruled surface by offsetAmount
ruled.Offset(offsetAmount, tolerance, out Surface offSetSurface);
// finds the offsetted curve as intersection between the ruled surface and the original one
Surface.Intersection(new List<Surface> { surface }, new List<Surface> { offSetSurface }, tolerance, out ICurve[] curveOffset);
foreach (Entity ent in curveOffset)
{
ent.LineWeight = 3;
ent.LineWeightMethod = colorMethodType.byEntity;
design1.Entities.Add(ent, Color.Blue);
}
The ruled surface's normals direction (inward/outward) depend both on the initial curve direction and on the starting surface normal.
If the curve is oriented counterclockwise with respect to the surface's normal then the ruled surface has the normals pointing outward, otherwise, the ruled surface's normals point inward.
To change this default behavior you can call:
ruled.ReverseU();
Comments
Using this method, the offset distance to the base curve will be extrinsic and not intrinsic, right?
Hi Martin,
Yes, it is a 3D distance and not the distance measured on the 2D surface.
Very helpful example.
Since the normal vector of the original surface is changing over the course of the offset area this idea can be refined by an iterative approach.
In case of a surface with a "fast" changing normal vector or a big offset this can reduce the error.
Blue = 1 Step
Orange = 4 Steps
Please sign in to leave a comment.