Find angle between two points, respective to horizontal axis? - math

I have two points, one is always at the origin (0,0), and the other can be anywhere else in the world. I'd like to find the angle between them, respective to the horizontal axis.
| 2
| /
| /
| /
| /
|/ a
---1-------------- (horizontal axis)
|
a = angle (~50 degrees, counter clockwise)
In the above I would construct a right triangle and use sohcahtoa to figure out the missing angle I want, but it gets a bit ugly when the second point is in a different quadrant like in this case:
2 |
\ |
\ |
\ |
\a|a
\|a
---1--------------
|
|
a = angle (~135, counter clockwise)
I just end up with a bunch of different cases depending on what quadrant the second point is in. I'm thinking there must be a much simpler, general solution. This is kind of like trying to find the angle between a point on the edge of a circle and its center, respective to the origin's horizontal axis.
What's a good way to do this?

Most programming languages/APIs provide a function, atan2(), which finds the angle and takes the quadrant into consideration. Just use that.

First we would like to find the equation of the straight line that connects the two points:
Let p = (x0,y0) be the second point.
if x=0 than the answer is 90 deg.
otherwise let m be y0/x0.
y = m(x-x0) +y0
tg^-1 (that is arctg) of m is the angle.
also note that if (x0,y0) == (0,0) than the angle is undefined

Related

Calculation of X/Y Coordinates to Offset Y-Rotation of Neighbor

I have 2 Lines in 2D Space, defined by L1a/L1b and L2a/L2b, which have the same width (or Length of X) and for simplification Y=0. Both Lines have their rotation axis in their center.
Both lines share a point with the same coordinates, namely point L1b from Line 1 and point L2a from Line 2.
Illustration 1.
L1a-----R1-----L1b L2a-----R2-----L2b
Both lines are now being rotated on the Y axis using the same angle, for example 45 degrees.
Illustration 2.
L1a L2a
-- --
-- --
-R1- -R2-
-- --
-- --
L1b L2b
I'd like to know the necessary calculations to translate the 2 points of either of the lines (pick any you like, if it makes a difference) to make points L1b and L2a share the same coordinates again?
Illustration 3.
L1a
--
--
-R1-
--
--
L1b L2a
--
--
-R2-
--
--
L2b
I hope my illustrations make sense. Remember, L1b and L2a are supposed to have the same coordinates, which is not clearly visible in my illustrations.
Here is an example which doesn't require much mathematical skills.
All points are defined as: L*(x,y)
Example: Rotation y=90 degrees
L1a( 0,0); L1b(100,0)
L2a(100,0); L2b(200,0)
Step 1. Coordinates after rotation
L1a( 50,50); L1b( 50,-50)
L2a(150,50); L2b(150,-50)
Step 2. Translation for points of Line 1
x=100, y=100
Step 3. Final Coordinates
>>L1a(150,150); L1b(150, 50)<<
L2a(150, 50); L2b(150,-50)
I hope this makes sense. Thank you!
I'm sorry but you're description is a bit confusing. You state there is a center of rotation of both lines but the pictures and math both seem to conclude otherwise.
Assuming R1 and R2 the centers of rotation of the lines it sounds like you are just looking for a circular rotation of all 4 points. To accomplish this you need to do some trigonometry.
You are going to increment a counter that represents the angle of the point on the circle. Then:
x = radius * cos(angle)
y = radius * sin(angle)
let length=2r;
choose axis so that:
L1a=(-2r,0) L2a=L1b=(0,0) L2b=(2r,0)
centers are C1=(-r,0) C2=(r,0)
after rotation of x alpha clockwise:
L2a=( r*cos(x)-r , -r*sin(x) ) L1b=( -r*cos(x)+r , r*sin(x) )
So the translation will be:
( 2r-2r*cos(x) , 2r*sin(x) )

get uvw coordinates from pixel coordinates for ray-tracing

