One of Captain America's signature moves is throwing his shield and having it hit its target after multiple bounces. It's just what he does. But how difficult would this actually be? Yes, I know Captain America is just a comic book hero, but that doesn't mean this won't be a fun physics problem.
How do you model a thrown shield reflecting off different surfaces? Really, that's the difficult part. Let me go ahead and start with some assumptions.
- The speed of the shield doesn't matter. I will assume it "flies" like an airplane wing so it will follow a level trajectory and not drop as it travels.
- In the comic books, the shield is made from vibranium. Let's assume this allows perfectly elastic collisions with different surfaces.
- As I showed before, a completely elastic collision can obey the "law of reflection". This means that when the shield hits a wall, the angle of incidence will be equal to the angle of reflection.
I think that's enough to start making a model. It's not difficult to make a shield move at a constant speed, but the reflection off a wall isn't so straightforward. Here's three questions you have to ask:
- Does the shield even hit the wall?
- When and where is the collision with the wall?
- What is the reflected velocity vector given the orientation of the wall and the incoming velocity?
Yes, it would be fairly easy to model this in the case of a wall that is only in the y-direction (up/down), but I want a more generic reflection. First, how do we know if there is a collision? There are several methods for collision detection (it's an important part of many video games) but I want to create my own.
Suppose I have a wall with a length of L, oriented in some direction, and a shield moving toward it. The first thing I am going to do is to find the position of the two end points for the wall (P1 and P2). Now I can calculate the distance from P1 and P2 to the position of the shield. If the shield is intersecting this wall, the sum of these distances should equal L. Here is a diagram:
If I calculate these distances as vectors, the sum of the magnitudes of r1 and r2 (from P1 and P2 to the shield) will only equal L if the center of the shield is between the two points. If the shield is outside the points or not yet to the wall, their sum will exceed L.
A couple of things to notice. First, I am just dealing with this wall in 2-D, but this method should work in 3-D. Second, I don't care about the size of the shield---I am merely dealing with it as a point object. I don't think this matters for playing with collisions with a wall (we could change this later if it bothers you).
Now for the reflection. This is trickier and my method only works in 2-D so the shield moves in the x-y plane. If I create a wall in VPython (Glowscript), there are some properties of this object which is technically a "box." There is the position of the center of the box, the size of the box and the "axis." The axis is a vector that is perpendicular to the box to describe its orientation.
Here is a diagram showing the shield colliding with the wall. The two important vectors are the velocity and the axis.
Here I have α as the angle between the incident velocity vector and the axis vector. You can find this angle by first finding the dot product between these two vectors and using the following relationship:
Finding the dot product for vectors is simple if you know the vector in component form (the x,y,z components). It's also simple to find the magnitude of these vectors. So, in the end you get the angle between these two vectors. Oh, it's even easier since both the dot product (dot) and the vector magnitude (mag) are built in functions in VPython. But what I really need is the angle θ which shows the amount I would have to rotate the original vector. Based on my drawing, this vector θ would be:
Now that I have the rotation angle, I need to rotate the vector. I can use the rotation matrix in 2-D. Here is the xkcd version of the rotation matrix. It's funnier than the actual matrix. So, that's pretty simple. Now let's put it all together.
Actually, this is sort of like a video game. So I made a video game. Just drag the arrow to pick the direction you wish to aim the shield. The goal is to bounce the shield off the wall and hit the blue circle.
If you successfully hit the circle, it turns yellow. If you miss, just press play and try again. The code is a little messy---but you can check it out here. I'll probably make a screencast in which I go over the different parts of this program.
Once you play with this program, you might notice it's not so trivial to aim at the wall and hit the target. You can do it, but only with a little bit of guesswork.
How about something a bit more complicated? What if the reflected surface isn't a flat wall but a curved surface? In this case we can still assume that the incident and reflected angle are still equal. However, there is a big difference. Now if you hit the curved surface at a slightly different point, it will have a different axis about which it will reflect.
In terms of coding, it's actually an easier program to create. Collision detection is simpler. All I need to do is determine the distance from the center of the curved wall to the center of the shield. If this distance is less than the sum of their radii, then they "hit." After that, I merely need to calculate the vector that is equivalent to the axis vector for the wall. There is one problem that I encountered---depending on where the shield hits, it could reflect either to the left or the right. By finding the angle between the incident velocity vector and the "axis" I can determine the direction of rotation in the rotation matrix.
Here is the same "game" with a curved surface. (the code)
Pretty tough, right?
Of course Captain America is better than all of you at this. He can bounce his shield off multiple surfaces and score a "hit." Are you ready to try two bounces? Try to hit the curved surface and then the wall and then target. Here is the code.
If you score a hit on your first try, you should be an Avenger. And if you want some homework, here are a few suggestions.
- Make a plot of initial velocity angle vs. deflected angle. How does this plot look for both the flat and curved wall? You might prefer to make a plot of initial angle vs. final y-position or something.
- What if you put in a third object to deflect the shield? Is it even solvable?
- Can you make the computer program find an angle that would score a hit?
- What about non-elastic collisions? Yes, that would be a little bit more difficult---but still fun.