ページ 1 / 1
指定した座標から指定した座標の角度の求め方
Posted: 2009年4月15日(水) 22:16
by dic
// ---------------------------------------------------------------
// 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 の計算方法が間違っているとしか
もう検討の余地がないのですが、
上のソースコードのどこが間違っているかを指摘してもらえると助かります
Re:指定した座標から指定した座標の角度の求め方
Posted: 2009年4月16日(木) 01:21
by Justy
>おおよそ検討できる場所としては 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]
Re:指定した座標から指定した座標の角度の求め方
Posted: 2009年4月16日(木) 04:37
by dic
よくわかりませんでしたが
自力でなんとか解決できました
Justyさん ありがとうございました
Re:指定した座標から指定した座標の角度の求め方
Posted: 2009年4月16日(木) 04:47
by dic
ラジアン角度はなんとなく理解できたのですが
習っていないものでして・・・
以下 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;
}