【先着1,000名様!】1,000円分をプレゼント!

2線分の最短距離を求める方法はありませんか?
ぐぐっても見ましたが点と線ばかりでした。

A 回答 (5件)

#1,#2,#4です。


>2次元の2つの線分の最短距離についてです。
2つの線分をAB,CDとすると、
最短距離は以下の手順で4つの候補を求め、その中の最小の長さが求める最短距離になります。
その中で、点と直線の距離(垂線の長さ)の公式、2点間の距離の公式、直線上の点が直線上の線分の範囲内にあるか、無いかの判別式を使います。

(1)端点Cから線分ABまたはその延長線に垂線CHを下ろして垂線の足Hが線分AB上にあればCDを候補とします。Hが線分AB上になければCAとCBの短い方の長さを候補とします。

(2)端点Dから線分ABまたはその延長線に垂線DKを下ろして垂線の足Kが線分AB上にあればDKを候補とします。Kが線分AB上になければDAとDBの短い方の長さを候補とします。

(3)端点Aから線分CDまたはその延長線に垂線AMを下ろして垂線の足Mが線分CD上にあればAMを候補とします。Mが線分CD上になければACとADの短い方の長さを候補とします。

(4)端点Bから線分CDまたはその延長線に垂線BNを下ろして垂線の足Nが線分CD上にあればBNを候補とします。Nが線分CD上になければBCとBDの短い方の長さを候補とします。

(5)(1)~(4)の候補の内、最小の長さの線分を2つの線分ABとCDの間の最小距離とする。
    • good
    • 2

#1,#2です。



A#2は三次元の2直線間の(最短)距離を対象とした回答です。

質問が2次元で、2線分間の距離の場合なら、補足でそのようにお書き下さい。

また三次元空間における2線分間の距離の場合も。補足にその様にお書き下さい。
この場合、直線間の最短距離の点が線分上にない場合は、最短点に最も近い線分の端点からの距離が最短になりますが、最短点がどちらの線分上の外に出てしまうか、あるいは、どちらの線分上にもない場合は、端点間の距離を比較して線分上の最短となる端点を選びます。

質問の内容が2次元か3次元か、線分の位置関係によって条件が変わってきますので、質問の問題をはっきり書いて、問題が不明確にならないようにして下さい。

この回答への補足

書き方が悪かったようですみません。
シューティングのレーザーorビーム類の当たり判定に使いたいと思っていますので、
2次元の2つの線分の最短距離についてです。
しかし後々3次元にも拡張したいと思っています
当たり判定用なので、線分同士の位置関係がどのようになるかは解りません。

補足日時:2009/07/19 11:53
    • good
    • 0

あなたがお聞きしたいのは2"線分"の最短距離ですか。


それとも2"直線"の最短距離ですか。

2"直線"の最短距離であれば#2での回答に従えばもとめることができます。
2"線分"の最短距離であれば場合わけが必要になります。

この回答への補足

お早い解答ありがとうございます。
おっしゃるとおり2"線分"です。
他の方も誤解があるようですみません。

補足日時:2009/07/19 01:28
    • good
    • 0

#1です。



補足です。
過去に私が解答したQA
qa4673776.html

また参考となるURLがありますので挙げておきます。
http://ahirujigen.hp.infoseek.co.jp/coding002.html
    • good
    • 0

>点と線ばかりでした。


それが分かれば、その点をもう一本の直線に代入して、距離が最小になる点の座標を求めれば良いだけです。

あるいは、それぞれの直線の法線が一致する条件から、最短となる直線上のそれぞれの点が決定できますので、その2点間の距離を計算すれば良いでしょう。

一般論で考えるのではなく、具体的な2本の直線の式を与えてやってみたらどうでしょう。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Q曲線と点の最短距離の出し方

曲線と点の最短距離の出し方について調べていますがわかりません。
最短距離にある曲線上の点が求められれば三平方で求められることはわかります。

例えば
y= -2x^2+16x-2
の曲線と
座標A(6,40)
の最短距離の求め方を教えて下さい
計算方法というか途中経過も含めて教えていただきたいです。

宜しくお願い致します。

Aベストアンサー

曲線 y = -2x^2+16x-2 上の点の座標は (x, -2x^2+16x-2) と書けるから, この点と P との距離 (の 2乗) を最小化すればいい. 高校の微分の問題だな.

QC++ vectorに配列をプッシュしたい

C++のstd::vectorが格納する要素として配列を指定することはできますか

vectorを使って2次元配列を表現したいときは,たとえば

std::vecor<std::vector<int>> v;

とすれば2次元配列が表現できますよね.

2次元配列の列方向の要素数が2で固定されていて,行方向の要素数が不確定のデータを扱いたいので,2次元配列を格納するvectorで扱えればなと思いました.
(2個で1組のデータがたくさんあるということなので,vectorの2次元配列ではありません)

std::vector<int[2]> v;

int a[2];
a[1] = 1;
a[0] = 2;
v.push_back(a);

