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;
}
```