ページ 11

一周した時の(double)角度について

Posted: 2012年5月12日(土) 01:43
by LisetteLander
角度がPIを跨ぐとき方向などはどのようにして確認したらいいのでしょうか?

角度のデータはdouble型なので
-3.14~3.14の範囲で角度を表現しているのですが

コード:

if(Angle<=PI){
 Angle+=PI*2;
}
if(Angle>=PI){
 Angle-=PI*2;
}
のようなコードを毎フレーム呼び出すと
範囲分岐に支障が出てしまいます。

コード:

#define Fan 1.50
if(Angle<Fan+PI/2 && Fan-PI/2<Angle){}
//角度Angleが、角度Fanから±PI/2分の範囲だった場合
分岐条件側でうまく回避することはできないでしょうか?

Re: 一周した時の(double)角度について

Posted: 2012年5月12日(土) 07:01
by だんごさん
sood さんが書きました:

コード:

if(Angle<=PI){
 Angle+=PI*2;
}
if(Angle>=PI){
 Angle-=PI*2;
}
このangleという変数が最初のif文に入って値が変わります。
ところが次にangle>=PIのif文に引っかかってしまうのではないのですか?
そのため値は常に-PI*2となるのではないでしょうか?

Re: 一周した時の(double)角度について

Posted: 2012年5月12日(土) 12:13
by LisetteLander
このangleという変数が最初のif文に入って値が変わります。
ところが次にangle>=PIのif文に引っかかってしまうのではないのですか?
そのため値は常に-PI*2となるのではないでしょうか?
角度が180度を上回ったら-360度して-180度を表現し
角度が180度を切ったら+360度して+180度を表現してます
なので、使用する値の範囲は2*PI~0(360度~0度)ではなく
PI~-PI(180度~-180度)までを使います。

Re: 一周した時の(double)角度について

Posted: 2012年5月12日(土) 12:27
by box
sood さんが書きました:
角度のデータはdouble型なので
-3.14~3.14の範囲で角度を表現しているのですが

コード:

if(Angle<=PI){
 Angle+=PI*2;
}
if(Angle>=PI){
 Angle-=PI*2;
}
角度が「ちょうどπ」の場合にどうしたいのか不明ですが、
後ろのif文にelseを付ければ解決する、という話ではないでしょうか。
間違っていたらすみません。

Re: 一周した時の(double)角度について

Posted: 2012年5月12日(土) 13:18
by LisetteLander
角度がちょうどPIの時必ず-PI*2になってしまいますね
そこはわかりやすいように直しておきます。
まぁ実際はあまり変わらないでしょうけど・・・

Re: 一周した時の(double)角度について

Posted: 2012年5月12日(土) 13:28
by LisetteLander
質問内容を図にするとこんな感じです。


画像の文章が間違ってて
「角度Funから+-PI/2の範囲にAngleがあるかを判定したい」
です。すいません

Re: 一周した時の(double)角度について

Posted: 2012年5月12日(土) 14:05
by アパナビ
おおおお

[修正] 解決チェックを外しておきました。他人のトピックを無意味にチェックマークする行為は大変失礼に当たります。ご遠慮ください。 by softya(ソフト屋)

Re: 一周した時の(double)角度について

Posted: 2012年5月12日(土) 14:59
by LisetteLander
えええ、解決してませんよ!

Re: 一周した時の(double)角度について

Posted: 2012年5月12日(土) 16:03
by tk-xleader
if(fabs(fmod(Angle - Fun,PI*2)) < PI/2)………

って判定式でいかがですか?

訂正

判定式の引数にミスがあったので訂正します。

Re: 一周した時の(double)角度について

Posted: 2012年5月12日(土) 23:54
by LisetteLander
えーと、提示した角度Angleから範囲基準角度引いて、PI*2で割った余りをがPI/2以下の時
ってことだから・・・

コード:

printfDx("Fun(青線)の角度:%f\n",Angle);
printfDx("○への角度:%f\n",atan2((double)(HungUnitCharacter[i].GetPosY()-PosY),(double)(HungUnitCharacter[i].GetPosX()-PosX)));
if(fabs(fmod(Angle - atan2((double)(HungUnitCharacter[i].GetPosY()-PosY),(double)(HungUnitCharacter[i].GetPosX()-PosX)),PI*2)) < PI/2){
	printfDx("現在PI/2範囲内です");
}
そしたら画像のようになりました。
画像中央(PosX,PosY)から画面中に見える青色の○に対して範囲内か範囲外かを判定しています。
この時御土居色の線はFunから±PI/2の境界を表しています。
無題.png
無題.png (31.24 KiB) 閲覧数: 11943 回
無題2.png
無題2.png (20.76 KiB) 閲覧数: 11943 回
やはり下記のコードで変換されると判定できないんでしょうか

コード:

if(Angle<PI){
 Angle+=PI*2;
}
if(Angle>PI){
 Angle-=PI*2;
}

Re: 一周した時の(double)角度について

Posted: 2012年5月13日(日) 01:14
by ISLe
数学関数とキャラクター座標のY軸方向は一致してますか?

Re: 一周した時の(double)角度について