という書き方ではコンパイルできなかったのですが,vectorに配列要素を格納させることはできないのでしょうか.
あるいは,もし可能ならどのように書けばよいのでしょうか.

結局は1組のデータセットを構造体化してそれをvectorにプッシュするやり方に落ち着いたのですが,疑問に思ったままモヤモヤしているので質問させて頂きます.

「vector 配列」などのキーワードで検索してみましたが,vectorの動的配列としての紹介記事が多くヒットしてしまい,自分ではうまく情報を発見することはできませんでした.
よろしくお願いします.

C++のstd::vectorが格納する要素として配列を指定することはできますか

vectorを使って2次元配列を表現したいときは,たとえば

std::vecor<std::vector<int>> v;

とすれば2次元配列が表現できますよね.

2次元配列の列方向の要素数が2で固定されていて,行方向の要素数が不確定のデータを扱いたいので,2次元配列を格納するvectorで扱えればなと思いました.
(2個で1組のデータがたくさんあるということなので,vectorの2次元配列ではありません)

std::vector<int[2]> v;

int a[2];
a[1] = 1;
a[0] = 2;
v...続きを読む

Aベストアンサー

コンテナに巣の配列を要素として入れることはできません.

C++11 (以降) なら std::array を使えばいい.

C++98 なら
・あきらめる
・Boost の boost::array を使う
・C++11 の std::array 相当のものを自作する
のいずれか, かな.

Q3次元空間内での線分の交差判定について

はじめまして。
3D関係のプログラムを組む上で、線分同士の判定を行う必要があるのですが
数学の知識が乏しく困っています。

3次元空間内の線分ABとCDが交差しているか判定し、
交差していればその交点を求めたいのです。
2次元の場合はできたのですが、3次元になるとどうやって計算すればよいのか
わかりません。(交差以外に、ねじれの位置関係があるんですよね?)
どなたか教えていただけると助かります。

Aベストアンサー

1)一般に「捩れの位置」になりますから、互いに最短の位置を求める問題に帰着します。a-kumaさんの言われるような連立一次方程式では未知数が2つ、式がx,y,z3つとなるので解けません。2次元ならyosizoさんの言われるように未知数と式の数が2つで簡単に解けます。

2)線分AB、CDの何れかの長さが<ε以下、または、線分AB、CDはほぼ平行ならゼロ割を起こすか答えが求まっても答えの精度が著しく低下します。このチェックも実際のプログラムでは絶対に必要です。

3)で、以下、2)のチェック済みであると仮定して.....。

4)たまたま最近3D-CAD用に作ったもので数式の求めた方を忘れてしまったが、

// t0:AB方向単位ベクトル、t1:CD方向単位ベクトル、として、
// float spd = <t0・t1>即ち、ベクトルt0とt1の内積

float det= spd*spd - 1.0f; // spd:AB方向単位ベクトル
v01 = C - A; //3Dベクトル (C-A)
u0 = (spd*<v01・t1> - <v01・t0>) / det;
u1 = (<v01・t0> - spd*<v01・t1>) / det;

として、パラメータ、u0,u1が求まります。ここに、
u0:AB方向パラメータ、u0=0の時、q0(u0)=Aで、u0はAからの距離を表わす。
■q0(u0)=A+u0*t0...............Equ.1)
u1:CD方向パラメータ、u1=0の時、q1(u1)=Cで、u1はCからの距離を表わす。
■q1(u1)=C+u1*t1...............Equ.2)

これで、捩れの位置に2点求まるのですが、

・2点が距離の許容誤差よりも離れていたら、エラーとする。
・2点が距離の許容誤差以内なら、2点の中点を取る。
・中点がいやなら、重みを掛ける(場合もある)。

この説明で不十分ならあとで補足します。

1)一般に「捩れの位置」になりますから、互いに最短の位置を求める問題に帰着します。a-kumaさんの言われるような連立一次方程式では未知数が2つ、式がx,y,z3つとなるので解けません。2次元ならyosizoさんの言われるように未知数と式の数が2つで簡単に解けます。

2)線分AB、CDの何れかの長さが<ε以下、または、線分AB、CDはほぼ平行ならゼロ割を起こすか答えが求まっても答えの精度が著しく低下します。このチェックも実際のプログラムでは絶対に必要です。

3)で、以下、2)のチェック済みである...続きを読む

Qタンジェントとアークタンジェントの違い

タンジェントとアークタンジェント、サインとアークサイン、コサインとアークコサインの違いをすごく簡単に教えてください。

Aベストアンサー

タンジェントやサイン、コサインは、角度に対する関数です。
例えば
 tan60°=√3
のような感じで、角度を入力すると、値が出てきます。

逆に、アークタンジェントなどは、数値に対する関数です。
 arctan√3=60°
などのように、数値を入力すると角度が出てきます。

そして、タンジェントとアークタンジェントの関係は、
springsideさんも書いてありますが、逆関数という関係です。
逆関数というのは、原因と結果が逆になるような関数です。
例えば、
  45°→タンジェント→1
  1  →アークタンジェント→45°
