how to get new coordinates with width, length and angle known? - algorithm

I have trapezoid with three coordinates known. So I need to create 4th coordinate with length, width and angles I am having. You can assume this problem with triangle as ADC from trapezoid. The model comes as differently expected . The Law of cosines gives the angle but it should be applied to local coordinates of the model. Right side I am showing with arrow pointed as wrong object which i am getting. Even if I rotate the object or flip it, the coordinates should not get wrong.
newWidth2 is AB. newLength is AD. Point C need to be created from A,D with angle D. Math.Pow is "to the power of" and 2 is it's square.(for who can't understand this notation).
Assume that I dont have coordinates of C. I know only A,D coordinates. I know length of AD, Width2 and Width1. I can get angle ADC from initial coordinates of C where coordinates of C will vary when I change Width2 of DC. So coordinates of C will be based on length of AD, angle D and so on. Finally what I need is coordinates of C if the entire object is rotated in any angle.
newWidth2 is AB.
newLength is AD.
Point C need to be created from A,D with angle A or angle D also.
Math.Pow is "to the power of" and 2 is it's square.(for who can't understand this notation).
//Initially I will have Coordinates for C but later I should remove them and create from the model width and heights. So I can't take input as C Coordinates of (X3,Y3) which I already have.
//distance formula
newWidth2 = Math.Sqrt(Math.Pow(CoordX3 - CoordX5, 2) + Math.Pow(CoordY3 - CoordY5, 2));
//from the formula -> b2 = a2 + c2 - 2acCos(B)
diagangle = Math.Acos((Math.Pow(newWidth2, 2) - Math.Pow(newdiagonal, 2) - Math.Pow(newLength, 2)) / (-2 * (newdiagonal) * (newLength)) );
//I am getting this C coordinates as wrong.
//for getting C (third coordinates)
xcoord3 = CoordX5 + (newWidth2 * Math.Cos(diagangle));
ycoord3 = CoordY5 + (newWidth2 * Math.Sin(diagangle));
//sample values of one model
Width1 36
Width2 24
Length 88.0783
A
CoordX1 43.944
CoordY1 409.2514
B
CoordX2 46.9337
CoordY2 373.3758
C
CoordX3 133.7111
CoordY3 392.6488
D
CoordX4 131.718
CoordY4 416.5659

It is not clear what exactly is known and what is to be found. I assume that you know coordinates of A, B, C and length AB = width1 and CD = width2 and need to find coordinates of D.
I think this problem is easier to solve if you see it as a vector problem rather than a trigonometry problem. If you look at vectors BA and CD you may see that they are collinear and |BA| = width1 while |CD| = width2. It means that vector CD = width2/width1 * BA. Not you can trivially calculate the coordinates of D by:
Calculating vector BA
Calculating CD = width2/width1 * BA
Calculating D = C + CD

Related

How can I find the coordinates of the resulting vector so that I can display it on an image?

I try to calculate and display a point on an image. Suppose I have the following points:
A = (x1, y1)
B = (x2, y2)
C = (x3, y3)
I want to calculate the coordinates of the resulting vector between the vectors AB and AC. What I thought:
AB=(x2-x1,y2-y1)
AC=(x3-x1,y3-y1)
and the resulting vector would be
AD(for example)=(((x2-x1)+(x3-x1)),((y2-y1)+(y3-y1)))
I'm not sure I thought well mathematically, but my biggest problem is that the result does not match the image, the coordinates can give negative numbers after this calculation. How can I find the coordinates of the resulting vector so that I can display it on an image?
I also added a small image, to better understand what I'm trying to say:
What you are doing is essentially adding two vectors, AD = AC + AB. So your image is correct if that is what you want to do. As for the negative numbers this depends on what your vectors are. The vector will be negative if it goes opposite the positive directions of your coordinate system.
Added an image to show how the vector AD is made graphically:
I recommend checking out some basic vector operations
EDIT: found similar topics:
How to get the vector between two vectors?
Hmm so if I see it right you want something between mirror and projection ... As there is probably no guarantee than AB and AC are symmetrical ...
I would try this using vector math:
ba = A-B
bc = C-B
E = B + bc* dot(ba,bc)/(|bc|^2)
D = E + (E-A)
D = 2.0*E - A
D = 2.0*(B + bc* dot(ba,bc)/(|bc|^2)) - A
Where dot(a,b)=a.x*b.x+a.y*b.y is scalar multiplication and |a|^2=(a.x*a.x)+(a.y*a.y) is vector size squared
So the E is perpendicular projection of A onto BC and D is mirror reflection of A around E and BC ...

