Get angle of unknown end point of a line - c++

Short Version:
Basically, I'm trying to figure out the X and Y values of an unknown Point C using the ending point of Line AB ( Point B ).
I tried using atan2( B.y, B.x) but it gives me the angle respective to the X-Axis which leads to wrong coordinates. I figured that I needed to get the angle formed by Line BC and the imaginary horizontal axis in which Point B lies ( Angle P ). Is there a way to obtain that angle? If getting that angle would not do what I want to do, what would?
Long Version:
I'm trying to do some math using C++ and I got stuck with this certain problem.
I have two vectors, Vector A and Vector B ( illustrated by Point A and Point B and they form the line AB ). Now, I want to get Vector C ( Point C ), which is L units away from Vector B ( illustrated by Line BC ).
I searched around, read some books, and got this formula to get the point that I need.
/* Let:
* L = length from B to C
* ( B.x, B.y ) = start point
* ( C.x, C.y ) = end point
* theta = angle respective to X-Axis ( using atan2( B.y, B.x ) )
*/
// To get C.x use formula cos( theta ) = ( C.x - B.x ) / L then derive
C.x = ( L * cos( theta ) ) + B.x;
// To get C.y use formula sin( theta ) = ( C.y - B.y ) / L then derive
C.y = ( L * sin( theta ) ) + B.y;
However, this does not result into Point C as illustrated above because the resulting C will be respective to the X-Axis. After reading some more, I figured out that I need to get the angle ( illustrated by purple Angle P ) between the Line BC ( pale red line ) and the imaginary horizontal axis ( teal line ) in which Point B lies.
Another example:
In this case, using the formula above would result to C being in the wrong place ( above ( X , 5 ) )
I am not sure if getting Angle P would do what I want, if you know a much more appropriate answer, please do so.

You don't need trig for this. It's simple proportions. I handy rule I found is that if you find yourself using sin, cos and atan2 then you're probably doing it wrong.
Here's how to do it without trig
dx = B.x - A.x;
dy = B.y - A.y;
dist = sqrt(dx*dx + dy*dy);
C.x = B.x + L*(dx/dist);
C.y = B.y + L*(dy/dist);

The first thing to do to is to create a tempB as if A was the origin(so you can find angle of B to A and so forth).
Subtract A's values from B.
tempB.x = B.x - A.x
tempB.y = B.y - A.y
Then you can use atan2 along with sin/cos (your formulas) to obtain C.x and C.y.
theta = atan2(tempB.y, tempB.x)
C.x = ( L * cos( theta ) ) + B.x;
C.y = ( L * sin( theta ) ) + B.y;
Another alternative is to obtain the unit vector of tempB.
magnitude = sqrt( pow(tempB.x,2) + pow(tempB.y,2))
unit.x = tempB.x/magnitude
unit.y = tempB.y/magnitude
Multiplying this unit vector by L gives you the offset from B.
C.x = B.x + unit.x * L
C.y = B.y + unit.y * L

What you need (in vector terms) is C = B + L*normalize(B-A). If you will be doing a lot more of this sort of calculation it would be worth using a vector library so that you can write your code exactly like that. Otherwise, You should use John's answer, which breaks down the same calculation into its elementary steps.
Edit: Here's a library you could use quite easily (it's just header files): GLM

Related

Checking if vector passes through vertices c++

How can I check if a vector that starts at one point passes through another one point?
It is on two-dimensional coordinates.
Mainly uses c ++, but other languages are possible.
float2 startToTarget = target - start;
if ((startToTarget.x) * vec.y - (startToTarget.y) * vec.x >= -floatingPoint && (startToTarget.x) * vec.y - (startToTarget.y) * vec.x <= floatingPoint)
if ((startToTarget.x) * vec.x + (startToTarget.y) * vec.y >= -floatingPoint && (startToTarget.x) * vec.x + (startToTarget.y) * vec.y <= floatingPoint) intersecting = true;
Calculate cross product of vector d (direction) and AB vector. If result is zero, then these vectors are collinear, so B point lies on the line, defined by point A and direction vector d.
To check direction, evaluate also dot product, it's sign is positive, when direction d coincides with direction AB
abx = B.x - A.x;
aby = B.y - A.y;
//cross product //dot product
if (abs(abx*dy - aby*dx) < 1.0e-10 and abx*dx + aby*dy>0)
{B lies on the ray A+d}

