前提
C言語のVisual studioで3次元の点と線分の距離を求めるプログラムを書いてます。ネットに合った2次元のプログラムを無理やり3次元にしてみました。
計算のやり方もいまいちわかってません。修正点などわかる方いたら情報が欲しいです。
実現したいこと
点と線分の距離の数値を的確に出したい。
発生している問題・エラーメッセージ
エラーは起こしていないが数値が正しくない このプログラムでは(0,0,0)と(10,0,0)の線分と(5,10,15)との距離が13.1037と出ます。 2個目は6.29961と出るのですが、実際の計算では、1個目は18.028で2個目は18.7085になりました。
該当のソースコード
C言語
1#include <iostream> 2 3struct Point 4{ 5 double x; 6 double y; 7 double z; 8}; 9 10struct LineSegment 11{ 12 Point start; 13 Point end; 14}; 15 16/** 17 @brief 線分と点の距離を計算する。 18 @param line 線分 19 @param point 点 20 @return ユークリッド距離 21 */ 22double calc_dist(const LineSegment& line, const Point& point) 23{ 24 double x0 = point.x, y0 = point.y, z0 = point.z; 25 double x1 = line.start.x, y1 = line.start.y, z1 = line.start.z; 26 double x2 = line.end.x, y2 = line.end.y, z2 = line.end.z; 27 28 double a = x2 - x1; 29 double b = y2 - y1; 30 double c = z2 - z1; 31 double a2 = a * a * a; 32 double b2 = b * b * b; 33 double c2 = c * c * c; 34 double r2 = a2 + b2 + c2; 35 double tt = -(a * (x1 - x0) + b * (y1 - y0) + c * (z1 - z0)); 36 37 if (tt < 0) 38 return cbrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) + (z1 - z0) * (z1 - z0)); 39 else if (tt > r2) 40 return cbrt((x2 - x0) * (x2 - x0) + (y2 - y0) * (y2 - y0) + (z2 - z0) * (z2 - z0)); 41 42 double f1 = a * (y1 - y0) * (z1 - z0) - b * (x1 - x0) * (z1 - z0) - c * (x1 - x0) * (y1 - y0); 43 return cbrt((f1 * f1) / r2); 44} 45 46int main() 47{ 48 Point point1 = { 5, 10 ,15 }; 49 LineSegment line1 = { {0, 0, 0}, {10, 0, 0} }; 50 double dist = calc_dist(line1, point1); 51 std::cout << "dist1: " << dist << std::endl; 52 53 54 Point point2 = { 20, 10, 5 }; 55 LineSegment line2 = { {0, 0, 0}, {10, 0, 0} }; 56 dist = calc_dist(line2, point2); 57 std::cout << "dist2: " << dist << std::endl; 58}
試したこと
ここに問題に対して試したことを記載してください。
補足情報(FW/ツールのバージョンなど)
元の2次元のプログラムはこれです。
https://teratail.com/questions/155180
元の「ネットに合った2次元のプログラム」のURLを載せてください。
わからないまま無理やり3次元にしたコードを見せられても、何をやっているのか分かりません。
すいません。こちらになります。
https://teratail.com/questions/155180
元ソースでは外積を使っているようなので、「点と線分の距離 外積」あたりで検索すれば、解説など見つかるかと思います。
> 計算のやり方もいまいちわかってません
数学の部分が解決してない状態なのであれば,その状態でてきとーなコードを書いてても仕方ない.
「距離の求め方」そのものが不明点だというなら「中学か高校レベルの数学の話を教えてください」っていうことになるから「プログラミングに関係ない話」ということになるような予感.
ものすごくざっくりと説明するなら:
その点から線分(を無限に延長した直線)に対して垂線を下ろすことを考えればいい.
下ろした先が線分の範囲内にあるならば垂線の長さがそのまま求める距離ということになるし,
そうでないなら線分の端点と点との距離を求めればいい.