Posted: 2012年5月13日(日) 02:13
by LisetteLander
引数の順番ということでしょうか?
確かにatan2はy,xにひっくり返っていたので入力支援に従って記述しました。
もしくはY座標は画面下に行くに連れて大きくなるというのと
数学上ではY軸は画面上に行くに連れて大きくなるということでしょうか?
後者は意識してないですが・・・

Re: 一周した時の(double)角度について

Posted: 2012年5月13日(日) 10:03
by tk-xleader
sood さんが書きました:やはり下記のコードで変換されると判定できないんでしょうか

コード:

if(Angle<PI){
    Angle+=PI*2;
}
if(Angle>PI){
    Angle-=PI*2;
}
そもそもこのコードって、Angleを0≦Angle<PI*2の間に補正しているコードですよね。でしたら、次のように書かないとまずいのではないでしょうか?

コード:

if(Angle >= PI*2){
	while(Angle >= PI*2){
		Angle -= PI*2;
	}
}else if(Angle < 0){
	while(Angle < 0){
		Angle += PI*2;
	}
}
まぁ、if文はなくてもいいんですけどね。ところで、fmod関数を使う場合、先に差の絶対値を取ったほうが良かったようです。ですから、次のコードだとうまく動くかもしれません。

if(fmod(fabs(Angle - atan2((double)(HungUnitCharacter.GetPosY()-PosY),(double)(HungUnitCharacter.GetPosX()-PosX))),PI*2)) < PI/2)………

Re: 一周した時の(double)角度について

Posted: 2012年5月13日(日) 11:53
by LisetteLander
角度をマイナスにするのはやめたほうがいいんですか
あ、そうするとやっぱり余りを求めることでうまく動きそうですね

Re: 一周した時の(double)角度について

Posted: 2012年5月13日(日) 15:18
by LisetteLander
角度って左回りに+ですよね、
例えば

コード:

DrawCircle(X,Y,10,COLOR,0);
DrawLine(X,Y,cos(PI/2)*100+X,sin(PI/2)*100+Y,COLOR,0);
このようなとき上を向いているはずですよね

Re: 一周した時の(double)角度について

Posted: 2012年5月13日(日) 15:22
by LisetteLander
ISLe さんが書きました:数学関数とキャラクター座標のY軸方向は一致してますか?
あぁ・・・

Re: 一周した時の(double)角度について

Posted: 2012年5月13日(日) 15:37
by LisetteLander
この○の位置でマイナス角度はおかしいし、凸字の角度もおかしい

コード:

printfDx("○への角度:%f\n",atan2((double)(HungUnitCharacter[i].GetPosY()-PosY),(double)(HungUnitCharacter[i].GetPosX()-PosX)));

Re: 一周した時の(double)角度について

Posted: 2012年5月13日(日) 22:54
by ISLe
sood さんが書きました:
ISLe さんが書きました:数学関数とキャラクター座標のY軸方向は一致してますか?
あぁ・・・
描画座標のY軸の正方向は下ですから、数学関数に素直に従えば角度は右回りになります。
atan2の戻り値は-π~πの範囲で、画面の上方向がマイナスです。

角度を使って座標を求めるとき(左回りになるように)上下反転させたりしてないですか?

Re: 一周した時の(double)角度について

Posted: 2012年5月14日(月) 02:11
by LisetteLander
math.hの関数の引数のY成分を符合逆にしたら欲しい結果がでました。

Re: 一周した時の(double)角度について

Posted: 2012年5月14日(月) 02:42
by LisetteLander
if(fabs(Angle - atan2(-(double)(HungUnitCharacter.GetPosY()-PosY),(double)(HungUnitCharacter.GetPosX()-PosX)))<PI/2){}


(現在の角度-○への角度)の絶対値がPI/2以下の時
180度(-180度)をまたがない状態で綺麗に表現できる条件分岐だと思います。
しかし180度を跨ぐとNo:6の画像みたいに判定してくれなくなります。


また、言うのが遅れましたが角度は0~PI*2 ではなく-PI~PIを使いたいです。

Re: 一周した時の(double)角度について

Posted: 2012年5月14日(月) 02:50
by LisetteLander

コード:


if(fabs(Angle - atan2(-(double)(HungUnitCharacter[i].GetPosY()-PosY),(double)(HungUnitCharacter[i].GetPosX()-PosX)))<PI/2){
 tmp=fabs(Angle - atan2(-(double)(HungUnitCharacter[i].GetPosY()-PosY),(double)(HungUnitCharacter[i].GetPosX()-PosX)));
}else{
 tmp=PI*2-fabs(Angle - atan2(-(double)(HungUnitCharacter[i].GetPosY()-PosY),(double)(HungUnitCharacter[i].GetPosX()-PosX)));
}

if(tmp<PI/2){
 printfDx("前方180度以内にいる!");
}

printfDx("\n");

if(fmod(fabs(Angle - atan2(-(double)(HungUnitCharacter[i].GetPosY()-PosY),(double)(HungUnitCharacter[i].GetPosX()-PosX))),PI*2) < PI/2){
 printfDx("tkmakwins15さんが前方180度以内にいる!");
}
なんかよくわからないけど上の判定が希望通りできました。
でもこれって上の分岐と下の分岐の違いがよくわからないですけどどう違うんでしょうか