Normal vector

Hello, I’m trying to get the normal vector of a point that is the intersection between mesh/ray.
To do it I did a custom component in C++ that obtains the intersection point and another custom component with GetClosestPoint() Rhino C++ API: ON_Mesh Class Reference that obtains the m_face_index.
Now with the intersection point and the face index, is there any function to get the normal?
Thank you!

You need two components. First Mesh Closest Point, then Mesh Eval.

1 Like

Thank you Martin, this was so usefull to understand what I want to do.
Now my problem is I don’t find a function to create a custom component like MeshEval. Do you know any function that can help me?
Thanks again!!

Why do you need a custom component?

I’m trying to replicate raytracing for optical simulations using C++. It’s for an university work and I must do as much as possible with code, even if there are already components that do the same that I want.

I recategorized your topic to “Grasshopper Developer”. You might get better help that way.

1 Like

Thanks Martin

In C# I use that

for this kind of simulation I think surface are better than meshes.
if you want mesh
https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_Intersect_Intersection_MeshRay.htm

/// <summary>
  ///
  /// </summary>
  /// <param name="surface"></param>
  /// <param name="ray">A line that is oriented so the ray is going to from to the end</param>
  /// <param name="distanceMax">The max distance we look for relexion</param>
  /// <param name="tolerance">Tolerance</param>
  /// <returns>The line representing the reflexion, line.From is on surface</returns>
  public Line RaySurfaceReflexion(Surface surface, Line ray, double distanceMax, double tolerance)
  {
    Line lineRay = new Line(ray.From, ray.Direction, distanceMax);
    Line lineOut = Line.Unset;

    Curve curve = lineRay.ToNurbsCurve();
    CurveIntersections cis = Rhino.Geometry.Intersect.Intersection.CurveSurface(curve, surface, tolerance, tolerance);
    if (cis.Count > 0)
    {
      double minParameter = double.MaxValue;
      foreach (IntersectionEvent ci in cis)
      {
        if (ci.ParameterA < minParameter)
        {
          minParameter = ci.ParameterA;
        }
      }
      if (minParameter >= 0)
      {
        Point3d pointIntersection = curve.PointAt(minParameter);
        double u, v;
        surface.ClosestPoint(pointIntersection, out u, out v);

        Plane frame = Plane.WorldXY;
        surface.FrameAt(u, v, out frame);
        Vector3d reflexion = Reflexion(ray.Direction, frame.Normal);
        lineOut = new Line(pointIntersection, reflexion, 1);
      }
    }
    return lineOut;
  }

  /// <summary>
  /// Perfect relexion
  /// </summary>
  /// <param name="ray">Ray as a vector</param>
  /// <param name="normal">Normal Vector at the impact point</param>
  /// <returns></returns>
  Vector3d Reflexion(Vector3d ray, Vector3d normal)
  {
    normal.Unitize();
    return ray - 2.0 * (ray * normal) * normal;
  }
1 Like