ページ 11

sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月26日(木) 20:32
by dic
初歩的なところでつまづいたのです
座標(x1,y1) , (x2, y2) がわかtっていてて、これに直線をひいて
sin, cos の値をもとめることができます
しかし、この値からどうやって角度を導きだせるのかでつまづいています

ライブラリなどを使ってもOKです
どういった角度の求め方があるでしょうか?

ソースコードは下のようになっています

コード:

int		CSystem::getToAngle( const tEnemy *enemy, int x, int y )
{
	int		angle = 0;

	double	x1 = enemy->x;
	double	y1 = enemy->y;
	double	x2 = x;
	double	y2 = y;

	double	a = x2 - x1;
	double	b = y2 - y1;
	double	c = sqrt((a*a)+(b*b));

	double	si = b / c;
	double	co = a / c;

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月26日(木) 20:40
by h2so5
atan2(b,a) で角度が出ます。
sin cosを求める必要はありません。

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月26日(木) 21:12
by dic
おお、初めて知りました
理解できましたけど、この戻り値をどうやってラジアン角度から度数の角度に変換するのでしょうか?

==追記
それとも、ラジアンを基準にして作ったほうがいいのだろうか・・・
ちょっと頭がおいつかないなぁ

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月26日(木) 21:20
by box
dic さんが書きました: 理解できましたけど、この戻り値をどうやってラジアン角度から度数の角度に変換するのでしょうか?
πラジアンが180度である、ということを数学で習いませんでしたか?
まだ習っていない年齢の方でしたら、すみません。

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月26日(木) 21:29
by dic
boxさん さんが書きました:πラジアンが180度である、ということを数学で習いませんでしたか?
なるほど そういった性質を利用するんですね

脳みそは・・・多分、高校1年くらいで止まってます

ある程度までは自力で考えようと思います ヒントをありがとうございました

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月27日(金) 00:51
by GRAM
dicさんの質問にそのままの回答をするとしたら標準の数学関数に
acos(コサインから0~πのラジアンへ)
asin(サインから-π/2~π/2のラジアンへ)

というものが存在します。 サインとコサインの符号から範囲を0~2πへ変換することも可能です
座標から角度を知りたいだけでしたらh2so5さんのおっしゃるatan2で十分です

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月28日(土) 20:40
by dic
>>GRAMさん
acos, asin の関数の存在は知っていたのですが、どのような処理をするか知りました
それぞれ、cos, sin から ラジアン角度を出すのですね

今回は atan2関数で導きだせました

ソースは・・・みたい人だけみていってください

コード:

static vector<double> m_vTan;

        // テーブルの作成
	int	i;
	double	pi, a;
	pi = 3.1415926535;
	a = pi / 180;
	for( i=0; i<180; i++ )
		m_vTan.push_back( (-a)*i );
	for( i=180; i<=360; i++ )
		m_vTan.push_back( a*(360-i) );


int		CSystem::getToAngle( const tEnemy *enemy, int x, int y )
{
	int		angle = 0;

	double	x1 = enemy->x;
	double	y1 = enemy->y;
	double	x2 = x;
	double	y2 = y;

	double	a = x2 - x1;
	double	b = y2 - y1;
	double	f;

	f = atan2( b, a );

	int	i;
	double	min = 0.0;

	if( f < 0 )
	{
		min = 0.0;
		for( i=0; i<180; i++ )
		{
			if( f > m_vTan[i] )
			{
				angle = i;
				break;
			}
		}
	}
	if( f > 0 )
	{
		min = 0.0;
		for( i=180; i<360; i++ )
		{
			if( f > m_vTan[i] )
			{
				angle = i;
				break;
			}
		}

	}

	return angle;
}


Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月28日(土) 21:13
by box
aの値が0のとき、すなわち直線がy軸に平行なとき、atan2()の実行に失敗するかもしれません。
変数minの存在意義がちょっとわかりません。

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月29日(日) 00:00
by GRAM
正確には失敗するのはa=b=0の時ですね。a=0だけでは失敗しないでしょう。
同じくminの存在意義はなんなんでしょう?(消し忘れただけ?)

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月29日(日) 10:17
by dic
a = b = 0 のときに失敗するんですね
修正しておきました

double min; は消しわすれです

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月29日(日) 12:02
by たいちう
> a = b = 0 のときに失敗するんですね

正確な仕様を確認しましょう。
http://msdn.microsoft.com/ja-jp/library ... 00%29.aspx

(a == 0 && b != 0), (a != 0 && b == 0), (a == 0 && b == 0)の3つの場合に、
自分はどのような角度が欲しくて、atan2はどのような値を返すのか。
それぞれを比較して失敗なのかそうでないのか、
そして失敗だとしたらどうすべきなのか判断してください。


それとラジアンからの変換方法について誰も突っ込まないのはなんでだろうか?

コード:

int CSystem::getToAngle( const tEnemy *enemy, int x, int y )
{
	double  x1 = enemy->x;
	double  y1 = enemy->y;
	double  x2 = x;
	double  y2 = y;

	double  a = x2 - x1;
	double  b = y2 - y1;
	double  f;

	f = atan2( b, a );

	return f * 180 / 3.141592;
}
さらに、こう。

コード:

int CSystem::getToAngle( const tEnemy *enemy, int x, int y ) {
	return atan2(y - enemy->y, x - enemy->x) * 180 / 3.141592;
}

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月29日(日) 18:32
by ISLe
aとbのどちらも0のとき0を返すのはVisual C++仕様ですよ。
aとbのどちらも0のとき返す値は処理系定義です。

Re: sin, cos の値がわかっている状態での角度のもとめかた

Posted: 2011年5月29日(日) 20:35
by たいちう
> aとbのどちらも0のとき0を返すのはVisual C++仕様ですよ。
> aとbのどちらも0のとき返す値は処理系定義です。

私の貼ったリンク先は、単にVC++の場合(VS2010)ですね。
http://www.bohyoh.com/CandCPP/C/Library/atan2.html
確かに↑を見ると、処理系依存のように書かれていました。

私の書いた「正確な仕様を確認しましょう。」は、
次のように書いた方が良かったですね。
ご指摘ありがとうございました。

「処理系毎の正確な仕様を確認しましょう。
例えば最新のVC++では、次のように定義されています。」