How to check if a point in a triangle (or on it's edge)

I'm trying to write an algorithm to determine if point is located inside a triangle or on it's edge in 3D coordinate space.
For example, I try to reach such results for different cases
I've figured out how to check if point P inside the triangle, I calculated normal vectors for triangles ABP, BCP, CAP and checked if they are similar.
Can someone explain how to check if a point is on the edge of a triangle (but not outside of a triangle)? You can provide formulas or code as you wish.
Make vectors:
r = p - A (r.x = p.x - A.x, r.y = p.y - A.y, r.z = p.z - A.z)
s = B - A
q = C - A
Calculate normal to ABC plane:
n = s x q (vector product)
Check if p lies in ABC plane using dot product:
dp = n.dot.r
If dp is zero (or has very small value like 1.0e-10 due to the floating point errors, then p is in the plane, and we can continue
Decompose vector p by base vectors s and q. At first check if z-component of normal (n.z) is non-zero. If so, use the next pair of equations (otherwise choose equations for x/z or y/z components):
px = a * sx + b * qx
py = a * sy + b * qy
Solve this system
a = (sy * qx - sx * qy) / (py * qx - px * qy)
b = (px - a * sx) / qx
If resulting coefficients a and b fulfill limits:
a >= 0
b >= 0
a + b <= 1.0
then point p lies in triangle plane inside it.

Verticalize Triangle

I have a triangle where two points have the same Z-Value and one has a different Value. Now I want to transform the point with the different Z-Value, so that it optically generates a "vertical" Triangle. Assuming point C is the one with the different height-Value, I somehow need to move the X and Y Coordinates of point C orthogonal to the Difference-Vector of A and B, until they vertically line up, e.g. the slope is exactly 90 degrees. But unfortunately, I am a complete idiot concerning rotations and stuff. Could you give me any hints how to solve that?
The code I need it for is written in C++, but a simple pseudo-code would be enough :)
But preferably a rather quick way, because it has to be called up to 700000 times per player, per chunk load
Let's say you have points A B C, and A.z == B.z, and z represents the vertical direction.
First, project the x,y co-ordinates of C onto the line between A and B in 2D:
// find normalized AB vector:
AB.x = B.x - A.x;
AB.y = B.y - A.y;
length = sqrt(AB.x * AB.x + AB.y * AB.y);
// test for length == 0 to avoid div by zero
AB.x /= length;
AB.y /= length; // note: you could save a division by dividing dot by length instead
// project C onto AB:
AC.x = C.x - A.x;
AC.y = C.y - A.y;
// this gives us how far along the line AB the projected point is:
dot = (AC.x * AB.x) * (AC.y * AB.y);
newC.x = A.x + (AB.x * dot);
newC.y = A.y + (AB.y * dot);
newC.z = A.z; // same as B.z
Next find the 3D distance between the projected point and C, which will be the vertical height above the AB line of the new point, if the triangle were rotated into a vertical position using AB as a hinge:
newCC.x = C.x - newC.x;
newCC.y = C.y - newC.y;
newCC.z = C.z - newC.z;
height = sqrt((newCC.x * newCC.x) + (newCC.y * newCC.y) + (newCC.z * newCC.z));
Set the z value:
newC.z += height;

Polar Rose 2D offset

I'm having some trouble trying to plot a polar rose with a offset C of the equation r(theta) = cos(k*theta) + C.
I'm trying to plot this polar rose: http://en.wikipedia.org/wiki/Polar_coordinate_system#/media/File:Cartesian_to_polar.gif
The polar equation can be:
r(theta) = cos(k * theta)
or
r(theta) = sin(k * theta)
The equation of the polar rose I want to draw is:
r(theta) = 2 + sin(6 * theta)
Ok, and the parametric equations will be:
x = C + sin(k * theta) * cos(theta)
y = C + sin(k * theta) * sin(theta)
In my Canvas(drawing area), my origin is not at the center of the screen, so I need to translate the rose to it. Ok, no big deal. Another point is that I need to scale the rose for it to be visible or it will be too small, but still no problem, this explains the: 100*. Here is my code, it is on C++ btw:
for ( float t = 0; t < PI_2; t+= 0.01 )
{
r = Origin.get_x() + 100*(2+(sin(6*t) * cos(t)));
h = Origin.get_y() + 100*(2+(sin(6*t) * sin(t)));
point(r,h);
}
I know that I'm doing it wrong, because when I add the +2 which should be the C constant is not working the way I want to, It's just translating more and drawing a polar rose without an offset. How do I prevent the "extra translation" and draw it properly?
x = r cos(theta), y = r sin(theta) so your parametric equations should be x(theta) = C * cos(theta) + sin(k*theta) * cos(theta) and y(theta) = C * sin(theta) + sin(k*theta) * sin(theta). You just forgot to multiply C by cos(theta) and by sin(theta) respectively.

Given two points and two vectors, find point of intersection [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you detect where two line segments intersect?
Given two points a and b plus two vectors v and u I want to find a third point c, which is the point of intersection in the following manner:
vector2 intersection(vector2 a, vector2 v, vector2 b, vector2 u)
{
float r, s;
a + r * v = b + s * u;
r * v - s * u = b - a
r * v.x - s * u.x = b.x - a.x
r * v.y - s * u.y = b.y - a.y
}
Is there any other way than using gaussian elimination to solve this system? Or is this the best (or at least an acceptable) way to handle this?
EDIT:
Definition of vector2
typedef union vector2
{
float v[2];
struct { float x, y; };
} vector2;
a and b are also of type vector2, because the only difference between a point and a vector is in the the way it is transformed by an affine transformation.
Looks like an assignment problem to me. Here is the logic that will help you write the code.
Let us call the first Ray as R0.
Locus of a point on R0 is defined as P:
P = P0 + alpha x V0
For the second ray R1:
P = P1 + beta x V1
Since they should intersect:
P0 + alpha x V0 = P1 + beta x V1
alpha and beta are unknowns and we have two equations in x any y.
Solve for the unknowns and get back the point of intersection.
i.e.,
P0.x + alpha * V0.x = P1.x + beta * V1.x
P0.y + alpha * V0.y = P1.y + beta * V1.y
solve for alpha and beta.
If there is a real positive solution for both alpha and beta, rays intersect.
If there is a real but at least one negative solution for both alpha and beta, extended rays intersect.
It's simple math.
But, first, check that you have intersection. If both vector are parallel you will fail to solve that:
// Edit this line to protect from division by 0
if (Vy == 0 && Uy == 0) || ((Vy != 0 && Uy != 0 && (Vx/Vy == Ux/Uy)) // => Fail.
Then (I won't show the calculation because they are long but the result is):
R = (AxUy - AyUx + ByUx - BxUy) / (VyUx - VxUy)
S = (Ax - Bx + RVx) / Ux
Hope that helped you.