How to reflect an angle across the Y axis - math

I am no mathematician, but I somehow got into game development as a hobby.
Having never studied anything beyond basic math, I have a lot of trouble figuring out how to reverse the angle of something, facing to the opposite direction, along the X axis & across the Y axis.
One image says more than 1000 words though (specially uneducated words):
http://img156.imageshack.us/i/wihwin.png/
I basically want to reverse the direction of cannon objects adhered to a robot. When the robot changes from facing right to facing left, I do (180 - angle) as everyone suggested me, but it literally reverses the angle, making the cannons aim up when they are aiming down. So, I need to do something else, but it escapes my knowledge.
To put it in other words, I work in 2D, so I want an angle that is facing right to face left. My angles are defined:
0 being "totally to the right"
180 "left"
90 "up" and
270 "down"
I want something that is aiming with an angle of 91 to turn into 89 when reversed. There's no Z axis present. Anyone would be so kind to help me with this?

In answer to your edit what you want then is
-( x - 90 ) + 90
i.e.
180 - x
Of course you will likely be working in radians and not degrees if you are using the standard C trigonometric functions so that would actually be
M_PI - x
Basically this breaks down into three steps
( x - 90 ) adjusts your angle so that the zero point is at 90 degrees.
Negating this then flips the transformed angle.
Add 90 back on to transform back to the original angle range.
Edit: Just noticed this is the same as #Paul R but you didn't seem to think that was correct?

This is quite tricky to answer without knowing a bit more about how the cannons are defined in your game, but I'll try to give some pointers.
It sounds like your cannon is viewed from the side, and you are wanting it to turn around from right to left but keeping the cannon facing up. The calculation depends on which direction 0 is, and whether the angles run clockwise or anticlockwise.
If the angle of 0 has the cannon pointing straight up, then the angle is measured from straight up, clockwise. Therefore, the reverse angle will be -angle. If negative angles don't work then use (360-angle).
If the angle of 0 has the cannon pointing to the right and an angle of 45 points to the bottom right, then the upward facing cannon angles are from 180 to 360 with 270 being straight up. Therefore, to reverse an angle, you'd use (540-angle).
If the angle of 0 has the cannon pointing to the right but an angle of 45 points to the top right, then the cannon angles are from 0 to 180. To reverse the angle, use (180-angle).
I hope that helps! Lee.

It depends on how you are defining your angle. If you define it relative to the X axis then the angle is indeed just (180 - alpha).

Looking at your diagram, the angles you've marked are the same - you've simply changed the starting point for them. If you actually intended to measure the angle so that 0 deg is straight up, then it's 360 - x
Thus if you have aimed at 45 degrees, when you reverse it is 360-45 = 315 degrees

Where does your zero degree angle point, and where does 90 degrees point?
If zero is straight up then you could just do -1 * angle.

Related

Two possible paths for G-code circles

In G-codes a clockwise arc can be specified by e.g.
G02 X2 Y0 R2
This code should give an arc between the current position and (2,0) with radius=2.
According to several sources (And Math) eg.
There will always be two circles/arcs that satisfies these conditions each with a clockwise arc.
Which one is chosen and is it implementation/manufacturer dependent?
According to CNCCookbook's G-code Tutorial, it depends on the controller. Some controller use the sign of the radius to choose, some never lets you make an arc of more than 90°.
Given the two choices shown, the controller chooses the path based on the sign of the radius. Negative forces the longer arc, positive the shorter. The negative sign forces the controller to seek a viable arc of more than 180 degrees.
Some controllers are touchier still and will not program an arc that crosses a quadrant line. Hence, the largest angle an arc can follow is 90 degrees, and that angle must not cross 0, 90, 180, or 270 degrees. For angles of 90 degrees that cross a quadrant line, they must be broken into two pieces, with the join between the pieces being right on the quadrant line.

How to determine if sphere is in front of plane

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.

Intersection between two Arcs? (arc = distance between pair of angles)

