views:

522

answers:

4

Hello,

I have the coordinates (x,y) of 2 points. I want to build the third point so that these 3 points make an equilateral triangle.

How can I calculate the third point?

Thank you

+4  A: 

Let's call your two points A and B. Bisect AB, call this point C. Find the slope of AB (YA-YB / XA-XB), call it m. Find the perpendicular to that (-1/m) and call it m2. Then compute a segment CD whose length is sin(60) * length(AB), at the slope m2 (there will be two such points, one to each side of AB). ABD is then your equilateral triangle.

That, obviously, is a "constructive" method. You should also be able to do it by solving a set of linear equations. I haven't tried to figure out the right system of equations for this case, but this approach tends to be somewhat more stable numerically, and has fewer special cases (e.g., with the constructive version, a slope of 0 has to be dealt with specially).

Jerry Coffin
Shouldn't that be cos(30)?
Niall C.
@nc9217:Oops. Corrected.
Jerry Coffin
+2  A: 

For BlueRaja's challenge go to end of post:


Answer using translation and rotation:

Says points are P(x1,y1) and Q(x2,y2).

Since it is graphics, you can use tranforms to get the point.

First translate axes so P is the origin. Next rotate Q around P by 60 degrees (or -60 to get the other possible point).

This gives you the coordinates of the third point say R, when P is the origin.

Translate back and there you have it.

You can use standard graphics API which take care of precision etc issues for you. No headaches.

Of course you could do the math and actually come up with a formula and use that and that might be faster, but then the question might get closed as off-topic ;-)


To take up BlueRaja's challenge: Here is a method which does not use trigonometry.

Given points P(x1,y1) and Q(x2,y2) Say the point we need (R) to find is (x3,y3).

Let T be midpoint of PQ.

We know the area of triangle PQR (as it is equilateral and we know the side)

and we know the area of triangle PRT (1/2 the earlier area).

Now area of a triangle can be written as a determinant having the co-ordinates as entries:

2*Area = |D|

where

     | 1 x1 y1|
D =  | 1 x2 y2|
     | 1 x3 y3|

We have two such equations (which are linear), solve for x3 and y3.

Moron
Nice, I think this should work. I was thinking something much simpler: since we know R and we know the height of the triangle (each half is a 30-60-90 triangle), we can simply place a normal vector at R and extend it by the height.
BlueRaja - Danny Pflughoeft
@BlueRaja: Yeah, that works too, as finding the normal need not involve trigonometry. I wanted to completely avoid using any kind of angle concepts, hence the complexity...
Moron
If you have `(x1, y1)` and `(x2, y2)`, the normal is just `(-(y2-y1), (x2-x1))/length`. Determining length is simple, but does not even matter in this case, as it cancels out of the final equation.
BlueRaja - Danny Pflughoeft
@BlueRaja: Yeah I am not disputing that. All I am saying is that I started out thinking "No angles... No angles.." and managed to complicate matters :-)
Moron
+2  A: 

You could rotate the second point 60° around first to find the location of the third point.

Something like this:

//find offset from point 1 to 2
dX = x2 - x1;
dY = y2 - y1;
//rotate and add to point 1 to find point 3
x3 = (cos(60°) * dX - sin(60°) * dY) + x1;
y3 = (sin(60°) * dX + cos(60°) * dY) + y1;
vkit
Isn't it [cos(60) sin(60); -sin(60) cos(60)]? I think your signs are wrong.
Arrieta
I think those signs are correct. See also: http://stackoverflow.com/questions/786472/rotate-a-point-by-an-angle
vkit
@arrieta Just tried this out, if you use the signs as you suggest it rotates the point the other way (clockwise/counter-clockwise) so depending on how your coordinate system is set up, one or the other might make more sense.
vkit
A: 

After reading the posts (specially vkit's) I produced this simple piece of code which will do the trick for one direction (remember that there are two points). The modification for the other case shold be trivial.

#include<stdio.h>
#include<math.h>

typedef struct{
  double x;
  double y;
} Point;

Point vertex(Point p1, Point p2){
  double s60 = sin(60 * M_PI / 180.0);    
  double c60 = cos(60 * M_PI / 180.0);

  Point v = {
    c60 * (p1.x - p2.x) - s60 * (p1.y - p2.y) + p2.x,
    s60 * (p1.x - p2.x) + c60 * (p1.y - p2.y) + p2.y
  };

  return v;
}
Arrieta
@Arrieta: I said the same thing! And I didn't put any explicit code for a reason: graphics API can do rotations (and translations) much better(precision, trigonometric calculations etc etc) than we can ever hope to do ourselves. Since we do not know the API OP is using, all we can do is mention what to do. Oh well...
Moron