2 つの点 A(x,y)---B(x,y) の間に線を引きました。これで 3 番目の点 C(x,y) ができました。CがAとBの間に引かれた線上にあるかどうかを知りたい.Java言語でやりたい. これに似た答えがいくつか見つかりました。しかし、すべてに問題があり、完璧な人はいません。
10 に答える
if (distance(A, C) + distance(B, C) == distance(A, B))
return true; // C is on the line.
return false; // C is not on the line.
あるいは単に:
return distance(A, C) + distance(B, C) == distance(A, B);
これが機能する方法はかなり単純です。C がAB
ライン上にある場合、次のシナリオが得られます。
A-C------B
そして、その行のどこにあるかに関係なく、dist(AC) + dist(CB) == dist(AB)
. それ以外の場合は、いくつかの説明と 'dist(AC) + dist(CB) > dist(AB)' の三角形があります。
A-----B
\ /
\ /
C
実際、これは C が外挿線上にある場合でも機能します。
C---A-------B
ただし、距離は符号なしで保持されます。距離は次のdist(AB)
ように計算できます。
___________________________
/ 2 2
V (A.x - B.x) + (A.y - B.y)
浮動小数点演算固有の制限 (精度の制限) に注意してください。等式が正しく機能することを確認するために、「十分に近い」テスト (たとえば、100 万分の 1 未満の誤差) を選択する必要がある場合があります。
注意!数学のみ!
この式を試すことができます。あなたA(x1, y1)
とB(x2, y2)
座標を式に入れると、次のようなものが得られます
y = k*x + b; // k and b - numbers
次に、この方程式を満たす任意の点は、直線上にあります。C(x, y)
が と の間A(x1, y1)
であることを確認するには、次を確認してB(x2, y2)
ください: (x1<x<x2 && y1<y<y2) || (x1>x>x2 && y1>y>y2)
。
例
A(2,3) B(6,5)
直線の方程式:
(y - 3)/(5 - 3) = (x - 2)/(6 - 2)
(y - 3)/2 = (x - 2)/4
4*(y - 3) = 2*(x - 2)
4y - 12 = 2x - 4
4y = 2x + 8
y = 1/2 * x + 2; // equation of line. k = 1/2, b = 2;
C(4,4)
がこの線上にあるかどうかを確認してみましょう。
2<4<6 & 3<4<5 // C between A and B
ここで、C 座標を方程式に入れます。
4 = 1/2 * 4 + 2
4 = 2 + 2 // equal, C is on line AB
PS: @paxdiablo が書いたように、計算する前に線が水平か垂直かを確認する必要があります。チェックするだけ
y1 == y2 || x1 == x2
私は最も簡単だと信じています
// is BC inline with AC or visa-versa
public static boolean inLine(Point A, Point B, Point C) {
// if AC is vertical
if (A.x == C.x) return B.x == C.x;
// if AC is horizontal
if (A.y == C.y) return B.y == C.y;
// match the gradients
return (A.x - C.x)*(A.y - C.y) == (C.x - B.x)*(C.y - B.y);
}
x 値の差を y 値の差で割ることで、勾配を計算できます。
注: 画面に C を描画した場合、A と B の間の線に C が表示されるかどうかを確認する別のテストがあります。数学では、A、B、C が無限に小さい点であると想定されています。実際には非常に小さく、表現誤差の範囲内です。
これが私のC#ソリューションです。Java の同等物はほぼ同じになると思います。
ノート:
メソッドは、点が線の境界内にある場合にのみ true を返します (無限の線を想定していません)。
縦線または横線を処理します。
チェックされているポイントのラインからの距離を計算するため、許容範囲をメソッドに渡すことができます。
/// <summary> /// Check if Point C is on the line AB /// </summary> public static bool IsOnLine(Point A, Point B, Point C, double tolerance) { double minX = Math.Min(A.X, B.X) - tolerance; double maxX = Math.Max(A.X, B.X) + tolerance; double minY = Math.Min(A.Y, B.Y) - tolerance; double maxY = Math.Max(A.Y, B.Y) + tolerance; //Check C is within the bounds of the line if (C.X >= maxX || C.X <= minX || C.Y <= minY || C.Y >= maxY) { return false; } // Check for when AB is vertical if (A.X == B.X) { if (Math.Abs(A.X - C.X) >= tolerance) { return false; } return true; } // Check for when AB is horizontal if (A.Y == B.Y) { if (Math.Abs(A.Y - C.Y) >= tolerance) { return false; } return true; } // Check istance of the point form the line double distFromLine = Math.Abs(((B.X - A.X)*(A.Y - C.Y))-((A.X - C.X)*(B.Y - A.Y))) / Math.Sqrt((B.X - A.X) * (B.X - A.X) + (B.Y - A.Y) * (B.Y - A.Y)); if (distFromLine >= tolerance) { return false; } else { return true; } }