I'm trying to find a way to calculate the intersection between two arcs.
I need to use this to determine how much of an Arc is visually on the right half of a circle, and how much on the left.
I though about creating an arc of the right half, and intersect that with the actual arc.
But it takes me wayyy to much time to solve this, so I thought about asking here - someone must have done it before.
Edit:
I'm sorry the previous illustration was provided when my head was too heavy after crunching angles. I'll try to explain again:
In this link you can see that I cut the arc in the middle to two halves, the right part of the Arc contains 135 degrees, and the left part has 90.
This Arc starts at -180 and ends at 45. (or starts at 180 and ends at 405 if normalized).
I have managed to create this code in order to calculate the amount of arc degrees contained in the right part, and in the left part:
f1 = (angle2>270.0f?270.0f:angle2) - (angle1<90.0f?90.0f:angle1);
if (f1 < 0.0f) f1 = 0.0f;
f2 = (angle2>640.0f?640.0f:angle2) - (angle1<450.0f?450.0f:angle1);
if (f2 < 0.0f) f2 = 0.0f;
f3 = (angle2>90.0f?90.0f:angle2) - angle1;
if (f3<0.0f) f3=0.0f;
f4 = (angle2>450.0f?450.0f:angle2) - (angle1<270.0f?270.0f:angle1);
if (f4<0.0f) f4=0.0f;
It works great after normalizing the angles to be non-negative, but starting below 360 of course.
Then f1 + f2 gives me the sum of the left half, and f3 + f4 gives me the sum of the right half.
It also does not consider a case when the arc is defined as more than 360, which may be an "error" case.
BUT, this seems like more of a "workaround", and not a correct mathematical solution.
I'm looking for a more elegant solution, which should be based on "intersection" between two arc (because math has no "sides", its not visual";
Thanks!!
I think this works, but I haven't tested it thoroughly. You have 2 arcs and each arc has a start angle and a stop angle. I'll work this in degrees measured clockwise from north, as you have done, but it will be just as easy to work in radians measured anti-clockwise from east as the mathematicians do.
First 'normalise' your arcs, that is, reduce all the angles in them to lie in [0,360), so take out multiples of 360deg and make all the angles +ve. Make sure that the stop angle of each arc lies to clockwise of the start angle.
Next, choose the start angle of one of your arcs, it doesn't matter which. Sort all the angles you have (4 of them) into numerical order. If any of the angles are numerically smaller than the start angle you have chosen, add 360deg to them.
Re-sort the angles into increasing numerical order. Your chosen start angle will be the first element in the new list. From the start angle you already chose, what is the next angle in the list ?
1) If it is the stop angle of the same arc then either there is no overlap or this arc is entirely contained within the other arc. Make a note and find the next angle. If the next angle is the start angle of the other arc there is no overlap and you can stop; if it is the stop angle of the other arc then the overlap contains the whole of the first arc. Stop
2) If it is the start angle of the other arc, then the overlap begins at that angle. Make a note of this angle. The next angle your sweep encounters has to be a stop angle and the overlap ends there. Stop.
3) If it is the stop angle of the other arc then the overlap comprises the angle between the start angle of the first arc and this angle. Stop.
This isn't particularly elegant and relies on ifs rather more than I generally like but it should work and be relatively easy to translate into your favourite programming language.
And look, no trigonometry at all !
EDIT
Here's a more 'mathematical' approach since you seem to feel the need.
For an angle theta in (-pi,pi] the hyperbolic sine function (often called sinh) maps the angle to an interval on the real line in the interval (approximately) (-11.5,11.5]. Unlike arcsin and arccos the inverse of this function is also single-valued on the same interval. Follow these steps:
1) If an arc includes 0 break it into 2 arcs, (start,0) and (0,stop). You now have 2, 3 or 4 intervals on the real line.
2) Compute the intersection of those intervals and transform back from linear measurement into angular measurement. You now have the intersection of the two arcs.
This test can be resumed with a one-line test. Even if a good answer is already posted, let me present mine.
Let assume that the first arc is A:(a0,a1) and the second arc is B:(b0,b1). I assume that the angle values are unique, i.e. in the range [0°,360°[, [0,2*pi[ or ]-pi,pi] (the range itself is not important, we will see why). I will take the range ]-pi,pi] as the range of all angles.
To explain in details the approach, I first design a test for interval intersection in R. Thus, we have here a1>=a0 and b1>=b0. Following the same notations for real intervals, I compute the following quantity:
S = (b0-a1)*(b1-a0)
If S>0, the two segments are not overlapping, else their intersection is not empty. It is indeed easy to see why this formula works. If S>0, we have two cases:
b0>a1 implies that b1>a0, so there is no intersection: a0=<a1<b0=<b1.
b1<a0 implies that b0<b1, so there is no intersection: b0=<b1<a0=<a1.
So we have a single mathematical expression which performs well in R.
Now I expand it over the circular domain ]-pi,pi]. The hypotheses a0<a1 and b0<b1 are not true anymore: for example, an arc can go from pi/2 to -pi/2, it is the left hemicircle.
So I compute the following quantity:
S = (b0-a1)*(b1-a0)*H(a1-a0)*H(b1-b0)
where H is the step function defined by H(x)=-1 if x<0 else H(x)=1
Again, if S>0, there is no intersection between the arcs A and B. There are 16 cases to explore, and I will not do this here ... but it is easy to make them on a sheet :).
Remark: The value of S is not important, just the signs of the terms. The beauty of this formula is that it is independant from the range you have taken. Also, you can rewrite it as a logical test:
T := (b0>a1)^(b1>a0)^(a1>=a0)^(b1>=b0)
where ^ is logical XOR
EDIT
Alas, there is an obvious failure case in this formula ... So I correct it here. I realize that htere is a case where the intersection of the two arcs can be two arcs, for example when -pi<a0<b1<b0<a1<pi.
The solution to correct this is to introduce a second test: if the sum of the angles is above 2*pi, the arcs intersect for sure.
So the formula turns out to be:
T := (a1+b1-a0-b0+2*pi*((b1<b0)+(a1<a0))<2*pi) | ((b0>a1)^(b1>a0)^(a1>=a0)^(b1>=b0))
Ok, it is way less elegant than the previous one, but it is now correct.

