This video started very well, but after coming up with the formula at 7.20, so little emphasis was put on it that I didn't register that this was the final formula. Instead, my mind just kept following the rest of the calculations (proof) and it felt like it all went around and I was lost in what was the goal of the whole thing. It would had been nice with stronger note both graphical and by speech at 7.20 that now we were actually done and this was the formula that you use to solve the original problem (and the one you should implement in code) and tie back on how to use this practically in a user case (i.e. start a sound when bullet reaches point b' or travelled |b'| distance or was at a certain percentage of a).
cos(theta) times the length of vector b will give you the length of vector b prime. Think about the definition of cosine, cos(theta) is adjacent over hypotenuse. That is, cos(theta) equals length of b prime over length of b. Rearranging that gives you length of b cos theta equals length of b prime. If that doesn't make sense, try writing it out on a piece of paper so you can see it better. Then the vector a just gets moved up into the numerator of the fraction. :)
I don't have it implemented in the game but suppose you made an enemy that shoots back at you, that would be an instance when you would implement the whizzing sounds. I don't have any videos showing that, sorry.
It's just a little trigonometry! b is the hypotenuse of a triangle. b' is the base of the same triangle. Remember that cos is A/H. So cos(theta) = b'/b. Multiply both sides by b to get b' = b*cos(theta). If that doesn't make sense then try writing it out on a piece of paper. Then the vector a just gets moved up into the numerator of the fraction :) Man I wish I could use LaTeX here.
After you find e, im assuming you remap the length of e to 0-1 so I can plug that range in to the metadata for volume for a sound instance, so that the farther the player is the quieter the whizz sound is.
Do you have any video where you implement shooting a bullet from P1 to P2? I mean, for example, shooting a bullet from a point to the mouse position. I'm just starting to see your videos, great work!
Awesome video. I've got one question though. How come b' + e = b? Doesn't it have to be b'² + e² = b². Also in the last part of calculating b' using the dot product I think you misplaced a '. Don't you mean b' = (|b|a)/|a|?
You use the squares if you're doing a pythagorean theorem, but in this case b' e and b are just vectors. Good spot about that a being misplaced, it's actually part of the previous equation.
A.dot(A) would produce the same as A.length_squared(), but length_swuared would be much more efficient due to a lacl of trig functions or square roots.
a function that calculates dot between a vector and itself and a function that calculates the length squared of a vector internally would be identical, they would both be v.x * v.x + v.y * v.y + v.z * v.z. No trig either way, same performance properties.
The initial impression I was under was that the full length of b was being oriented to the same direction as a, but when you said you would get a right angle angle at some point I knew I was mistaken. If both vectors had the same length then there couldn't be a right angle vector connecting their endpoints right?
Kevin Barker b gets chopped a bit shorter when it gets projected onto a. Imagine that a is the ground, and b is a vector sticking out of the ground at some angle, and that the sun is directly above a. What shadow does b cast on the ground? If a and b are perpendicular (they are at right angles to each other) then b will cast no shadow. If they're parallel then b's shadow will be the same length as b. The length of the shadow is determined by the dot products we do in the video.
Jorge Rodriguez Actually the idea of the dot product makes complete sense. I think the use of b' instead of just using a new variable made me think the length was remaining the same just the direction was changing. By the way excellent videos. Been using libgdx for Java, but I didn't understand a lot of what was going on in the background.
sorry for being a year late. yes, there is. if you know a little bit of trig, it should have been pretty easy to know. It is vector b divided by sin(angle between b prime and b). SOH CAH TOA are the three cases, since we have hypotenuse and the opposite, we can calculate vector e.
Does it work the same with flipped Y axis? I tried to visualize it, but result is weird. Pseudo code: pastebin.com/SH7KjtYW, screenshot of the result: prnt.sc/p36ax5. White line should end at S.
I like your videos. but this video also felt a bit unnecessary after 7.20. You kind of present the proof, but it's confusing. Of course, it should not be forgotten that this is a video from 9 years ago. Maybe this video will stay here forever and be a great resource to many people. So I wrote the code on unity using the formula. Here is the code: To use it, copy the code into a script and create a cube or whatever for the required objects and reference them. public class Projection : MonoBehaviour { public Transform bulletEnd; public Transform enemy; public Transform player; private void OnDrawGizmos() { // Calculated Projection Point; Vector3 closestPoint = CalcProjection(player.position, enemy.position, bulletEnd.position); // Line From Player To Bullet; Gizmos.color = Color.black; Gizmos.DrawLine(player.position, bulletEnd.position); // Line From Player To Enemy; Gizmos.color = Color.red; Gizmos.DrawLine(player.position, enemy.position); // Line From Player To Projection Point; Gizmos.color = Color.green; Gizmos.DrawLine(player.position, closestPoint); // Line From Enemy To Projection Point; Gizmos.color = Color.white; Gizmos.DrawLine(enemy.position, closestPoint); } public Vector3 CalcProjection(Vector3 self, Vector3 target, Vector3 endPoint) { Vector3 heading = target - self; // DotProduct End point and End Point float num = endPoint.x * endPoint.x + endPoint.y * endPoint.y + endPoint.z * endPoint.z; // DotProduct Heading and End Point float num2 = heading.x * endPoint.x + heading.y * endPoint.y + heading.z * endPoint.z; //Calculated Projection Point return endPoint * num2 / num; } } Im not sure but i founded little problem there. If "bullet end point", In between player and enemy its not work well
I disagree. To find b', which is the distance away from the origin to the player in one axis, you need the angle of b' and b and the vector of b to find b'. from there, you can just do some basic trig, divide b by the sin of the angle between b' and b to get the e vector, which you can remap the length of it to a volume that goes from one to 0, to make it so the farther it is, the quieter it is.
This video started very well, but after coming up with the formula at 7.20, so little emphasis was put on it that I didn't register that this was the final formula. Instead, my mind just kept following the rest of the calculations (proof) and it felt like it all went around and I was lost in what was the goal of the whole thing.
It would had been nice with stronger note both graphical and by speech at 7.20 that now we were actually done and this was the formula that you use to solve the original problem (and the one you should implement in code) and tie back on how to use this practically in a user case (i.e. start a sound when bullet reaches point b' or travelled |b'| distance or was at a certain percentage of a).
This feedback is great, keep it up. :)
cos(theta) times the length of vector b will give you the length of vector b prime. Think about the definition of cosine, cos(theta) is adjacent over hypotenuse. That is, cos(theta) equals length of b prime over length of b. Rearranging that gives you length of b cos theta equals length of b prime. If that doesn't make sense, try writing it out on a piece of paper so you can see it better. Then the vector a just gets moved up into the numerator of the fraction. :)
Excellent, keep these coming, a great resource to have these things explained so well! Much appreciated.
I'm learning a lot, thanks Jorge
I don't have it implemented in the game but suppose you made an enemy that shoots back at you, that would be an instance when you would implement the whizzing sounds. I don't have any videos showing that, sorry.
It's just a little trigonometry! b is the hypotenuse of a triangle. b' is the base of the same triangle. Remember that cos is A/H. So cos(theta) = b'/b. Multiply both sides by b to get b' = b*cos(theta). If that doesn't make sense then try writing it out on a piece of paper. Then the vector a just gets moved up into the numerator of the fraction :)
Man I wish I could use LaTeX here.
Hello, at the end you obtain b' = (b' length) x a / (a length)
How we get (b' length) ?
Amazing, this stuff is genius! makes game math a lot easier for me, can't wait for the next one! you should submit this to khan academy!
Since we don't know b' or its length, why do you sub |b'| for |b|cos(theta)?
After you find e, im assuming you remap the length of e to 0-1 so I can plug that range in to the metadata for volume for a sound instance, so that the farther the player is the quieter the whizz sound is.
Do you have any video where you implement shooting a bullet from P1 to P2? I mean, for example, shooting a bullet from a point to the mouse position. I'm just starting to see your videos, great work!
Great tutorials, Are you planing to teach something about rigid body?
Rigid body physics simulations? Yeah I have plans to do something like that a bit later on. All in time!
Awesome video. I've got one question though. How come b' + e = b? Doesn't it have to be b'² + e² = b². Also in the last part of calculating b' using the dot product I think you misplaced a '. Don't you mean b' = (|b|a)/|a|?
You use the squares if you're doing a pythagorean theorem, but in this case b' e and b are just vectors. Good spot about that a being misplaced, it's actually part of the previous equation.
seems to make sense to me up until 9:20. why can you remove cos(theta) and replace with a-vector?
A.dot(A) would produce the same as A.length_squared(), but length_swuared would be much more efficient due to a lacl of trig functions or square roots.
a function that calculates dot between a vector and itself and a function that calculates the length squared of a vector internally would be identical, they would both be v.x * v.x + v.y * v.y + v.z * v.z. No trig either way, same performance properties.
@@JorgeVinoRodriguez Well, color me surprised.
The initial impression I was under was that the full length of b was being oriented to the same direction as a, but when you said you would get a right angle angle at some point I knew I was mistaken. If both vectors had the same length then there couldn't be a right angle vector connecting their endpoints right?
Kevin Barker b gets chopped a bit shorter when it gets projected onto a. Imagine that a is the ground, and b is a vector sticking out of the ground at some angle, and that the sun is directly above a. What shadow does b cast on the ground? If a and b are perpendicular (they are at right angles to each other) then b will cast no shadow. If they're parallel then b's shadow will be the same length as b. The length of the shadow is determined by the dot products we do in the video.
Jorge Rodriguez Actually the idea of the dot product makes complete sense. I think the use of b' instead of just using a new variable made me think the length was remaining the same just the direction was changing. By the way excellent videos. Been using libgdx for Java, but I didn't understand a lot of what was going on in the background.
You can think of b' as a completely new variable if it helps.
Hello, is there any way of knowing the length of b or e? Thanks for your vids btw, they have been very helpfull and educational.
sorry for being a year late. yes, there is. if you know a little bit of trig, it should have been pretty easy to know. It is vector b divided by sin(angle between b prime and b). SOH CAH TOA are the three cases, since we have hypotenuse and the opposite, we can calculate vector e.
Does it work the same with flipped Y axis? I tried to visualize it, but result is weird. Pseudo code: pastebin.com/SH7KjtYW, screenshot of the result: prnt.sc/p36ax5. White line should end at S.
Ultra super amazing very cool ❤️🔥🔥
I'm in college now, I study computer science.
Yes sure :) I'm working on a very old and small tablet, sorry.
hey, out of interest what did you study at college?
I like your videos. but this video also felt a bit unnecessary after 7.20. You kind of present the proof, but it's confusing. Of course, it should not be forgotten that this is a video from 9 years ago. Maybe this video will stay here forever and be a great resource to many people. So I wrote the code on unity using the formula.
Here is the code:
To use it, copy the code into a script and create a cube or whatever for the required objects and reference them.
public class Projection : MonoBehaviour
{
public Transform bulletEnd;
public Transform enemy;
public Transform player;
private void OnDrawGizmos()
{
// Calculated Projection Point;
Vector3 closestPoint = CalcProjection(player.position, enemy.position, bulletEnd.position);
// Line From Player To Bullet;
Gizmos.color = Color.black;
Gizmos.DrawLine(player.position, bulletEnd.position);
// Line From Player To Enemy;
Gizmos.color = Color.red;
Gizmos.DrawLine(player.position, enemy.position);
// Line From Player To Projection Point;
Gizmos.color = Color.green;
Gizmos.DrawLine(player.position, closestPoint);
// Line From Enemy To Projection Point;
Gizmos.color = Color.white;
Gizmos.DrawLine(enemy.position, closestPoint);
}
public Vector3 CalcProjection(Vector3 self, Vector3 target, Vector3 endPoint)
{
Vector3 heading = target - self;
// DotProduct End point and End Point
float num = endPoint.x * endPoint.x + endPoint.y * endPoint.y + endPoint.z * endPoint.z;
// DotProduct Heading and End Point
float num2 = heading.x * endPoint.x + heading.y * endPoint.y + heading.z * endPoint.z;
//Calculated Projection Point
return endPoint * num2 / num;
}
}
Im not sure but i founded little problem there. If "bullet end point", In between player and enemy its not work well
I disagree. To find b', which is the distance away from the origin to the player in one axis, you need the angle of b' and b and the vector of b to find b'. from there, you can just do some basic trig, divide b by the sin of the angle between b' and b to get the e vector, which you can remap the length of it to a volume that goes from one to 0, to make it so the farther it is, the quieter it is.