Find tangent points in a circle from a point

Circle center : Cx,Cy
Circle radius : a
Point from which we need to draw a tangent line : Px,Py
I need the formula to find the two tangents (t1x, t1y) and (t2x,t2y) given all the above.
Edit: Is there any simpler solution using vector algebra or something, rather than finding the equation of two lines and then solving equation of two straight lines to find the two tangents separately? Also this question is not off-topic because I need to write a code to find this optimally
Here is one way using trigonometry. If you understand trig, this method is easy to understand, though it may not give the exact correct answer when one is possible, due to the lack of exactness in trig functions.
The points C = (Cx, Cy) and P = (Px, Py) are given, as well as the radius a. The radius is shown twice in my diagram, as a1 and a2. You can easily calculate the distance b between points P and C, and you can see that segment b forms the hypotenuse of two right triangles with side a. The angle theta (also shown twice in my diagram) is between the hypotenuse and adjacent side a so it can be calculated with an arccosine. The direction angle of the vector from point C to point P is also easily found by an arctangent. The direction angles of the tangency points are the sum and difference of the original direction angle and the calculated triangle angle. Finally, we can use those direction angles and the distance a to find the coordinates of those tangency points.
Here is code in Python 3.
# Example values
(Px, Py) = (5, 2)
(Cx, Cy) = (1, 1)
a = 2
from math import sqrt, acos, atan2, sin, cos
b = sqrt((Px - Cx)**2 + (Py - Cy)**2) # hypot() also works here
th = acos(a / b) # angle theta
d = atan2(Py - Cy, Px - Cx) # direction angle of point P from C
d1 = d + th # direction angle of point T1 from C
d2 = d - th # direction angle of point T2 from C
T1x = Cx + a * cos(d1)
T1y = Cy + a * sin(d1)
T2x = Cx + a * cos(d2)
T2y = Cy + a * sin(d2)
There are obvious ways to combine those calculations and make them a little more optimized, but I'll leave that to you. It is also possible to use the angle addition and subtraction formulas of trigonometry with a few other identities to completely remove the trig functions from the calculations. However, the result is more complicated and difficult to understand. Without testing I do not know which approach is more "optimized" but that depends on your purposes anyway. Let me know if you need this other approach, but the other answers here give you other approaches anyway.
Note that if a > b then acos(a / b) will throw an exception, but this means that point P is inside the circle and there is no tangency point. If a == b then point P is on the circle and there is only one tangency point, namely point P itself. My code is for the case a < b. I'll leave it to you to code the other cases and to decide the needed precision to decide if a and b are equal.
Here's another way using complex numbers.
If a is the direction (a complex number of length 1) of the tangent point on the circle from the centre c, and d is the (real) length along the tangent to get to p, then (because the direction of the tangent is I*a)
p = c + r*a + d*I*a
rearranging
(r+I*d)*a = p-c
But a has length 1 so taking the length we get
|r+I*d| = |p-c|
We know everything but d, so we can solve for d:
d = +- sqrt( |p-c|*|p-c| - r*r)
and then find the a's and the points on the circle, one of each for each value of d above:
a = (p-c)/(r+I*d)
q = c + r*a
Hmm not really an algorithm question (people tend to mistake algorithm and equation) If you want to write a code then do (you did not specify language nor what prevents you from doing this which is the reason of close votes)... Without this info your OP is just asking for math equation which is indeed off-topic here and by answering this I risk (right-full) down-votes too (but this is/was asked a lot here with much less info and 4 reopen votes against 1 close put my decision weight on reopen and answering this anyway).
You can exploit the fact that you are in 2D as in 2D perpendicular vectors to vector a(x,y) are computed like this:
c = (-y, x)
d = ( y,-x)
c = -d
so you swap x,y and negate one (which one determines if the perpendicular vector is CW or CCW). It is really a rotation formula but as we rotate by 90deg the cos,sin are just +1 and -1.
Now normal n to any circumference point on circle lies in the line going through that point and circles center. So putting all this together your tangents are:
// normal
nx = Px-Cx
ny = Py-Cy
// tangent 1
tx = -ny
ty = +nx
// tangent 2
tx = +ny
ty = -nx
If you want unit vectors than just divide by radius a (not sure why you do not call it r like the rest of the math world) so:
// normal
nx = (Px-Cx)/a
ny = (Py-Cy)/a
// tangent 1
tx = -ny
ty = +nx
// tangent 2
tx = +ny
ty = -nx
Let's go through derivation process:
As you can see, if the interior of the square is < 0 it's because the point is interior to the circumferemce. When the point is outside of the circumference there are two solutions, depending on the sign of the square.
The rest is easy. Take atan(solution) and be carefull here with the signs, you may better do some checks.
Use (2) and then undo (1) transformations and that's all.
c# implementation of dmuir's answer:
static void FindTangents(Vector2 point, Vector2 circle, float r, out Line l1, out Line l2)
{
var p = new Complex(point.x, point.y);
var c = new Complex(circle.x, circle.y);
var cp = p - c;
var d = Math.Sqrt(cp.Real * cp.Real + cp.Imaginary * cp.Imaginary - r * r);
var q = GetQ(r, cp, d, c);
var q2 = GetQ(r, cp, -d, c);
l1 = new Line(point, new Vector2((float) q.Real, (float) q.Imaginary));
l2 = new Line(point, new Vector2((float) q2.Real, (float) q2.Imaginary));
}
static Complex GetQ(float r, Complex cp, double d, Complex c)
{
return c + r * (cp / (r + Complex.ImaginaryOne * d));
}
Move the circle to the origin, rotate to bring the point on X and downscale by R to obtain a unit circle.
Now tangency is achieved when the origin (0, 0), the (reduced) given point (d, 0) and an arbitrary point on the unit circle (cos t, sin t) form a right triangle.
cos t (cos t - d) + sin t sin t = 1 - d cos t = 0
From this, you draw
cos t = 1 / d
and
sin t = ±√(1-1/d²).
To get the tangency points in the initial geometry, upscale, unrotate and untranslate. (These are simple linear algebra operations.) Notice that there is no need to perform the direct transform explicitly. All you need is d, ratio of the distance center-point over the radius.

