I need some help. I've spent about the last 5 days slowly moving through Tony's vector tutorials, and I can't seem to get past projecting vectors. The whole goal of this is to prepare myself for my all-but-done JIG entry, and yet, maybe it's the way he explains it, but it seems like the concepts don't come across very well at all. The code just seems to be thrown at you, and in the examples, they don't clearly reflect the code displayed in each chapter. Does anyone know of any other vector tutorials that cover the basics of movement and bouncing?
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6
I'll take my own stab at this, maybe it will help...
Everyone knows how to bounce a point object around in a box - it's one of the first real-time simulations you try when you're learning how to game program. The basis game loop is: update position from velocity, IF position exceeds the box THEN move back into the box, and flip the offending velocity's sign to start moving the other way.
x += vx;
y += vy;
if (x < 0)
{ x = 0; vx = -vx; }
if (x > xMax)
{ x = xMax; vx = -vx; }
// ... do the same clipping stuff for y...
This IS vector math, even though it doesn't look much like it. The important fact: it is easy to bounce off a wall when the wall is orthogonal to one of the basis vectors of the coordinate system that expresses your position and velocity. So in this example, it was easy to bounce of a y-directed (vertical) wall by checking the orthogonal component (x) and flipping the x component of the velocity).
Vector projection is all about changing the coordinate system of your velocity. We always want to express the velocity in a coordinate system where one coordinate measures along the axis parallel to the wall, and the other coordinate measures along the axis perpendicular to the wall. JUST LIKE we do for the x-y bouncy-ball-in-box system shown up top, that everybody already knows.
Picture time - see Figure 1. There's a lot in the picture so take a moment.
There's a red ball (with zero radius for now), with position p0 and velocity v0. It's going down-right, we want it to bounce back up.
There's also the black edge, which stretches FROM position p1 TO position p2
It DOES have direction. It's length is E.
e-hat is a unit length vector that expresses the direction of the edge. Compute it by: e = p2-p1, e_hat = e.normalize().
n-hat is another unit length vector, that is orthogonal to e-hat. This vector can be constructed from e_hat: n.x = -e.y; n.y = e.x;
Finally, there's x_hat and y_hat, which are invariably (1,0) and (0,1).
IMPORTANT: Any vectors x(y)-component can be found by the dot product with x(y)_hat:
p0.x = p0 DOT x_hat
p0.y = p0 DOT y_hat
Now we change coordinate systems. Instead of working in the x-y frame, we want to work in a new coordinate system, the e-n frame. The origin of this frame is at p1. The other end, p2, is at the coordinate (E,0). Check out Figure 2.
Just like before, we can compute the e-component and n-component of any vector by dotting it with e_hat and n_hat. Of greatest importance is the "height" of the ball above the edge. Convert the ball position into e-n coordinates by:
p0' = p0-p1 // a vector that points from the new origin to the ball.
p0'_e_component = p0' DOT e_hat
p0'_n_component = p0' DOT n_hat
Figure 3 shows how this decomposition works.
In this case, there's no collision yet. The "height", (p0-p1) DOT n_hat, is still positive. Fast forward a frame, and the ball slips below the edge. If the ball is right on the edge, the height will pop out zero. When it crosses the edge, the dot product will pop out negative. That's our cue to act. See figure 4.
What do we do? First, move the ball back into the playing field - construct a new position vector which has the same e_component as the current position vector, but zero n_component: (the SCALED_BY operation stretches a vector by a scalar). See figure 5.
The final step is to "bounce" by changing the velocity. Recall for the beginners ball-in-box, when we crossed a y-directed wall, we flipped the x-component. In this case, we crossed an e-directed wall, so we'll flip the n-component. See figure 6.
v_e_component = v DOT e_hat
v_n_component = v DOT n_hat
The next frame, the ball will move away from the edge and won't trigger another check. To put it all together, wrap the ball inside of a consistently ordered set of edges, and let 'er rip (Figure 7). Each edge test is performed exactly the same - they're no funny special cases if you order them this way (i.e., you're always checking for positive height and triggering the resolution steps when the height is negative).
At each frame, test the ball against each wall (just like in the square-box problem, you checked against all four edges of the screen).
EDIT: one last thing - watch out if you do all this calculation in screen space, which is a left handed coordinate system. The only think it might muck up is the calculation of the inward normal - it might twiddle the signs.
Vector projection is all about changing the coordinate system of your velocity. We always want to express the velocity in a coordinate system where one coordinate measures along the axis parallel to the wall, and the other coordinate measures along the axis perpendicular to the wall. JUST LIKE we do for the x-y bouncy-ball-in-box system shown up top, that everybody already knows.
If tony had said it that simply strait-up, I wouldn't have made this thread. :-p
Basically that paragraph suggests that you envision your x/y axis rotated to the angle of your movement vector:
Is this a correct assumption?
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6
There's a few more subtleties, such as what to do when your bounding polygon is non-convex, what to when your ball has nonzero radius, what to do when your polygon has angles less than 90 degrees and the ball is nonzero radius, and friction/damping. But the basics always stay the same.
Basically that paragraph suggests that you envision your x/y axis rotated to the angle of your movement vector:
Actually I spoke too soon. The correct statement is:
envision your x/y axis rotated to the angle of your walls edge vector.
(Though your picture demonstrates correct understanding - it shows a coordinate system where the wall is parallel to one coordinate axis and perpendicular to the other axis. )
Ok good to know. I'm sure it will help a lot. Though if I understand correctly, we were both correct. The re-written statement you suggested puts the the angle my theory calls perpendicular (orthogonal?) as your parallel. So yay, win-win.
The 'Boose':
ASUS Sabertooth P67 TUF
Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
8GB G.Skill Ripjaws 1600 DDR3
ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
New addition: OCZ Vertex 240GB SATA III SSD WEI Score: 7.6
Them you dont need vectors for that, you can do all with trigonometry too
While you can do it with trig, the calls to various trig functions are very processor expensive. That's the main reason for using vectors, they are computationally much faster (especially if you use stay away from numbers).
I have spent the past few months reading every vector tutorial I could find, and they all have the same weakness, examples. In a classroom setting, you can ask your teacher about something you don't understand, and they can draw it out for you to show you step by step what is happening. I think examples with a "step" button to change from real-time to step-time animation would help alot of people understand what is happening. For my recent 3d vector work I created a similar function, and it has helped me debug much faster.
Sorry for digging up this old (but delicious) thread, but I could really use
some of your wisdom again, Rachil0. Any chance you could upload those pictures?