I have x,y data coming in from a [coordinates1] database (GIS - but this could be any database). I have my application with it's own coordinate system, referencing THE SAME MAP.
I have established that a linear relationship exists between coordinates1 (x,y) and coordinates2(x,y) as I have subtracted two different coordinates1 and coordinates2 (dividing x1 with x2 and y1 with y2) and in all cases I get them both showing 0.724 or 0.141 or 0.825 respectively i.e. coordinates1 + coordinates2.
What I now need to figure out - or you help - is that if coordinates1(100000,200000) and coordinates2(0.125,0.255) how do I calculate coordinates2(x,y) from the data in coordinates1(x,y)?
For the sake of clarity, I'm going to call coordinates in your base (xn, yn), and coordinates in your target (un, vn).
Now, if we assume:
The origins of the two coordinate systems are the same.
The orientation of the two coordinate systems are the same (i.e. one is not rotated with respect to the other).
In this case you only need one set of points {(x1, y1), (u1, v1)} to determine the location of (un, vn):
un = u1/x1 * xn
vn = v1/y1 * yn
Note: we must have x1 ≠ 0, y1 ≠ 0
On the other hand, if the two coordinate systems have different origins (but they are still not rotated with respect to one another), we will need two sets of points {(x1, y1), (u1, v1)} and {(x2, y2), (u2, v2)}:
un = (u2 - u1)/(x2 - x1) * (xn - x1) + u1
vn = (v2 - v1)/(y2 - y1) * (yn - y1) + v1
Note: we must have x1 ≠ x2, y1 ≠ y2
Now, if the two coordinate systems are rotated with respect to one another, you need (I believe) one more set of matching coordinates. But it doesn't sound like you need that (unless one of your maps has north pointing in a direction other than straight up), so I'm not going to work out the math now. :)
To do the conversion, you need to know the coordinates of one point O in your two coordinates systems .
Let's suppose O has coordinates x1O,y1O in coordinate system 1, and x2O,y2O in coordinate system 2.
Then a point with coordinates x1,y1 in system 1, and x2,y2 in system 2 will satisfy:
(x1O - x1) = Kx * (x2O - x2)
(y1O - y1) = Ky * (y2O - y2)
where Kx and Ky are the scale factor. If you know the coordinates of an other point M in both systems, than you will have Kx and Ky with
Kx = (x1O - x1M) / (x2O - x2M)
Ky = (y1O - y1M) / (y2O - y2M)
Then, you just need to apply the first relationship to go from one system to another system, with
x1 = x1O - Kx * (x2O - x2)
y1 = y10 - Ky * (y2O - y2)
or
x2 = x2O - (x1O - x1) / Kx
y2 = y2O - (y1O - y1) / Ky
Do you also need the code ?
Related
Hello again first part is working like a charm, thank you everyone.
But I've another question...
As I've no interface, is there a way to do the same thing with out not knowing the radius of the circle?
Should have refresh the page CodeMonkey solution is exactly what I was looking for...
Thank you again.
============================
First I'm not a developer, I'm a simple woodworker that left school far too early...
I'm trying to make one of my tool to work with an autonomous robot.
I made them communicate by reading a lot of tutorials.
But I have one problem I cant figure out.
Robot expect position of the tool as (X,Y) but tool's output is (A,B,C)
A is the distance from tool to north
B distance to east
C distance at 120 degree clockwise from east axe
the border is a circle, radius may change, and may or may not be something I know.
I've been on that for 1 month, and I can't find a way to transform those value into the position.
I made a test with 3 nails on a circle I draw on wood, and if I have the distance there is only one position possible, so I guess its possible.
But how?
Also, if someone as an answer I'd love pseudo code not code so I can practice.
If there is a tool to make a drawing I can use to make it clearer can you point it out to me?
Thank you.
hope it helps :
X, Y are coordinate from center, Da,Db, Dc are known.
Trying to make it more clear (sorry its so clear in my head).
X,Y are the coordinate of the point where is the tool (P).
Center is at 0,0
A is the point where vertical line cut the circle from P, with Da distance P to A;
B is the point where horizontal line cuts the circle fom P, with Db distance P to B.
C is the point where the line at 120 clockwise from horizontal cuts the circle from P, with Dc distance P to C.
Output from tool is an array of int (unit mm): A=123, B=114, C=89
Those are the only informations I have
thanks for all the ideas I'll try them at home later,
Hope it works :)
Basic geometry. I decided to give up having the circle at the origin. We don't know the center of the circle yet. What you do have, is three points on that circle. Let's try having the tool's position, given as P, as the new (0,0). This thus resolves to finding a circle given three points: (0, Da); (Db,0), and back off at 120° at Dc distance.
Pseudocode:
Calculate a line from A to B: we'll call it AB. Find AB's halfway point. Calculate a line perpendicular to AB, through that midpoint (e.g. the cross product of AB and a unit Z axis finds the perpendicular vector).
Calculate a line from B to C (or C to A works just as well): we'll call it BC. Find BC's halfway point. Calculate a line perpendicular to BC, through that midpoint.
Calculate where these two lines cross. This will be the origin of your circle.
Since P is at (0,0), the negative of your circle's origin will be your tool's coordinates relative to the circle's origin. You should be able to calculate anything you need relative to that, now.
Midpoint between two points: X=(X1+X2)/2. Y=(Y1+Y2)/2.
The circle's radius can be calculated using, e.g. point A and the circle's origin: R=sqrt(sqr((Ax-CirX)+sqr(Ay-CirY))
Distance from the edge: circle's radius - tool's distance from the circle's center via Pythagorean Theorem again.
Assume you know X and Y. R is the radius of the circle.
|(X, Y + Da)| = R
|(X + Db, Y)| = R
|(X - cos(pi/3) * Dc, Y - cos(pi/6) * Dc)| = R
Assuming we don't know the radius R. We can still say
|(X, Y + Da)|^2 = |(X + Db, Y)|^2
=> X^2 + (Y+Da)^2 = (X+Db)^2 + Y^2
=> 2YDa + Da^2 = 2XDb + Db^2 (I)
and denoting cos(pi/3)*Dc as c1 and cos(pi/6)*Dc as c2:
|(X, Y + Da)|^2 = |(X - c1, Y - c2)|^2
=> X^2 + Y^2 + 2YDa + Da^2 = X^2 - 2Xc1 + c1^2 + Y^2 - 2Yc2 + c2^2
=> 2YDa + Da^2 = - 2Xc1 + c1^2 - 2Yc2 + c2^2
=> Y = (-2Xc1 + c1^2 + c2^2 - Da^2) / 2(c2+Da) (II)
Putting (II) back in the equation (I) we get:
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da / (c2+Da) + Da^2 = 2XDb + Db^2
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da + Da^2 * (c2+Da) = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> (-2Xc1 + c1^2 + c2^2) Da + Da^2 * c2 = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> X = ((c1^2 + c2^2) Da + Da^2 * c2 - Db^2 * (c2+Da)) / (2Dbc2 + 2Db*Da + 2Dac1) (III)
Knowing X you can get Y by calculating (II).
You can also make some simplifications, e.g. c1^2 + c2^2 = Dc^2
Putting this into Python (almost Pseudocode):
import math
def GetXYR(Da, Db, Dc):
c1 = math.cos(math.pi/3) * Dc
c2 = math.cos(math.pi/6) * Dc
X = ((c1**2 + c2**2) * Da + Da**2 * c2 - Db * Db * (c2 + Da)) / (2 * Db * c2 + 2 * Db * Da + 2 * Da * c1)
Y = (-2*X*c1 + c1**2 + c2**2 - Da**2) / (2*(c2+Da))
R = math.sqrt(X**2 + (Y+Da)**2)
R2 = math.sqrt(Y**2 + (X+Db)**2)
R3 = math.sqrt((X - math.cos(math.pi/3) * Dc)**2 + (Y - math.cos(math.pi/6) * Dc)**2)
return (X, Y, R, R2, R3)
(X, Y, R, R2, R3) = GetXYR(123.0, 114.0, 89.0)
print((X, Y, R, R2, R3))
I get the result (X, Y, R, R2, R3) = (-8.129166703588021, -16.205081335032794, 107.1038654949096, 107.10386549490958, 107.1038654949096)
Which seems reasonable if both Da and Db are longer than Dc, then both coordinates are probably negative.
I calculated the Radius from three equations to cross check whether my calculation makes sense. It seems to fulfill all three equations we set up in the beginning.
Your problem is know a "circumscribed circle". You have a triangle define by 3 distances at given angles from your robot position, then you can construct the circumscribed circle from these three points (see Circumscribed circle from Wikipedia - section "Other properties"). So you know the diameter (if needed).
It is also known that the meeting point of perpendicular bisector of triangle sides is the center of the circumscribed circle.
Let's a=Da, b=Db. The we can write a system for points A and B at the circumference:
(x+b)^2 + y^2 = r^2
(y+a)^2 + x^2 = r^2
After transformations we have quadratic equation
y^2 * (4*b^2+4*a^2) + y * (4*a^3+4*a*b^2) + b^4-4*b^2*r^2+a^4+2*a^2*b^2 = 0
or
AA * y^2 + BB * y + CC = 0
where coefficients are
AA = (4*b^2+4*a^2)
BB = (4*a^3+4*a*b^2)
CC = b^4-4*b^2*r^2+a^4+2*a^2*b^2
So calculate AA, BB, CC coefficients, find solutions y1,y2 of quadratic eqiation, then get corresponding x1, x2 values using
x = (a^2 - b^2 + 2 * a * y) / (2 * b)
and choose real solution pair (where coordinate is inside the circle)
Quick checking:
a=1,b=1,r=1 gives coordinates 0,0, as expected (and false 1,-1 outside the circle)
a=3,b=4,r=5 gives coordinates (rough) 0.65, 1.96 at the picture, distances are about 3 and 4.
Delphi code (does not check all possible errors) outputs x: 0.5981 y: 1.9641
var
a, b, r, a2, b2: Double;
aa, bb, cc, dis, y1, y2, x1, x2: Double;
begin
a := 3;
b := 4;
r := 5;
a2 := a * a;
b2:= b * b;
aa := 4 * (b2 + a2);
bb := 4 * a * (a2 + b2);
cc := b2 * b2 - 4 * b2 * r * r + a2 * a2 + 2 * a2 * b2;
dis := bb * bb - 4 * aa * cc;
if Dis < 0 then begin
ShowMessage('no solutions');
Exit;
end;
y1 := (- bb - Sqrt(Dis)) / (2 * aa);
y2 := (- bb + Sqrt(Dis)) / (2 * aa);
x1 := (a2 - b2 + 2 * a * y1) / (2 * b);
x2 := (a2 - b2 + 2 * a * y2) / (2 * b);
if x1 * x1 + y1 * y1 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x1, y1]))
else
if x2 * x2 + y2 * y2 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x2, y2]));
From your diagram you have point P that you need it's X & Y coordinate. So we need to find Px and Py or (Px,Py). We know that Ax = Px and By = Py. We can use these for substitution if needed. We know that C & P create a line and all lines have slope in the form of y = mx + b. Where the slope is m and the y intercept is b. We don't know m or b at this point but they can be found. We know that the angle of between two vectors where the vectors are CP and PB gives an angle of 120°, but this does not put the angle in standard position since this is a CW rotation. When working with circles and trig functions along with linear equations of slope within them it is best to work in standard form. So if this line of y = mx + b where the points C & P belong to it the angle above the horizontal line that is parallel to the horizontal axis that is made by the points P & B will be 180° - 120° = 60° We also know that the cos angle between two vectors is also equal to the dot product of those vectors divided by the product of their magnitudes.
We don't have exact numbers yet but we can construct a formula: Since theta = 60° above the horizontal in the standard position we know that the slope m is also the tangent of that angle; so the slope of this line is tan(60°). So let's go back to our linear equation y = tan(60°)x + b. Since b is the y intercept we need to find what x is when y is equal to 0. Since we still have three undefined variables y, x, and b we can use the points on this line to help us here. We know that the points C & P are on this line. So this vector of y = tan(60°)x + b is constructed from (Px, Py) - (Cx, Cy). The vector is then (Px-Cx, Py-Cy) that has an angle of 60° above the horizontal that is parallel to the horizontal axis. We need to use another form of the linear equation that involves the points and the slope this time which happens to be y - y1 = m(x - x1) so this then becomes y - Py = tan(60°)(x - Px) well I did say earlier that we could substitute so let's go ahead and do that: y - By = tan(60°)(x - Ax) then y - By = tan(60°)x - tan(60°)Ax. And this becomes known if you know the actual coordinate points of A & B. The only thing here is that you have to convert your angle of 120° to standard form. It all depends on what your known and unknowns are. So if you need P and you have both A & B are known from your diagram the work is easy because the points you need for P will be P(Ax,By). And since you already said that you know Da, Db & Dc with their lengths then its just a matter of apply the correct trig functions with the proper angle and or using the Pythagorean Theorem to find the length of another leg of the triangle. It shouldn't be all that hard to find what P(x,y) is from the other points. You can use the trig functions, linear equations, the Pythagorean theorem, vector calculations etc. If you can find the equation of the line that points C & P knowing that P has A's x value and has B's y value and having the slope of that line that is defined by the tangent above the horizontal which is 180° - phi where phi is the angle you are giving that is CW rotation and theta would be the angle in standard position or above the horizontal you have a general form of y - By = tan(180° - phi)(x - Ax) and from this equation you can find any point on that line.
There are other methods such as using the existing points and the vectors that they create between each other and then generate an equilateral triangle using those points and then from that equilateral if you can generate one, you can use the perpendicular bisectors of that triangle to find the centroid of that triangle. That is another method that can be done. The only thing you may have to consider is the linear translation of the line from the origin. Thus you will have a shift in the line of (Ax - origin, By - origin) and to find one set the other to 0 and vise versa. There are many different methods to find it.
I just showed you several mathematical techniques that can help you to find a general equation based on your known(s) and unknown(s). It just a matter of recognizing which equations work in which scenario. Once you recognize the correct equations for the givens; the rest is fairly easy. I hope this helps you.
EDIT
I did forget to mention one thing; and that is the line of CP has a point on the edge of the circle defined by (cos(60°), sin(60°)) in the 1st quadrant. In the third quadrant you will have a point on this line and the circle defined by (-cos(60°), -sin(60°)) provided that this line goes through the origin (0,0) where there is no y nor x intercepts and if this is the case then the point on the circle at either end and the origin will be the radius of that circle.
I read this tutorial for aabb-plane test, and I'm having trouble understanding the "optimized" aabb-plane test described.
Under "Geometric Approach - Testing Boxes II", I understand everything until this line:
Assume a AAB that has its components x,y,and z varying between xmin
and xmax; ymin and ymax; and zmin and zmax. The components of the
positive vertex p are selected as follows: ...
I also don't get the code that comes afterwards.
My AABB objects are defined by their minVertex, maxVertex parameters.
Can you explain me what did the author mean?
Consider the following picture where the diagonal PS is (supposedly) parallel to the normal vector (BTW, this is what the tutorial calls the AAB case). This picture represents the 2D version of the problem where the idea is easier to explain and understand.
The p-vertex is, by definition, the one that is further aligned with the direction of the normal. This means that you have to decide which one of the following four vectors is further aligned with the normal:
R - Q, Q - R, P - S or S - P (1)
In this case the answer is S - P, which means that S is the p-vertex and P the n-vertex. But the problem is how to detect this programmatically.
Well, the dot product between two vectors measures the projection of one of them onto the other, so the problem can be restated as: which of the vectors in (1) has the maximum dot product with the normal (xn, yn)?
Here are the four dot products:
(xn, yn).(R - Q) = xn(x1 - x2) + yn(y1 - y2)
(xn, yn).(Q - R) = xn(x2 - x1) + yn(y2 - y1)
(xn, yn).(P - S) = xn(x1 - x2) + yn(y2 - y1)
(xn, yn).(S - P) = xn(x2 - x1) + yn(y1 - y2)
So, the one we are looking for is the one that makes both terms of the sum positive, this is
if xn > 0 select x2 - x1 (>0) otherwise x1 - x2 (<0)
if yn > 0 select y2 - y1 (>0) otherwise y1 - y2 (<0)
The reason being the rule of signs (+ times + = + and - times - = +.)
All of this translates into
start with p-vertex = (x1, y1)
if xn > 0, change x1 with x2 (effectively leaving p-vertex = (x2, y1))
if yn > 0, change y1 with y2 (effectively leaving p-vertex = (x*, y2))
(In step 3, x* is x1 or x2 depending on the result of setp 2)
These arguments remain valid if you are in 3 dimensions. The only difference is that you have to add z coordinates everywhere.
Excuse me if I phrased the title wrong, I am not great with math and don't know the right term, but I figure someone will edit it correctly.
I am creating a script in Lua and I have a target location and my location. I found the slope for it so at the moment I have X1, X2, Y1, Y2, and M(slope).
I do not know the math to add a new point with x distance away.
Sort of like this badly done MS paint example where the 2 black dots are target on the far right, and my location on the left, and then the green dot is what I want.
I'm going to assume thatThe black point on the left is (X1, Y1)The black point on the right is (X2, Y2)The slope M = (Y2 – Y1)/(X2 - X1)This means that the straight line between (X1, Y1) and (X2, Y2) are all the points (X,Y) where
Y = Y1 + M (X-X1)
Define the distance D between (X1, Y1) and (X2, Y2), which is given by
D = Math.sqrt((X2 - X1)² + (Y2 – Y1)²)
where Math.sqrt(...) is the square root function. If you want a point on that straight line to be a distance d from (X1, Y1) then there are two such points, one to the left of (X1, Y1) and one to the right of (X1, Y1). The coordinates of those two points are
(X1 + (X2 - X1) d/D, Y1 + (Y2 - Y1) d/D)
and
(X1 - (X2 - X1) d/D, Y1 - (Y2 - Y1) d/D)
The first point, with the + sign, is the point that's a distance d from (X1, Y1) in the direction of (X2, Y2). The second point with the - sign, is the point that's a distance d from (X1, Y1) but in the direction away from (X2, Y2). If the case you want is always as shown in the diagram, then the answer is always to take the second point with the - sign.
You have to combine two formula.
1. (y3-y2)^2 + (x3-x2)^2 = d
2. (y2-y1)/(x2-x1) = (y3-y2)/(x3-x2)
This is haskell code for your question. it maybe usefull.
foo x1 y1 x2 y2 d =
[(x3,y3) |
x3 <- [-100..100], y3 <- [-100..100],
(y3-y2)^2 + (x3-x2)^2 == d,
(y2-y1)/(x2-x1) == (y3-y2)/(x3-x2)]
ps: 100 is a range. you can change it. this function return two couple. like (-1,1), (11,9). because I dont specify the way.
Another solution:(I combined formulas)
let k = d / sqrt((y2-y1)^2 + (x2-x1)^2)
x3 = x2 + k * (x2-x1) other x3 = x2 - k * (x2-x1)
y3 = y2 + k * (y2-y1) other y3 = y2 - k * (y2-y1)
I would like to write a function that takes a 3d triangle (as 3 points (vector3ds)) and returns a 2d triangle (as 3 points (vector2ds)):
When given a 3d triangle, it should return the 2 dimensional coordinates of its points as they lie on its plane. (By 'its plane' I mean the plane that all three points lie on).
I can think a long winded way todo this:
rotate the triangle until its normal is equal to +z (0,0,1), then construct a triangle from the (x, y) coords of each point.
I cant help but think there must be an easier way to achieve the same thing.
If posting code examples please try not to use Greek alphabet. Some pseudo code in a C/java style language would be ideal.
From your comments I infer that you can choose the coordinate system of the plane in an arbitrary way, as long as the Euclidean metric of this coordinate system is the same as the metric induced by the Euclidean metric of your three-dimensional coordinate system. (That is, Euclidean distances will stay the same.)
One possible solution:
x0' = 0
y0' = 0
x1' = sqrt((x1 - x0)^2 + (y1 - y0)^2 + (z1 - z0)^2)
y1' = 0
x2' = ((x1 - x0) * (x2 - x0) +
(y1 - y0) * (y2 - y0) +
(z1 - z0) * (z2 - z0)) / x1'
y2' = sqrt((x2 - x0)^2 + (y2 - y0)^2 + (z2 - z0)^2 - x2'^2)
There is no singular answer to this problem.
The plane in which the triangle sits has no defined origin, and no defined orientation.
The best you can do is define one of the vertices as the origin, and one of the edges laying along the X axis:
v1 = (0, 0)
You will need to calculate vectors A (i.e. v2 - v1) and B (i.e. v3 - v1).
Vertex 2 will then be at:
v2 = (|A|, 0)
The position of vertex 3 can be worked out by using the vector cross product rule, e.g.:
A x B = |A| * |B| sin(theta)
So, work out A x B and from that you can work out the sine of the angle theta between A and B:
sin(theta) = | A x B | / (|A| * |B|)
Vertex 3 is then at coordinates:
v3 = |B| (cos(theta), sin(theta))
You can take advantage of cos(theta) = sqrt(1 - sin(theta) ^ 2) to avoid any inverse trig operations.
You should also see that |B| sin(theta) is just | A x B | / | A |
I have a 3D math problem which I just can't seem to solve.
I have data of 3 points. The data is a (2D) coordinate on a plane, floating somewhere in 3D space. I also know the (2D) coordinate of the projection. That results in the following array of data:
[[[x1,y1], [px1,py1],
[[x2,y2], [px2,py2],
[[x3,y3], [px3,py3]]
Where the normal (x1 etc.) coordinates stand for the coordinates on the plane and the other (px1 etc.) for the projected coordinates.
What I would like to do is project a new 2D coordinate ([x4,y4]).
.
What I tried so far:
Ofcourse you need an eye for projection, so I set that to [xe,ye,-1]. The xe and ye are known. (It is photo referencing, so I just placed the eye in the center of the photograph.)
Beneath the eye I placed the projection surface (z=0). That gives the following projection coordinates:
[[[x1,y1], [px1,py1,0],
[[x2,y2], [px2,py2,0],
[[x3,y3], [px3,py3,0]]
I can't do the same for the coordinates on the plane, since I don't know anything about that plane.
I also figured that I could make a parameterized formula of the lines running from the eye through the projection coordinates. For line1 that would be:
line1x = xe+(px1-xe)*t1
line1y = ye+(py1-ye)*t1
line1z = -1+t1 // = -1+(0--1)*t1
I also know the distance between the points in 3D. That's the same as in 2D. That means the distance between point1 and point2 would be sqrt((x1-x2)^2+(y1-y2)^2).
I also know the distance between the lines (line1 and line2) at any time. That is sqrt((line1x-line2x)^2+(line1y-line2y)^2+(line1z-line2z)^2).
However, I don't really know how to go from here... Or even whether this is the right route to take.
.
I hope you understand what I want to be able to do, and that you can help me.
Thanks in advance!
There is a function Projection, which can transform points so that Projection([x1, y1]) = [px1, py1] , Projection([x2, y2]) = [px2, py2], Projection([x3, y3]) = [px3, py3]. If I understand correctly, author wants to know how to find this Projection function, so that he can trasnform [x4, y4] into [px4, py4].
Since we are dealing with planes here, the Projection function looks like this:
Proj([ix, iy]) :
return [ax*ix + bx*iy + cx,
ay*iy + by*iy + cy];
Using that we can make 2 equation systems to solve.
The first one
x1 * ax + y1 * bx + cx = px1
x2 * ax + y2 * bx + cx = px2
x3 * ax + y3 * bx + cx = px3
Solving for ax, bx and cx gives us
ax = (px1 * (y3 - y2) - px2*y3 + px3*y2 + (px2 - px3) * y1) /
(x1 * (y3 - y2) - x2*y3 + x3*y2 + (x2 - x3) * y1)
bx = - (px1 * (x3 - x2) - px2*x3 + px3*x2 + (px2 - px3) * x1) /
(x1 * (y3 - y2) - x2*y3 + x3*y2 + (x2 - x3) * y1)
cx = (px1 * (x3*y2 - x2*y3) + x1 * (px2*y3 - px3*y2) + (px3*x2 - px2*x3) * y1) /
(x1 * (y3 - y2) - x2*y3 + x3*y2 + (x2 - x3) * y1)
The second one
x1 * ay + y1 * by + cy = py1
x2 * ay + y2 * by + cy = py2
x3 * ay + y3 * by + cy = py3
Solving for ay, by and cy gives us
ay = (py1 * (y3 - y2) - py2*y3 + py3*y2 + (py2 - py3) * y1) /
(x1 * (y3 - y2) - x2*y3 + x3*y2 + (x2 - x3) * y1)
by = - (py1 * (x3 - x2) - py2*x3 + py3*x2 + (py2 - py3) * x1) /
(x1 * (y3 - y2) - x2*y3 + x3*y2 + (x2 - x3) * y1)
cy = (py1 * (x3*y2 - x2*y3) + x1 * (py2*y3 - py3*y2) + (py3*x2 - py2*x3) * y1) /
(x1 * (y3 - y2) - x2*y3 + x3*y2 + (x2 - x3) * y1)
Note: I used this tool to solve equation systems.
You should use homographic functions and homogeneous coordinates, which are generaly used for 3D perspective operations.
Write
(x4,y4,1) = A1*(x1,y1,1) + A2*(x2,y2,1) + A3*(x3,y3,1),
solving for A1,A2,A3. Then
(xp4,yp4) = A1*(px1,py1) + A2*(px2,py2) + A3*(px3,py3).
1st edit.
(A1,A2,A3) is the solution of the linear system Mat*(A1,A2,A3)=(x4,y4,1).
( x1 x2 x3 )
Mat = ( y1 y2 y3 )
( 1 1 1 )
This can be solved in various ways. For example using Cramer's rules.
2nd edit.
The 1's I inserted are not Z coordinates, but homogeneous extensions of the input coordinates (which must be Euclidean coordinates). (A1,A2,A3) are homogeneous coordinates in the basis formed by the triangle vertices.
3rd edit.
The correspondence between the 3D plane and the projection plane is a projective transformation. It can be defined as a 3x3 matrix T operating on homogeneous coordinates in the input plane (x,y,1) (in your coordinate system) and producing coordinates (u,v,t) in the projection plane. Then px=u/t and py=v/t.
If a point has homogeneous coordinates (A1,A2,A3) in the basis formed by three points of the input plane (not on the same line) then its projection has the same homogeneous coordinates in the projected basis.
It seemed quite clear to me 1 hour ago, but now I'm beginning to doubt: maybe knowing one additional pair of points is needed to have a single solution to the problem... If you can find it, have a look at the book "Algebraic Projective Geometry" by J.G. Semple and G.T. Kneebone.
I don't really understand the problem? Are you trying to locate an object in 3d-space that you know is located on a plane (a wall or floor for example) and the only input you have is 3 points(of which you know the distances between in 3d-space) from a camera-image?
In that case you will have 3 equations like this where localCoordinates is the points coordinates in objectspace(gives the known distance between the points) and world is the objects position in 3d-space.
cameraCoordinates = world*view*projection*localCoordinates
This will yield an equation system with 6 unknown(rotation and position in 3d) and 6 equations (2 for every point). It will however be non linear so you have to solve it using numerical methods. Try the Newton Rapson method.
A "bit" late here, but the highest rated answer doesn't take into account the 3D-space of the problem. We have a perspective projection problem, with three points on a plane (actually any 3 3D points) being projected (as in projective geometry) on the surface of a camera.
It is not possible to give an unambiguous solution to this problem (multiple solutions exist). The general problem of finding a camera position and pose given 3 3D points and their respective 2D perspective projections can be solved using the P3P (Perspective-3-Point) algorithm from the original RANSAC paper, which give up to four possible feasible solutions (with the points in front of the camera).
Given a camera pose, it is trivial to calculate the projection of additional plane points.