place points with only distance matrix

I want to visualize some points, but only a distance matrix for them is given. It is there any good method to get one possible way to place them on 2D space.
Input: a distance matrix
Ouput: coordinates of these points
For a given matrix, if you come up with a possible placement, then any translation of the points will also satisfy the matrix, as will any rotation, and also mirroring.
For one possible placement:
Choose 3 points A B C (i.e. 3 rows from the matrix) that form a triangle with distances AB, AC and BC taken from the matrix. The points can't all lie on a line, so AB != AC + BC, AC != AB + BC and BC != AB + AC.
Place A at the origin and B at (AB, 0). Then use the Cosine rule to deduce the angle between the lines AB and AC:
angle = arccos((AB2 + AC2 - BC2) / (2 * AB * AC))
Now that you have the angle you can calculate the position of C:
C = (cos(angle) * AC, sin(angle) * AC);
You now have positions for A B and C. You can go through each of the other rows in the matrix corresponding to the other points, and find the distance between each point and A B and C. Then you can use this formula to work out the position of the point based on your assumed positions of A B C and the distance of the point to each:
Finding location of a point on 2D plane, given the distances to three other know points
So, you only actually need 3 values from each row of the matrix. For a large matrix, most of it is totally redundant. This might be helpful to you if you are trying to minimize storage space.
Remember that any translation, rotation and mirroring is also valid.

