全ての3点組について、同一直線上に存在するか調べればよい。
2点 i,j(i<j)を固定し、通る直線 L を求める。
3点目を j<k の範囲で探索し、L 上にあった k の個数+2が、その直線が通る点の個数。
全ての i,j を通して、最も通った点の数が多い直線が求めるもの。
いくつかの方法がある。なるべく途中で小数が出てこないようにする方がよい。
3点に囲まれた三角形の面積は以下で求められる。
これが0なら同一直線上にある。
幾何でよく使われるユーティリティ関数に、ccw(Counter-ClockWise、反時計回り判定)がある。
A→B の線分から見て、B→C がどっち向きに曲がっているか(まっすぐか)を、外積で判定する。
汎用性があるので、これで判定してもよい。
2点組ごとに「2点を結ぶ直線の方程式 ax+by+c=0 の係数 (a,b,c)」を求め、それごとにカウントする。
(x1,y1),(x2,y2) を通る直線の方程式は、dx=x2−x1,dy=y2−y1 として、以下のようになる。
ただし、係数に定数倍をかけたものは (a,b,c) が異なっても同一の直線を示すので、それらを統一する必要がある。
こうすると、違いを吸収して、同一の直線は同一の (a,b,c) となる。
k 個の点が並ぶ直線は、k(k−1)2 回カウントされることになるので、 最終カウント結果から、各直線にいくつの点が並ぶか復元できる。
O(N2) 本の全てのカウントされた直線に対して個数を復元する。k 個の点が並ぶ直線上には、kC3 組の3つ組みがある。
最も多くカウントされた直線が、求める直線である。