Im trying to determine where a "shot" will hit the wall from a position and an angle.
The player shoots a ball from a certain point with a certain angle towards a wall. And I want to be able to determine if the ball will hit within the bounds of the goal.
This is what i know:
origin: the ball's coordinates
length: the distance to the wall
angle: the angle of the shot
This is what i want to calculate:
point: the position the ball will have when it hits the wall
Thanks in advance!
unless i'm missing something:
point y = origin y + length
point x = origin x - length * tan(angle)
in Trig for a right angled triangle Tan(angle) = opposite/adjacent.
This should be all you need to get your position.
It should be noted that this is not a programming question as such and there are probably other places for Maths questions like this. :)
Related
My maths is very rusty and I've never been great at imagining things past 2 dimensional space.
My question is this. Given a point of origin (p1), how can I calculate a new point (p2) which is a known distance (100 units) based on two angles (Yaw and Pitch).
What I know is the 3D dimensions for a virtual room, the point of origin within that room and the Yaw and Pitch (I've called this horizontal angle and vertical angle). To put it in to English, I would like to fire a line of 100 units within this room from that point of origin based on it's Yaw and Pitch values and get the point at the end of that line.
I would like this point in space because I would like to define my line using p1 and p2. I want to eventually go on to use this line in a line/plane intersection test. The planes are also known within the virtual room. I only mention this because with my lack of mathematical knowledge, someone may suggest I look at some other method.
If you just want to define a line, you don't need the second point. The line's direction vector can be calculated directly as:
/ cos pitch * sin yaw \
dir = | sin pitch |
\ cos pitch * cos yaw /
This assumes that the y-axis points upwards. A zero yaw points in positive z-axis. Increasing yaw will turn the direction towards the positive x-axis. These definitions are all interchangeable.
The line is then:
x = startPoint + t * dir | t \in R
If you really want the second point, just use 100 as t and calculate x.
I want to do frustum culling for my engine :)
On this site seems to be nice example how to do this, but there is one thing I don't get:
if ( D3DXPlaneDotCoord( &m_frustum[i], pPosition ) + radius < 0 )
{
// Outside the frustum, reject it!
return FALSE;
}
Is why there is a radius for?
Or maybe what is dependence between dot product and distance from plane?
Cause with my actual knowledge I would calculate it like that:
calculate dot product of plane. And as vectors are normalized dot product is equal to cosinus of angle between vectors. So it can return values between -1 and 1.(Thats why I dont understand why radius is added). And if cos > 0 means that angle is between 0 and 90 degrees. So center point is in front of plane. Then I would use equation for distance of point from plane. And check if that distance is higer than radius of sphere. But this guy have this in that one equation. What magic is behid that?
Ok I see where is my mistake dot procuct is not equal to cos of angle, but cos of angle and length of vector P( describing position of center of sphere). So what exactly is cos*|P| = ?
http://tinypic.com/r/2vxrpkw/5( no rep for images )
Probably answered own question brb( wikipedia ) :)
Yeah exactly. My P is not P desribing point in coordinate system, but It's P - known point of plane. So it's vector between point and know point of plane. Everything seems legit. Thanks for help :P It's nicely explained here: www.songho.ca/math/plane/plane.html
This can be seen as a projection of the pPosition along the plane's normal.
If the length of this projection plus the plane's D component minus the sphere radius is less than zero means the sphere is behind.
For fun I am making Pong in Python with Pygame. I have run into some trouble with reflections.
So the ball has an angle associated with it. Since positive y is down this angle is downward. If the ball hits the top or bottom walls I can simply negate the angle and it will reflect properly, but the trouble is with the left and right walls. I cannot figure out the trigonometry for how to change the angle in this case. I am currently trying combinations of the below snippet but with no luck.
self.angle = -(self.angle - math.pi/2)
I have attached the code. You can try it for yourself easily. Just remember to take out the "framerate" module which I have not included or used yet. I would appreciate any input. Thanks!
You'll want to look into Angle of Incidence.
Basically you'll want to find the angle theta between your incoming vector and the normal of the wall the ball is hitting. Where the incoming angle is (wall normal)-theta the resulting angle is (wall normal)+theta.
The angle can be found using the dot product between your incoming vector and the normal of the wall, then taking the inverse cosine (normalize your vectors first).
You should use:
math.pi - angle
Hey I can't figure out what the equation to find the new angle of travel of an object is after reflecting off of a wall.... The angle of travel is also based off the unit circle so 0degrees would be traveling right, 180 traveling left, 270 down, etc.
Just making the angle negative doesn't work either, any tips?
I think this is what you're looking for. I added in the angle of the wall, even if you didn't need it.
reflectionAngle = wallAngle + ((wallAngle + 180) - (incidenceAngle + 180))
If the wall is just vertical, its angle would be 90 degrees.
I hope this helps, and good luck!
EDIT: As a more simplified method, posted by Casey below:
reflectionAngle = 2*wallAngle - incidenceAngle
You have to change the angle relative to the wall coordinate system (t, n) and then transform back to (x, y) coordinates. The wall coordinate n is perpendicular to the wall; the direction t is created by taking the cross-product of the t-vector into the z-direction.
The algorithm would say that the incoming (v_t, v_n) velocity are changed as follows:
perpendicular component v_n changes sign.
tangential component v_t is unchanged, assuming no friction.
Once you have those, transform back to (x, y) coordinates.
It's easy if you think in terms of 2D vectors.
It would be
outAngle = 360 - inAngle
I have a direction vector that applied to a position gives me the point at which the camera should look. How can I get from that yaw, pitch and roll in order to use glRotatef properly?
Thanks in advance
None of these equations are 'wrong' but all are a little clumsy.
Ryder052, you example does not account certain cases as you've commented. Why not use atan2?
Given unit (normalized) direction vector d
pitch = asin(-d.Y);
yaw = atan2(d.X, d.Z)
You cannot get yaw, pitch and roll from a direction vector as the direction vector will only tell which direction to look in (yaw and pitch)
To get the yaw and pitch you use trigonometry - I assume you have some working knowledge. Check out this wiki page for some useful diagrams to visualize the angles.
Letting Y = yaw, P = pitch.
First to get yaw you want:
tan(Y) = x/(-y)
Now to get pitch:
tan(P) = sqrt(x^2 + y^2)/z
To get the actual values for Y and P you'll need to use inverse tan, I've written it above using tan to make the derivation clearer.
Note that the minus signs depend on how you define you angles and axes, but you should get the idea.
You can then set roll to be 0 or whatever you like.
You probably don't actually want the yaw, pitch and roll. You just need the correct transformation. Try using gluLookAt to build it. Documentation.
pheelicks's equations are wrong. Dear future googlers, here you got what's working:
Assuming pitch: rotation by X axis, yaw: rotation by Y axis, roll: rotation by Z axis. Direction vector V(x,y,z)
pitch = asin(V.y / length(V));
yaw = asin( V.x / (cos(pitch)*length(V)) ); //Beware cos(pitch)==0, catch this exception!
roll = 0;
Well, I am not sure what any of these answers are about because I could not get any of them to work.
I created my own solution...
// get world target offset
// convert world target offset to world direction normal
// get my world transposed (inverted)
// rotate world direction normal to my space normal
Vector3D lWorldTargetOffset = gWorldTargetLocation - gWorldMyLocation;
Vector3D lWorldTargetDirection = lWorldTargetOffset.Normalize();
MatrixD lMyWorldTransposed = MatrixD.Transpose(MyWorldMatrix);
Vector3D lMySpaceTargetDirection = Vector3D.Rotate(lWorldTargetDirection, lMyWorldTransposed);
you now have the world target direction normal in my space
lMySpaceTargetDirection.X = pitch
lMySpaceTargetDirection.Y = yaw.
lMySpaceTargetDirection.Z = <0 infront >0 behind.
As per direction normals all values are -1 to 1 so if you want degrees simply * 90.
Not saying this is the best solution but it is the only one I could get to work after spending hours searching online and wading through copious amounts of obtuse and nebulous crud.
I hope you, someone, or anyone, will enjoy simply rotating the target direction normal making it relative to myspace, and find it easy and helpful :)