views:

363

answers:

6

Hi, I want to know a piece of a code which can actually tell me if 3 points in a 2D space are on the same line or not. A pseudocode is also sufficient but Python is better. Thanks

A: 

y - y0 = a(x-x0) (1) while a = (y1 - y0)/(x1 - x0) and A(x0, y0) B(x1, y1) C(x2, y2). See whether C statisfies (1). You just replace the appropriate values.

Details

myle
+16  A: 

This is C++, but you can adapt it to python:

bool collinear(int x1, int y1, int x2, int y2, int x3, int y3) {
  return (y1 - y2) * (x1 - x3) == (y1 - y3) * (x1 - x2);
}

Basically, we are checking that the slopes between point 1 and point 2 and point 1 and point 3 match. Slope is change in y divided by change in x, so we have:

y1 - y2     y1 - y3
-------  =  --------
x1 - x2     x1 - x3

Cross multiplying gives (y1 - y2) * (x1 - x3) == (y1 - y3) * (x1 - x2);

Note, if you are using doubles, you can check against an epsilon:

bool collinear(double x1, double y1, double x2, double y2, double x3, double y3) {
  return fabs((y1 - y2) * (x1 - x3) - (y1 - y3) * (x1 - x2)) <= 1e-9;
}
dcp
What does it do?
dtb
@dtb - I added an explanation, let me know if you still have questions.
dcp
nice trick. However, checking floating point numbers for equality isn't safe. You might test the absolute difference against a pre-defined threshold that is dependent on the resolution (sensitivity) you want to achieve
bgbg
Corner cases? e.g. x1==x2
dtb
@bgbg: Where exactly are floating point numbers used?
Mark Peters
Couldn't one slope be positive and one negative? I think you ought to compare their absolute value.
jellybean
@jellybean: I thought so too, but it checks out. Remember a negative slope is a different line (top left to bottom right). If the line goes 3, 1, 2 with 1 in the middle, it still works because the negatives cancel out.
Mark Peters
@Mark: Ah, you're right ...
jellybean
@dtb - x1==x2 works ok, consider these cases: collinear(-2,0,-2,1,-1,1) returns false, and collinear(-2,0,-2,1,-2,2) returns true. I think the corner cases are covered, let me know if you disagree.
dcp
@jellybean: negative slopes will give other lines than positive ones, then no you must not compare absolute values of you won't get the right answer.
kriss
This requires less computation than @florin's answer even if it's equivalent (so I vote for it).
martineau
@Mark: you are right, no floats here. On the other hand, this algorithm isn't limited for floats, so ...
bgbg
A: 

Define a Java Line2D, and then use yourLine2D.contains(double x, double y).

Ethan Shepherd
+1  A: 

Read this, and use it to find the equation of a line through the first two points. Follow the instructions to find m and b. Then for your third point, calculate mx + b - y. If the result is zero, the third point is on the same line as the first two.

Douglas
+17  A: 

You can check if the area of the ABC triangle is 0:

[ Ax * (By - Cy) + Bx * (Cy - Ay) + Cx * (Ay - By) ] / 2

Of course, you don't actually need to divide by 2.

florin
This is much better because there is no risk of dividing by 0.
John Smith
Just to point something out... This is mathematically equivalent to @dcp's answer above (if you ignore the `/2`), but checking if the area is 0 makes it easier to add a tolerance... (i.e. `stuff < err_tolerance` instead of `stuff1 == stuff2` as @dcp does above)
Joe Kington
+1 mathematically is the same but the concept is more simple/visual/straighforward (i like it).
joaquin
Using this formula with A:(516,520) B:(538,523) and C:(526,475) I get the area -1578! Why is that?
Hossein
@Hossein: Are you asking about the absolute value, or about the sign? With your points and my formula I'm getting -510. The sign means that you chose a certain order of the points. You could swap A with C or B and you'll get a positive area, even thought it's the same triangle.
florin
@Joe Kington: (1) You need to do -tolerance < stuff < tolerance. (2) @florin's formula requires 3 multiplications and 5 additions/subtractions to give a "should be zero" result. @dcp's formula, adjusted by changing `==` to `-`, requires 2 mults and 5 subtractions to give a "should be zero" result. I'd give @dcp the tick, not @florin.
John Machin
+1  A: 

Rule 1: In any linear 2d space, two points are always on the same line.

Take 2 points and build an equation that represents a line through them. Then check if the third point is also on that line.

Good luck.

Rob Vermeulen