Equation to calculate new object velocity(angle specifically) after reflection?

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

XNA 2D vector angles - what's the correct way to calculate?

what is in XNA in 2D the standard way vector angles work ?
0 degrees points right, 90 points up, 180 left, 270 down ?
What are the 'standard' implementations of
float VectortoAngle(Vector2 vec)
and
Vector2 AngleToVector(float angle)
so that VectortoAngle(AngleToVector(PI)) == PI ?
To answer your first question, 0 degrees points up, 90 degrees points right, 180 degrees points down, and 270 degrees points left. Here is a simple 2D XNA rotation tutorial to give you more information.
As for converting vectors to angles and back, I found a couple good implementations here:
Vector2 AngleToVector(float angle)
{
return new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
}
float VectorToAngle(Vector2 vector)
{
return (float)Math.Atan2(vector.Y, vector.X);
}
Also, if you're new to 2D programming, you may want to look into Torque X 2D, which provides a lot of this for you. If you've payed to develop for XNA you get the engine binaries for free, and there is a utility class which converts from angles to vectors and back, as well as other useful functions like this.
Edit: As Ranieri pointed out in the comments, that function doesn't make sense when up is 0 degrees. Here's one that does (up is (0, -1), right is (1, 0), down is (0, 1), left is (-1, 0):
Vector2 AngleToVector(float angle)
{
return new Vector2((float)Math.Sin(angle), -(float)Math.Cos(angle));
}
float VectorToAngle(Vector2 vector)
{
return (float)Math.Atan2(vector.X, -vector.Y);
}
I would also like to note that I've been using Torque for a while, and it uses 0 degrees for up, so that's where I got that part. Up meaning, in this case, draw the texture to the screen in the same way that it is in the file. So down would be drawing the texture upside down.
There is no convention for which direction a certain angle represents in XNA, so you can just define it however you like.
I'm not sure when the last time I used angles in a game was. In almost every case it's easier to work directly with vectors, if a little less intuitive to begin with.

Resources