I’ve written before about how I sometimes like to imagine what would happen if you shot a laser in a fully mirrored room. Back then I did a bunch of cool stuff with flat walls, mostly by calculating the distance beyond the wall a bouncing ball was and having a potential energy function that brought the ball back. Recently I’ve been trying to figure out how to do that in much more complex shapes so I’ve been playing around with *Mathematica’*s “Region” capabilities. It took me a while, but I think I finally have a decent version with arbitrary shapes.

For those that don’t want to read any more, here’s a laser bouncing around inside a cow:

I was hoping that there would be an easy function like “normal to surface” or something but I couldn’t find anything close enough. There is a nice “RegionDistance” function that tells you how far from a region (a cow) you are. Unfortunately I couldn’t use that as my potential energy because to do the differential equation solving I need to be able to take a derivative of that (that’s what gives you the forces and hence the acceleration of the ball) and Mathematica didn’t really like that (I don’t blame it, it’s not really a differentiable function).

So then I started playing around with “RegionNearest” which tells you what part of a region is closest to your current position (ie the position of the ball). With that, here’s what I do:

- Define the region (cow=ExampleData[{“Example3D”, “Cow”}, “MeshRegion”])
- Find the boundary of the region (BoundaryRegion[cow])
- Launch the laser/ball
- Constantly check to see if the position is within some small distance of the boundary
- If it is, find the nearest point on the boundary and use that to determine the normal to the boundary (current point minus the boundary point).
- Use the normal vector to reflect the velocity vector
- repeat 4-7 until your computer crashes.

What’s really handy is the “WhenEvent” feature of Mathematica’s differential equation solver “NDSolve.” WhenEvent basically does part 4 above and triggers the function for 5 and 6. It’s so useful that I use it for this situation that isn’t really a differential equation. Basically I just say the force is zero everywhere and add the WhenEvent feature to do the reflections. It works great!

I should note that I started this project wondering what happens in a sphere. But it turns out that it’s super boring:

Then I went on to an ellipsoid, but that was pretty boring too. So, I went with the cow (my sons helped pick that). When my son saw the one above, he was really interested in what happens when it goes down a leg. Here you go:

Cool, huh?

Thoughts? Here are some starters for you:

- I’m in this class and … wait … nevermind
- This is cool. I especially like . . .
- This is dumb, you forgot about . . .
- You should try this shape . . .
- Why didn’t you use python to do this?
- How do you do the vector math with the normal vector and the velocity vector to do the reflection?
- What if the cow moves?
- Wait, I thought you were in the dean’s office now. Why are you still doing this cool stuff, aren’t you just a stuffed suit?
- Why do you only sometimes italicize the word M
*a*t*h*e*m*a*t*i*c*a?

I don’t know about lasers, but I agree that it seems like shooting a laser inside a sphere would result in the beam staying in a single plan. It seems like the only part of a sphere that would matter is essentially a circle (or a very short cylinder, if you insist on staying in three dimensions).

I also want to state that I do not support you being awarded grant money to put an actual laser inside an actual cow.

Interesting. Have you thought what would happen if the cow weren’t completely empty (optically speaking), but filled with internal organs that had different refractive index than the cow itself?

ooh, that’s interesting! To modify my current approach I’d have to use an Eikonal approach, basically applying the Fermat’s least action/time continuously. Actually if there were abrupt changes in refractive index I guess it would just be normal ray tracing (which is really all I’m doing here).