How to find angle of reflected Ray to match a Point - math

this is for a Tank game I am making
Please see pic for a clear idea :link text
I want to precompute the exacte angle to hit Point T2.
T1:point start
T2:point Target
V1(a,b):line
reflect point : this is what I m looking for :)
Edit:it would be cool to see some "Code" :p

It'd be useful to see what happens to lines/vectors during reflection. Wikipedia provides a nice picture for this:
Where, in this picture, in a proper reflection, both angles are the same.
Now, what does that have to do with you? Let's take a look again at your situation.
Note that, due to the laws of reflection, the angles a and b are equal. That's good for us, because if we know that, we know c and d are also equal! (They are right triangles)
So we know:
a = b
c = d
We soon realize that we have similar triangles. Meaning, the corresponding sides are proportional to eachother. Meaning, mathematically:
A / C = B / D
A / B = C / D
A / (A+B) = B / (A+B) = C / P = D / P
So, if you know A and B, which you should, you can find your reflection point by adding C to the x value of the intersection.
You can find C this way:
Given:
A (distance from shooting tank to wall)
B (distance from target tank to wall)
P (x distance between points)
Find:
C (x distance from shooting tank where wall is to be hit)
A / (A+B) = C / P
C = A*P / (A+B) <- here it is
For example, if your first tank is at (1,5) and your second tank is at (3,7), and your wall is the x axis:
A = 5
B = 7
P = 3-1 = 2
therefore:
C = 5*2 / (5+7)
= 10/12
= 5/6
So your tank should shoot towards (0,5/6) if it wants to hit a tank at (3,7).
For a more general solution:
if the wall is the X axis, and you have shooting tank at (s_x,s_y)
and hit tank at (h_x,h_y), the point to be shot at is:
[ s_x + s_y * (h_x-s_x) / (h_y + s_y), 0 ]
Alternative, with arbitrary wall placement/direction
The problem with the above solution is that your wall has to be your x axis. What if it's not?
First, you need to find the distance from each point to the wall -- A and B:
Find w, which is the unit vector in the direction of the wall.
From w, find v, which is the unit vector perpendicular to the wall. If w = [x,by], v = [-y,x].
Find r_s, which is the vector from your shooting tank to any known point on your wall.
Find r_h, which is the vector from your hit tank to any known point on your wall.
The distance A = | v . r_s |, where . is the dot product operator. This can be found by [l,m] . [n,o] = l*n + m*o
The distance B = | v . r_h |
Once you find A and B, find P, which is the distance parallel to the wall. To do that:
Find q, which is the vector from the hit tank to the shooting tank
The distance P = | w . q |
Now that you have A, B, and P, you have two ways to go:
Find the point on the wall to aim for, by first solving for C in the method above and then finding the intersection of v starting from your shooting tank and your wall, and adding C*w to that intersection point.
You can find the angle (from v) that you must shoot, and it's the inverse tangent of P/(A+B).

Reflect T2 on the other side of V1, using V1 as the axis of reflection (we'll call this new point T2'); The line between T1 and T2' will intersect V1 at the point you want. From that point it's a matter of simple trigonometry to figure out what any angles are.
http://en.wikipedia.org/wiki/Transformation_%28geometry%29#Reflection

Related

Calculate circle center (3D) from 2 point, arc angle and plane normal

I need to calculate a 3D circle center point from 2 points(3D) and arc angle (plane normal is also known).
I searched it with Google but I think my English is not good enough to search properly. Anyone know the calculations to do this?
We have points A, B, normal N, angle Fi.
Calculate difference vector (arc chord) and middle point
AB = B - A
M = (A + B) / 2
Calculate vector F perpendicular to AB and N using vector product and normalize it
F = AB x N
uF = F / len(F)
We know that circle center C lies on the ray from point M with direction F (with parameter t equal to apothem CM length (center-chord distance))
C = M + t * uF
What should be t value? We can express t through right triangle AMC parameters
tan(Fi/2) = 0.5*len(AB) / t
So finally center is
C = M + uF * 0.5*len(AB) / tan(Fi/2)
Note that center C is not unique because we don't know arc direction (just change sign before uF in the last formula and get mirror point C' against chord)