I'm trying to implement a simple ray-tracing algorithm
so the first step is to convert pixel coordinates into uvw coordinates system
iam using those two equations that i found in a book
where l,r,b,t are the view frustum points , (i,j) are the pixel indexes , (nx,ny) are the scene width and height
then to calculate canonical coordinate i use
i want to understand the previous equations and why they give uwv coordinates for perspective projection not for orthogonal projection (when i use orthogonal projection the equation still gives the result as if perspective projection is used)
Let's assume your camera is some sort of a pyramid. It has a bottom face which I'll refer to as the "camera screen", and the height of the pyramid, also known as the focal length, will be marked as F (or in your equations, Ws).
T(op)
*---------*
|\ /|
| \ / |
| \ / |
| \ / |
L(eft) | *E(ye| R(ight)
| / \ |
| / \ |
| / \ |
|/ \|
*---------*
B(ottom)
Let's assume j goes from the bottom to the top (from -Ny/2 to +Ny/2 in steps of 1/Ny), and i goes from left to right (from -Nx/2 to +Nx/2 in steps of 1/Nx). Note that if Ny is even, j goes up to Nx/2-1 (and similar when Nx is even).
As you go from bottom to top in the image, on the screen, you move from the B value to the T value. At the fraction d (between 0=bottom and 1=top) of your way from bottom to top, your height is
Vs = T + (B-T) * d
A bit of messing around shows that the fraction d is actually:
d = (j + 0.5) / Ny
So:
Vs = T + (B-T) * (j + 0.5) / Ny
And similarly:
Us = L + (R-L) * (i + 0.5) / Nx
Now, let's denote U as the vector going from left to right, V from bottom to top, 'W' going from the eye forward. All these vectors are normalized.
Now, assume the eye is located directly above (0,0) where that is exactly above the center of the rectangular face of the pyramid.
To go from the eye directly to (0,0) you would go:
Ws * W
And then to go from that point to another point on the screen at indexes (i,j) you would go:
Us * U + Vs * V
You will be able to see that Us = 0 for i = 0 and Vs = 0 for j = 0 (since B = -T and L = -R, as the eye is directly above the center of the rectangle).
And finally, if we compose it together, a point on the screen at indexes (i,j) is
S = E + Us * U + Vs * V + Ws * W
Enjoy!

Calculate the rotation performed around a point

I have two points in 2D space, centred on origin (0,0). The first point represents the starting location and the second represents the end location. I need to calculate the angle of rotation between the two points, my problem being that the hypoteneuse from each point to (0,0) is not equal.
Could someone tell me how to work out the angle between the two points, bearing in mind that they could be anywhere relative to (0,0).
Many thanks,
Matt.
Let's say point 1 is (x1,y1) and point 2 is (x2,y2)
The tangent of the Angle from X axis to point 1, relative to (0,0) is y1/x1
The tangent of the Angle from X axis to point 2, relative to (0,0) is y2/x2
Take the arc tangent (is that the right term? Tan-1 on a calculator) to get the actual angle for each, then subtract to get the answer you're looking for
This is easily accomplished taking the arccosine of the normalized inner product of the two vectors. That is, given u = (ux, uy) and v = (vx, vy), the angle between the two is given by θ = acos(u·v/|u||v|), where u · v = uxvx + uyvy is the dot product of the two and the | | operator is the l2 normal given by |u| = sqrt(ux2 + uy2). This will result in the smallest rotation that can be applied to one of the vectors that will make them linear multiples of each other. Therefore, you may need to fiddle with the sign of θ to make sure you're going in the right direction if you have one you want to start from.

Finding Whether A Point is Within a Right-Angle Triangle

I've always wondered the easiest way to figure out whether or not a point lies within a triangle, or in this instance, a rectangle cut into half diagonally.
Let's say I have a rectangle that is 64x64 pixels. With this rectangle, I want to return a TRUE value if a passed point is within the upper-left corner of the rectangle, and FALSE if it isn't.
-----
| /|
| / |
|<__|
Horray for bad ASCII art.
Anyway, the hypothetical points for this triangle that would return TRUE would be (0,0) and (63,0) and (0, 63). If a point lands on a line (e.g., 50,0) it would return TRUE as well.
Assuming 0,0 is in the upper-left corner and increases downwards...
I've had a possible solution in my head, but it seems more complicated than it should be - taking the passed Y value, determining where it would be in the rectangle, and figuring out manually where the line would cut at that Y value. E.g, a passed Y value of 16 would be quarter height of the rectangle. And thus, depending on what side you were checking (left or right), the line would either be at 16px or 48px, depending on the direction of the line. In the example above, since we're testing the upper-left corner, at 16px height, the line would be at 48px width
There has to be a better way.
EDIT:
The rectangle could also look like this as well
-----
|\ |
| \ |
|__>|
But I'm figuring in most cases the current answers already provided should still hold up...
Top-left/bottom-right triangles: For all points in the top-left triangle, x+y<=64. Points in the bottom-right triangle have x+y>64.
(for a rectangle of size (w,h) use w*y+h*x-w*h<0)
Top-right/bottom-left triangles: For all points in the bottom-left triangle, x<=y. Points in the top-right triangle have x>y.
(for a rectangle of size (w,h) use h*x-w*y<0)
How did we get there?
For a rectangle of dimensions (w,h) and TL/BR triangles, the equation of the diagonal is (try it out! assign x=0 and check that you get y==h, and assign y=0 and check that x==w)
h*x + w*y - w*h = 0
Points on one side of that line will have
h*x + w*y - w*h > 0
While points on the other will have
h*x + w*y - w*h < 0
Inserting 64 for both w and h, we get:
64x + 64y - 64*64 < 0
Dividing by 64 gets us:
x+y < 64
For TR/BL triangles, the line equation and the resulting inequalities are:
h*x - w*y = 0
h*x - w*y < 0
h*x - w*y > 0
Inserting 64 for w and h, we get
64x-64y < 0
=> x<y
you can represent the triangle with three affine functions
take the unit triangle with corners at (0, 0), (1, 0) and (1, 1). the sides are represented by the three lines
y = 0
x = 1
y = x
So the interior and boundry of the triangle are given as the intersection of the sets
x >= 1
y >= 0
y <= x
so given a point, (x, y), you just need to verify that it satisfies those three inequalities.
You can of course generalize this to any triangle using the fact that any affine function (representing a line) can be written in the form y = mx + b.
The equation for the line looks like this :
y = mx + b
So, if you insert your x and y-Values into that equation, it will probably not hold anymore. Let's reformulate it:
mx + b - y = 0
Same thing, different look. Again, the result is probably not zero. But, the result will now tell you whether it's on the one side of the line or the other.
Now you just have to find out whether the point is inside your rectangle.
Lets assume your right angled triangle has one corner at 0,0 and the diagonal corner at a,b.
So y=mx+c c=0 as we start at the origin.
m=b/a
So y=bx/a
To know which half of the triangle your point (c,d) falls in
if (d<=(bc/a)) {//point is in bottom half}
if (d>(bc/a)) {//point is in top half}
I think...
A simple option is to use a ray casting algorithm. Whilst perhaps a little overkill for what you need, it does have the advantage that it will work with more complex triangles and polygons.
Loosely, the algorithm takes an imaginary point in a direction (infinitely off to the left, for example) and casts a ray to your test point; you then calculate whether each line of your triangle crosses that infinitely long line. If you get an odd number of crossings, your point is inside your triangle; even and you're out of your triangle

formula for best approximation for center of 2D rotation with small angles

This is not a homework. I am asking to see if problem is classical (trivial) or non-trivial. It looks simple on a surface, and I hope it is truly a simple problem.
Have N points (N >= 2) with
coordinates Xn, Yn on a surface of
2D solid body.
Solid body has some small rotation (below Pi/180)
combined with small shifts (below 1% of distance between any 2 points of N). Possibly some small deformation too (<<0.001%)
Same N points have new coordinates named XXn, YYn
Calculate with best approximation the location of center of rotation as point C with coordinates XXX, YYY.
Thank you
If you know correspondence (i.e. you know which points are the same before and after the transformation), and you choose to allow scaling, then the problem is a set of linear equations. If you have 2 or more points then you can find a least-squares solution with little difficulty.
For initial points (xi,yi) and transformed points (xi',yi') you have equations of the form
xi' = a xi + b yi + c
yi' =-b xi + a yi + d
which you can rearrange into a linear system
A x = y
where
A = | x1 y1 1 0 |
| y1 -x1 0 1 |
| x2 y2 1 0 |
| y2 -x2 0 1 |
| ... |
| xn yn 1 0 |
| yn -xn 0 1 |
x = | a |
| b |
| c |
| d |
y = | x1' |
| y1' |
| x2' |
| y2' |
| ... |
| xn' |
| yn' |
the standard "least-squares" form of which is
A^T A x = A^T y
and has the solution
x = (A^T A)^-1 A^T y
with A^T as the transpose of A and A^-1 as the inverse of A. Normally you would use an SVD or QR decomposition to compute the solution as they ought to be more stable and less computationally intensive than the inverse.
Once you've found x (and so the four elements of the transformation a, b, c and d) then the various elements of the transformation are given by
scale = sqrt(a*a+b*b)
rotation = atan2(b,a)
translation = (c,d)/scale
If you don't include scaling then the system is non-linear, and requires an iterative solution (but isn't too difficult to solve). If you do not know correspondence then the problem is substantially harder, for small transformations something like iterated closest point works, for large transformations it's a lot harder.
Edit: I forgot to include the centre of rotation. A rotation theta about an arbitrary point p is a sequence
translate(p) rotate(theta) translate(-p)
if you expand it all out as an affine transformation (essentially what we have above) then the translation terms come to
dx = px - cos(theta)*px + sin(theta)*py
dy = py - sin(theta)*px - cos(theta)*py
we know theta (rotation), dx (c) and dy (d) from the equations above. With a little bit of fiddling we can solve for px and py
px = 0.5*(dx - sin(theta)*dy/(1-cos(theta)))
py = 0.5*(dy + sin(theta)*dx/(1-cos(theta)))
You'll notice that the equations are undefined if theta is zero, because there is no centre of rotation when no rotation is performed.
I think I have all that correct, but I don't have time to double check it all right now.
Look up the "Kabsch Algorithm". It is a general-purpose algorithm for creating rotation matrices using N known pairs. Kabsch created it to assist denoising stereo photographs. You rotate a feature in picture A to picture B, and if it is not in the target position, the feature is noise.
http://en.wikipedia.org/wiki/Kabsch_algorithm
See On calculating the finite centre of rotation for
rigid planar motion for a relatively simple solution. I say "relatively simple" because it still uses things like psuedo-inverses and SVD (singular value decomposition). And here's a wikipedia article on Instant centre of rotation. And another paper: ESTIMATION OF THE FINITE CENTER OF ROTATION IN PLANAR MOVEMENTS.
If you can handle stiffer stuff, try Least Squares Estimation of Transformation Parameters Between Two Point Patterns.
First of all, the problem is non-trivial.
A "simple" solition. It works best when the polygon resembles circle, and points are distributed evenly.
iterate through N
For both old and new dataset, find the 2 farthest points of the point N.
So now you have the triangle before and after the transformation. Use the clockwise direction from the center of each triangle to number its vertices as [0] (=the N-th point in the original dataset), [1], and [2] (the 2 farthest points).
Calculate center of rotation, and deformation (both x and y) of this triangle. If the deformation is more then your 0.001% - drop the data for this triangle, otherwise save it.
Calculate the average for the centers of rotation.
The right solution: define the function Err(Point BEFORE[N], Point AFTER[N], double TFORM[3][3]), where BEFORE - constant old data points, AFTER - constant new data points, TFORM[3][3] affine transformation matrix, Err(...) function that returns the scalar error value, 0.0 when the TFORM translated BEFORE to exact AFTER, or some >0.0 error value. Then use any numeric math you want to find the minimum of the Err(TFORM): e.g. gradient search.
Calculate polygon centers O1 and O2. Determine line formulae for O1 with (X0, Y0) and O2 with (XX0, YY0). Find intersection of lines to get C.
If I understand your problem correctly, this could be solved in this way:
find extremities (furthest points, probably on several axises)
scale either one to match
their rotation should now be trivial (?)
Choose any 2 points on the body, P1, P2, before and after rotation. Find vectors between these before and after points. Cross these vectors with a vector normal to the plane of rotation. This results in two new vectors, the intersection of the lines formed by the initial points and these two new vectors is the center of the rotation.
{
if P1after = P1before return P1after
if P2after = P2before return P2after
Vector V1 = P1after - P1before
Vector V2 = P2after - P2before
normal = Vn // can be messy to create for arbitrary 3d orientation but is simple if you know orientation, for instance, normal = (0,0,1) for an object in the x,y plane)
Vector VL1 = V1 x Vn //Vector V1 cross product with Vn
Vector VL2 = V2 x Vn
return intersectLines(P1after,VL1,P2after,VL2) //Center of rotation is intersection of two lines
}
intersectLines(Point P1, Vector V1, Point P2, Vector V2)
{
//intersect two lines using point, direction form of a line
//returns a Point
}

Resources