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
+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
2010-09-28 14:21:39
What does it do?
dtb
2010-09-28 14:25:11
@dtb - I added an explanation, let me know if you still have questions.
dcp
2010-09-28 14:30:57
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
2010-09-28 14:34:25
Corner cases? e.g. x1==x2
dtb
2010-09-28 14:34:36
@bgbg: Where exactly are floating point numbers used?
Mark Peters
2010-09-28 14:35:44
Couldn't one slope be positive and one negative? I think you ought to compare their absolute value.
jellybean
2010-09-28 14:37:14
@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
2010-09-28 14:39:01
@Mark: Ah, you're right ...
jellybean
2010-09-28 14:40:56
@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
2010-09-28 14:42:34
@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
2010-09-28 14:45:08
This requires less computation than @florin's answer even if it's equivalent (so I vote for it).
martineau
2010-09-29 00:13:41
@Mark: you are right, no floats here. On the other hand, this algorithm isn't limited for floats, so ...
bgbg
2010-09-29 10:47:47
A:
Define a Java Line2D, and then use yourLine2D.contains(double x, double y)
.
Ethan Shepherd
2010-09-28 14:22:32
+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
2010-09-28 14:24:46
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
2010-09-28 14:43:50
+1 mathematically is the same but the concept is more simple/visual/straighforward (i like it).
joaquin
2010-09-28 15:08:20
Using this formula with A:(516,520) B:(538,523) and C:(526,475) I get the area -1578! Why is that?
Hossein
2010-10-02 11:02:05
@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
2010-10-04 04:30:28
@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
2010-10-06 02:53:11
+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
2010-09-28 14:34:40