のように、「1」と「45°」が逆の位置にありますよね?
こういう関係を、「逆関数」というんです。

どうでしょう、わかりましたか?

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。

Q任意の点と任意の線分との最短距離となる点

現在C++でシューテイングゲームを作成しています。
当たり判定の計算として二次元座標の三点で判定を取れないかと考えて詰まっています。

具体的には任意の点Pと任意の点ABからなる線分の最短距離を算出したいのですが、これは可能なのでしょうか

Aベストアンサー

三点の座標は、それぞれ、A(a1,a2)、B(b1,b2)、P(p1,p2) であるとします。
次の三つの操作で最短距離が求まります。

(1)点Aが原点にくるよう全体を平行移動させます。
   A(0,0)、B(b1-a1,b2-a2)、P(p1-a1,p2-a2) となる.

(2)線分ABがx軸と合うよう全体を回転させます。
   θ=arctan{(b2-a2)/(b1-a1)} として、
   A(0,0)、B{(b1-a1)/cosθ,0}、P{(p1-a1)/cosθ,(p2-a2)/sinθ} となる.

(3)・ |点Pのx座標|≦|点Bのx座標| の場合、最短距離は、|点Pのy座標|
   つまり、|(p2-a2)/sinθ|
  ・ |点Pのx座標|>|点Bのx座標| の場合、
   ψ=arctan[{(p2-a2)/sinθ}/[{(p1-a1)/cosθ}-{(b1-a1)/cosθ}] として、
   最短距離は、|{(p2-a2)/sinθ}/sinψ|

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Q最大化と最小化ボタン

Win32Applicationサンプルを作っていて疑問に思ったのですが。

(1) メインウィンドウの右上の閉じる「×」は必要ですが、最小化・最大化ボタンを「なくす」方法は、どうすれば良いのでしょう。
(2) ダイアログボックスで反対に最小化・最大化ボタンを「追加する」方法は、どうすれば良いのでしょう。

まず(1)を知りたいです。 VC++超初心者レベルとお考え下さい。 宜しくお願い致します。

Aベストアンサー

>(1) メインウィンドウの右上の閉じる「×」は必要ですが、
>最小化・最大化ボタンを「なくす」方法は、どうすれば良いのでしょう。

CreateWindowまたはCreateWindowExのパラメータで、ウィンドウスタイルを設定するパラメータで、WS_MINIMIZEBOXとWS_MAXIMIZEBOXを含まないスタイルを指定します。

http://yokohama.cool.ne.jp/chokuto/urawaza/prm/window_style.html

>(2) ダイアログボックスで反対に最小化・最大化ボタンを「追加する」方法は、どうすれば良いのでしょう。

ダイアログのデザインで、プロパティのスタイルに設定するところがあります。

QUpdateData( FALSE); による文字列データの表示更新(VC++6.0)

VC++の超初心者です.

UpdateData( FALSE );
を用いてエディットボックスの文字列の表示の更新を
試みているのですが,たとえば,以下のコードのようにボタンをクリックした際に文字列表示の更新を複数回行おうとするとうまくいきません.
具体的には一回目のUpdateData( FALSE );が反映されず二回目のUpdateData( FALSE );のみ反映されるという症状です.

なおm_mojiretsuはCstring型でエディットボックスのDDX用の変数です.

void CMyDlg::OnButton1()
{
DWORD p;

m_mojiretsu=_T("mojirstu1");
UpdateData( FALSE );

/*5秒の待ち*/
p=timeGetTime();
while(1){if((timeGetTime()-p)>5000) break;}

m_mojiretsu=_T("mojirstu1\r\nmojirstu2");
UpdateData( FALSE );

}


何か別の処理を行わなければいけないのでしょうか.
どこかに根本的なミスがあるのでしょうか.

VC歴3日程度で,右も左も分からず大変困っております.よろしくお願いします.

VC++の超初心者です.

UpdateData( FALSE );
を用いてエディットボックスの文字列の表示の更新を
試みているのですが,たとえば,以下のコードのようにボタンをクリックした際に文字列表示の更新を複数回行おうとするとうまくいきません.
具体的には一回目のUpdateData( FALSE );が反映されず二回目のUpdateData( FALSE );のみ反映されるという症状です.

なおm_mojiretsuはCstring型でエディットボックスのDDX用の変数です.

void CMyDlg::OnButton1()
{
DWORD p;

m_mojiretsu=_T("mojirst...続きを読む

Aベストアンサー

m_mojiretsu=_T("mojiretsu1");
UpdateData(FALSE);
UpdateWindow(); // <- これを追加

/*5秒の待ち*/
...

とすれば、ひとまず期待どおりの動作になると思います。

# こうするよりは、OnButton1() では変数を書き換えるべしと言う
# 自前のコマンドメッセージを投げるだけで、すぐに戻った方が
# お行儀は良いのですが...
# そこいらへんは追々調べたり試したりしてみて下さい。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング