指定した座標から指定した座標の角度の求め方

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
dic

指定した座標から指定した座標の角度の求め方

#1

投稿記事 by dic » 16年前

//	---------------------------------------------------------------
//	Name:	GetForPlayerAngle
//	Desc:	指定した座標からプレイヤーの角度を求めます
//
double	GetForPlayerAngle( double x, double y )
{
	double pi = 3.14159265358979323846264338327950288419716939937510;

	double	a, b, c;

	//	gX, gY プレイヤーの座標
	a = gX - x;
	b = gY - y;
	c = (a+b);

	double	s = b/c;

	static	bool	bFlag = false;
	static	vector<double>	vAngle;

	//	テーブルの初期化
	if( !bFlag ) {
		for( double j=0; j<=pi*2; j+=pi/180 )
		{
			vAngle.push_back(j);
			bFlag = true;
		}
	}

	//	近似値を求める
	double	angle = 0;

	//	実数値 s
	int	i;
	for( i=0; i<vAngle.size(); i++ )
	{
		if( s<vAngle.at(i) ){
			angle = i;
			break;
		}
	}

	HDC	hdc = GetDC( hwndApp );
	MoveToEx( hdc, x, y, NULL );
	LineTo( hdc, gX, gY );
	ReleaseDC( hwndApp, hdc );

	return angle;
}
現在指定した座標x,yからプレイヤーの座標gX,gYへの角度の求める関数を作成中です
そこで三角関数を使い sinの実数値を求め、初期化したテーブルに一番近い値を
角度として判定するものを作っていますが

どうにもうまくいきません

MoveToEx関数などで座標が間違っていないかを描画し確認しているのですが
問題はないようなので どこかで計算が間違っているとかし思えません

おおよそ検討できる場所としては s の計算方法が間違っているとしか
もう検討の余地がないのですが、

上のソースコードのどこが間違っているかを指摘してもらえると助かります

Justy

Re:指定した座標から指定した座標の角度の求め方

#2

投稿記事 by Justy » 16年前


>おおよそ検討できる場所としては s の計算方法が間違っているとしか
>もう検討の余地がないのですが

 何を基準にした角度なのか(真上? 真横?)、sが何を意味しているのか、さっぱりですが、
アプローチが根本的におかしいです。

 仮に sがラジアンだとしても、sとラジアンテーブルを比較して近ければカウンタ値を
角度(degree)とする、という方法もかなり乱暴です。
 きちんと計算で求めるべきです。


 この手の角度の求め方は

シューティングゲームの館
ttp://dixq.net/s/17.html

龍神録プログラミングの館
ttp://dixq.net/rp/13.html

などにも参考になるコードが載っていますし、「ベクトル なす角度」とか
「角度 ラジアン 変換」で検索すればいろいろ出てきます。

 あと、作るときはどこを基準(0度)ととし、どちらの方向を正の方向とするかも考えないといけません。


 参考までに、たとえば始点と終点を結ぶベクトルと真上[0, -1]のなす角度を、時計回りで表した計算は
以下のようになります。

[color=#d0d0ff" face="monospace]
#include <math.h>
#include <float.h>

const double PI = 3.14159265358979323846;

double GetVectorAngle(double fromX, double fromY, double toX, double toY)
{
double dx = toX - fromX;
double dy = toY - fromY;

double len2 = (dx * dx) + (dy * dy);
if(len2 <= DBL_EPSILON)
return 0;

double ang = acos(dy * (-1.0 / sqrt(len2)));
return -dx <= 0? ang: -ang;
}
[/color]

dic

Re:指定した座標から指定した座標の角度の求め方

#3

投稿記事 by dic » 16年前

よくわかりませんでしたが
自力でなんとか解決できました
Justyさん ありがとうございました

dic

Re:指定した座標から指定した座標の角度の求め方

#4

投稿記事 by dic » 16年前

ラジアン角度はなんとなく理解できたのですが
習っていないものでして・・・

以下 sinの実数値から近い角度を求めるようにしてできました

c = a + b; でなく
c = sqrt(a*a+b*b);でしたね
double	GetForPlayerAngle( double x, double y )
{
	double pi = 3.14159265358979323846264338327950288419716939937510;

	double	a, b, c;

	//	gX, gY プレイヤーの座標
	a = gX - x;
	b = gY - y;
	c = sqrt(a*a+b*b);

	double	s = b/c;

	static	bool	bFlag = false;
	static	vector<double>	vSin;

	//	テーブルの初期化
	if( !bFlag ) {
		for( double j=0; j<=pi*2; j+=pi/180 )
		{
			vSin.push_back( sin(j) );
		}
		bFlag = true;
	}

	//	近似値を求める
	double	angle = 0;

	//	例外
	if( -1 == s )	return 270;
	if( 1 == s )	return 90;
	if( 0 == s ){
		if( gX>x )	return 0;
		if( gX<x )	return 180;
	}

	if( s<0 )	s = -s;

	//	実数値 s
	int	i;
	for( i=0; i<vSin.size(); i++ )
	{
		if( s<vSin.at(i) ){
			angle = i;
			break;
		}
	}

	if( (gX<x) && (gY>y) )	angle = 180 - angle;
	if( (gX<x) && (gY<y) )	angle = 180 + angle;
	if( (gX>x) && (gY<y) )	angle = 360 - angle;

	HDC	hdc = GetDC( hwndApp );
	MoveToEx( hdc, x, y, NULL );
	LineTo( hdc, gX, gY );
	ReleaseDC( hwndApp, hdc );

	return angle;
}

閉鎖

“C言語何でも質問掲示板” へ戻る