Efficient method to check if point is within a diamond

I have an array of diamonds as shown in the image and I know the position of every diamond and the distance from the origin of the diamond to any vertex (They are all the same distance from the center). I am also given a point. Given that information what is the most efficient method to find which diamond the point is in.
I know that I can just check the distance of the point from the position of every diamond but that seems way too cpu intensive as I have to do this multiple times.
Also, this shouldn't matter, but I am using C# and Unity 3D to do this.
If your diamonds form a regular pattern as in your picture, then just perform coordinate transformation to rotate the whole thing 45 degrees CW or CCW with (0, 0) as the origin. After that the problem becomes trivial: locating a point in a regular orthogonal grid.
Diamonds border line have equations
x + y = a0 + u * Size
y - x = b0 + v * Size
where a0, b0 are coordinates of the some vertex of base diamond (that has cell coordinates 0, 0), u and v are cell coordinates, Size is edge length. So to find what diamond point (px, py) belongs to, you can calculate
u = Floor((px + py - a0) / Size))
v = Floor((py - px - b0) / Size))

computational geometry - projecting a 2D point onto a plane to determine its 3D location

The following is what I am trying to figure out.
Question - Explain how you can project a 2D point onto a plane to create a 3D point.
I want to know how I would go about figuring this out. I have looked through a computational geometry book and looked for anything that may relate to what I'm trying to figure out. There was no information given along with the question about the computational geometry problem. The thing is I don't know anything about computational geometry< so figuring this out is beyond my knowledge.
Can anyone point me in the right direction?
If I understood this correctly you want to project points on the 2D plane onto a plane with a different orientation. I’m also going to assume that you are looking for the orthogonal projection (i.e. all points from the xy-plane are to be projected onto the closest point on the target plane).
So we have the equations of the two planes and the point we want to project:
The original 2D plane: z = 0, with the normal vector n1 = (0, 0, 1)
The target plane: ax + by + cz + d = 0 with the normal vector n2 = (a, b, c)
Point P: (e, f, 0) which obviously lies in the xy-plane
Now, we want to travel from point P in the direction of the normal of the target plane (because this will give us the closest point on the target plane). Hence we form an equation for the line which starts at point P, and which is parallel to the normal vector of the target plane.
Line L: (x,y,z) = (e,f,0) + t(a,b,c) = (e+ta, f+tb, tc) , where t is a real valued parameter
Next, we want to find a point on the line L which also lies on the target plane. Hence, we plug the line equation into the equation for the target plane and receive:
a(e+ta) + b(f+tb) + c * tc + d= 0
ae + bf + d + t(a2 + b2 + c 2) = 0
t = - (ae + bf + d) / (a2 + b2 + c 2)
hence the projected point will be:
Pprojected = (e + ka, f + kb, kc), where k = - (ae + bf + d) / (a2 + b2 + c 2)
With all the variables in the solution about, it might be a bit hard to grasp if you are new to the area. But really, it is rather simple. The things you have to learn are:
The standard equation for a plane: ax + by + cz + d = 0
How to extract the normal vector from the equation of the plane
What the normal vector is (a vector which is perpendicular to all position vectors in the plane)
The parametric representation of a line: (x, y, z) = u + t*v* , where u is a point which lies on the line, t is a real valued parameter and v is a vector parallel to the line.
The understanding that the closest path between a point and a plane will be parallel to the normal of the plane
If you grasped the above concepts, computing the projection is simple:
Compute the normal vector of the target plane. Starting from the point that you want to project, travel parallel to the computed normal vector until you reach the plane.

Resources