Finding out if a point is within a line with a given width

I'm a little lost on the math aspect if what I need to do.
I have 3 points: Point A, Point B, Point C.
I need to find out if point C is on the line segment from Point A to Point B. But... the caveat is that I at the same time need to make the line "wider" from Point A to B.
I'm guessing I need to first create a bounding box that surrounds A->B? Then check if I'm within the bounding box?
How do I go about creating that box..
A and B can negative or positive on the grid, and the "distance" of the box is changeable as well.
I'm hoping this picture illustrates it better. The distance is the total given, so half would go 1 direction, half the other.
Even if I can just get those 4 points of the box, I can do the simple check to see if C is within.
Define u = normalize(b - a) and v = (-u.y, u.x).
Your point c is inside the line segment from a to b of width w if and only if both of the following hold:
0 <= dot(c - a, u) <= length(b - a)
abs(dot(c - a, v)) < w / 2
You have to (web picture with another point names P0=A, P1=B, P=C):
1) make orthogonal projection of C onto AB line (point D)
2) find distance CD and check if it is less than half-width
3) check that D lies between A and B (inside the segment)
for 2: distance d = |AC x uAB| - norm of cross product of AC vector and unit direction vector uAB = AB/|AB|
for 3: true if DotProduct(AC, AB) >= 0 and DotProduct(BC, BA) >= 0
Here you have all necessary formulas https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
First you find shortest distance btw point C and the line and check that it is less equal that width/2. Then you find coordinates of point D - closest to C point on the line and check that this point is between A and B. Than can be done by checking that distance(A,D) + distance(B,D) == distance( A,B )

Find a point along an angled line

I'm trying to figure out how to find a point along a line (half way, to be precice).
I need this to put a particle emitter in the correct location to leave a smoke-trail after bullets.
I've got point A and point C. Point A is the barrel-muzzle, and point C is found using ray-cast. Now, in order to put the emitter in the right location I need to find point D. How do one do this? I attached a picure to make it more visual.
No, I could not attach the picture, but here's a link.
Thanks in advance.
-Pimms
If your point is half way along a line between two points then you can just average their x and y co-ordinates to get the x and y for the midpoint (works in any number of dimensions).
If you want a point a certain proportion (ie 1/10th) along then you would do 1/10th of one point plus 9/10th of the other point.
In your example Point D is mid way between point A and C. This means the co-ordinates of D would be:
X = (0+10)/2 = 5
Y = (0+7)/2 = 3.5
Do I get you right? D is halfway between A and C ?
Solution:
D = (A + C) / 2
or:
D.x = (A.x + C.x) / 2
D.y = (A.y + C.y) / 2

Minimal perpendicular vector between a point and a line

Okay so I'm trying to get a separating axis theorem algorithm to work (for collision detection) and I need to find the minimal perpendicular vector between a point and a line. I'm not asking for the minimum perpendicular distance (which I know how to find) but rather the vector that would have the same magnitude as that distance and that goes from an arbitrary point and a point on the line. I know the location of the point, a point on the line, and a unit vector giving the direction of the line.
What I tried doing was first finding the minimal distance between the point and the line.
The next part is confusing but I:
1) Found the vector between the point and the point on the line I know
2) Found the vector between the point on the line and the point on the line plus the unit vector giving the direction of the line
3) Took the cross product of these two vectors (I'll call this cross product A)
4) Took the cross product of the unit vector giving the direction of the line and the vector from cross product A (I'll call this cross product B)
5) Normalized cross product B
6) Scaled cross product B by the minimal distance
Anyways that whole attempt failed miserably. Can anyone tell me how I am supposed to find this vector?
If I understood your question correctly, I believe this is what you're looking for:
P - point
D - direction of line (unit length)
A - point in line
X - base of the perpendicular line
P
/|
/ |
/ v
A---X----->D
(P-A).D == |X-A|
X == A + ((P-A).D)D
Desired perpendicular: X-P
where the period represents the dot product and |X-A| means magnitude.
From the above figure, you have:
q = p + s --> s = q - p = q - (p2-p1) = q + p1 - p2
==> s^ = |q - p2 - p1| / |s| (unitary vector)
Also: |s| = |q| sin c = |q|sin(b-a)
b = arcsin (qy / |q|); a = arcsin( p1y / |p1| )
where: |q| = (qx^2 + qy^2)^1/2

comparing two angles

Given four points in the plane, A,B,X,Y, I wish to determine which of the following two angles is smaller ∢ABX or ∢ABY.
The angle ∢ABX is defined as the angle of BX, when AB is translated to lie on the open segment (-∞,0]. Intuitively when saying ∢ABX I mean the angle you get when you turn left after visiting vertex B.
I'd rather not use cos or sqrt, in order to preserve accuracy, and to minimize performance (the code would run on an embedded system).
In the case where A=(-1,0),B=(0,0), I can compare the two angles ∢ABX and ∢ABY, by calculating the dot product of the vectors X,Y, and watch its sign.
What I can do in this case is:
Determine whether or not ABX turns right or left
If ABX turns left check whether or not Y and A are on the same side of the line on segment BX. If they are - ∢ABX is a smaller than ABY.
If ABX turns right, then Y and A on the same side of BX means that ∢ABX is larger than ∢ABY.
But this seems too complicated to me.
Any simpler approach?
Here's some pseudocode. Doesn't detect the case when both angles are the same. Also doesn't deal with angle orientation, e.g. assumes all angles are <= 180 degrees.
v0 = A-B
v1 = X-B
v2 = Y-B
dot1 = dot(v0, v1)
dot2 = dot(v0, v2)
if(dot1 > 0)
if(dot2 < 0)
// ABX is smaller
if(dot1 * dot1 / dot(v1,v1) > dot2 * dot2 / dot(v2, v2) )
// ABX is smaller
// ABY is smaller
if(dot2 > 0)
// ABY is smaller
if(dot1 * dot1 / dot(v1,v1) > dot2 * dot2 / dot(v2,v2) )
// ABY is smaller
// ABX is smaller
Note that much of this agonizing pain goes away if you allow taking two square roots.
Center the origin on B by doing
X = X - B
Y = Y - B
A = A - B
EDIT: you also need to normalise the 3 vectors
A = A / |A|
X = X / |X|
Y = Y / |Y|
Find the two angles by doing
acos(A dot X)
acos(A dot Y)
===
I don't understand the point of the loss of precision. You are just comparing, not modifying in any way the coordinates of the points...
You might want to check out Rational Trigonometry. The ideas of distance and angle are replaced by quadrance and spread, which don't involve sqrt and cos. See the bottom of that webpage to see how spread between two lines is calculated. The subject has its own website and even a youtube channel.
I'd rather not use cos or sqrt, in order to preserve accuracy.
This makes no sense whatsoever.
But this seems too complicated to me.
This seems utterly wrong headed to me.
Take the difference between two vectors and look at the signs of the components.
The thing you'll have to be careful about is what "smaller" means. That idea isn't very precise as stated. For example, if one point A is in quadrant 4 (x-component > 0 and y-component < 0) and the other point B is in quadrant 1 (x-component > 0 and y-component > 0), what does "smaller" mean? The angle of the vector from the origin to A is between zero and π/2; the angle of the vector from the origin to B is between 3π/4 and 2π. Which one is "smaller"?
I am not sure if you can get away without using sqrt.
Simple:
AB = A-B/|A-B|
XB = X-B/|X-B|
YB = Y-B/|Y-B|
if(dot(XB,AB) > dot (YB,AB)){
//<ABY is grater
}
else
{
...
}
Use the law of cosines: a**2 + b**2 - 2*a*b*cos(phi) = c**2
where a = |ax|, b =|bx| (|by|), c=|ab| (|ay|) and phi is your angle ABX (ABY)

Resources