Suface normal nut perpendicular to Surface

Surface normal not perpendicular to Surface

The surface is an extrusion of a circle along the x axis. The x dimemsion at the end of the vector
should be the same as the begining of the vector. Front and perpective views are included.
The lines are added to show the vectors.

Below is the c# code used to create the normal vectors.
The steps in the code are a little overkill. This is what I ended up with after trying other ways
to make sure the point for the normal was on the surface

    public void BranchProfileToRingCore2(RhinoDoc doc, RingProfile profile, Surface core_surface)
        double u;
        double v;
        Guid point;
        Guid line_id;
        Point3d test_point;
        Point3d[] points;
        Vector3d base_vector;
        Curve[] new_curve;
        Brep pull_brep;

        Curve curve = BullFallsPlugIn.Instance.settings_drawings.CurveFromGuid(profile.Bottom);
        Curve test_curve = curve.DuplicateCurve();

        test_point = profile.center_bottom;
        pull_brep = core_surface.ToBrep();
        Rhino.Geometry.Collections.BrepFaceList bref_faces = pull_brep.Faces;

        new_curve = test_curve.PullToBrepFace(bref_faces[0], .000001);
        doc.Objects.Delete(profile.Bottom, true);
        Rhino.Geometry.NurbsCurve nncurve = new_curve[0].Rebuild(3, 3, true);
        Guid new_curve_id = doc.Objects.AddCurve(nncurve);
        Curve pulled_curve = BullFallsPlugIn.Instance.settings_drawings.CurveFromGuid(new_curve_id);
        pulled_curve.DivideByCount( 2, true, out points);


        bref_faces[0].ClosestPoint(points[1], out u, out v);
        base_vector = bref_faces[0].NormalAt(u, v);
        if (bref_faces[0].OrientationIsReversed)
        point = doc.Objects.AddPoint((Point3d)base_vector);
        Line line = new Line((Point3d)base_vector, profile.center_bottom);
        line_id = doc.Objects.AddLine(line);

Hi Jim,

I"m not seeing where your problem is. Is there a simple block of code that I can run here that repeats this?


Line line = new Line((Point3d)base_vector, profile.center_bottom);

Is probably incorrect. A vector is not a point, as it indicate magnitude and direction, not position. So casting a vector as a point is (my guess) not what you want to do…

base_vector = bref_faces[0].NormalAt(u, v);
This line of code gives the normal vector from the point on the surface.

point = doc.Objects.AddPoint((Point3d)base_vector);
This line of code displays the vector point.
The line you refer to is diagnostic and added to show the direction of the vector normal. It is not part of the model.
The purpose of the method that I enclosed is so the profiles(5) can be rotated perpendicular to to the surface, which is the core of a ring.
There is no simple block of code. The parts used in this method are created and configured in several different places of the plugin.

Jim Randall

Are you sure you don’t want to do this?

var point = brep.Faces[0].PointAt(u, v);
var normal = brep.Faces[0].NormalAt(u, v);
var normal_line = new Line(point, point + normal);

Thanks for your help. It works. I forgot that a normal vector is an offset and not an actual point.

Jim Randall

A vector is not an offset. Again, a vector is a geometric object that has magnitude (or length) and direction. You can learn more about vectors in the Essential Mathematics For Computational Design.