逆三角関数等々。。。

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

逆三角関数等々。。。

#1

投稿記事 by ulllllr » 12年前

お初に質問させていただきます。
現在、2Dのゲームを、このサイトを参考にさせていただきながら、作っているのですが、
プログラミング、そして数学の知識、経験ともに浅く、行き詰ってしまいました。

行き詰った処理というのは、プレイヤーの腕のスプライトの描画処理で、

  マウスの位置によって、腕の角度を変えるために胴体と腕のつなぎ目部分の座標値から、マウスの座標を引くなどして、
  直角三角形の底辺と垂直辺の長さを出して、それをタンジェントに変換 ( y/x) して、
  それをタンジェントから、ラジアンを出す、atan関数に渡し、戻り値を角度に直し、角度によって、スプライトのインデックスを変更し、スプライトの表示を変える。

という、処理です。

一応、コードは書けたのですが、結果が思うように動かず、四苦八苦しています。

ソース。

GetMousePoint( &mx, &my ); //// カーソル座標取得

if(( mx - ( px + 32 )) >= 0 ){ //// マウスカーソルがPlayerの右側にあるとき ////
tgx = mx - ( px + 32 );
tgsangle = 1; //// 表示するスプライトが右側のものか、否かのフラグ 1: 右 0: 左
}
else if((( px + 32 ) - mx) > 0 ){ //// マウスカーソルがPlayerの左側にあるとき ////
tgx = ( px + 32 ) - mx;
tgsangle = 0;            //// 表示するスプライトが右側のものか、否かのフラグ  1: 右 0: 左
}
else {
return 0;
}

if((( py + 16 ) - my ) >= 0 ){ //// マウスカーソルがPlayerの上側にあるとき ////
tgy = ( py + 16 ) - my;
tguangle = 1; //// 上か下か。 1: 上 0: 下
}
else if((my - ( py + 16 )) > 0 ){ //// マウスカーソルがPlayerの下側にあるとき ////
tgy = my - ( py + 16 );
tguangle = 0; //// 上か下か。 1: 上 0: 下
}
else {
return 0;
}

tgr = AngleOut( tgx, tgy ); //// tgr ( 角度格納用 ) に、AngleOut ( x,yの長さから、タンジェント出してラジアン。計算して角度を出す関数 ) に角度を格納。

if( tguangle ){

if( 90 >= tgr && tgr >= 65 ) wep_hgar_sprite = 0; //// 分かりやすいように、このときのスプライトを、 0_sprite とする。
else if( 65 > tgr && tgr >= 45 ) wep_hgar_sprite = 1; //// 同じく、 1_sprite
else if( 45 > tgr && tgr >= 25 ) wep_hgar_sprite = 2; //// 2_sprite
else if( 25 > tgr && tgr >= 5 ) wep_hgar_sprite = 3; //// 3_sprite
else if( 5 > tgr ) wep_hgar_sprite = 4; //// 4_sprite
}

else if( !tguangle ){

if( 5 > tgr ) wep_hgar_sprite = 4; //// 4_sprite 表示するスプライトは、上の4_spriteと同じため。
else if( 5 >= tgr && tgr > 25 ) wep_hgar_sprite = 5; //// 5_sprite
else if( 25 >= tgr && tgr > 45 ) wep_hgar_sprite = 6; //// 6_sprite
else if( 45 >= tgr && tgr > 65 ) wep_hgar_sprite = 7; //// 7_sprite
}


これで、どのようになるかというと、2_sprite, 3_sprite, 5_sprite, 6_sprite, 7_sprite は表示されず、ある程度すると、

  ○×.exe の 0x773915de でハンドルされていない例外が発生しました: 0xC0000094: Integer division by zero

と、表示されるか、

  ○×.ece は停止しました。

と出て、続行不可能になります。


どなたか、ご教示ください。


AngleOut関数 はこんなかんじです。

double AngleOut(
int x, int y //// それぞれ底辺、垂直線 ////
){

double r, tan; //// 角度、タンジェント 格納用 ////

tan = y / x; //// タンジェント格納 ////

r = atan( tan ) * ( 180.0 / 3.14159265358979 ); //// atan()でタンジェントからラジアンを出し、さらにラジアンを角度に変えて、r に格納 ////

return r;
}

nil
記事: 428
登録日時: 14年前

Re: 逆三角関数等々。。。

#2

投稿記事 by nil » 12年前

コードタグを使用してください。
エラーの内容はint型変数が0で除算された、だと思うのですが、
とりあえずはデバッグモードなりを使ってどこでエラーが起こっているのかを調べましょう。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 逆三角関数等々。。。

#3

投稿記事 by softya(ソフト屋) » 12年前

マルチポストですので相互リンクを行なって下さい。 → フォーラムルールhttp://dixq.net/board/board.html

「DXライブラリを用いた、ゲーム制作での三角関数等について。 こんにちは。私は、趣... - Yahoo!知恵袋」
http://detail.chiebukuro.yahoo.co.jp/qa ... 1297835247
補足は使ってしまっているので、向こうにはお礼を書いて、お礼にこちらで質問していることを書き添えて下さい。

向こうでatan2がヒントに出てますが使っていない理由ありますか?
※ こちらは相互リンクするまで回答を控えさせて頂きます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ulllllllr
記事: 5
登録日時: 12年前

Re: 逆三角関数等々。。。

#4

投稿記事 by ulllllllr » 12年前

すみません。
焦っていたもので、つい読み飛ばしてしまっていたようです。
ご指摘ありがとうございます。ただいま、知恵袋の http://detail.chiebukuro.yahoo.co.jp/qa ... 1297835247 のほうでも、お礼とリンクを張ってきました。

atan2 を使用しない理由ですが、ほかのプロジェクトで試しに使ってみた際、上手くいかなかったので、使用していません。
おそらく、自分の使い方がおかしかったのでしょうが、時間が惜しかったため、上手くいった、 atan を使っています。


コードタグも、すっかり忘れていました。申し訳ないです。
もう一度、コードタグをつけて、コードをあげたほうがいいでしょうか?


いまさらですが、OSは windows7 IDEは、 VisualStudio Express 2010 DXライブラリを使って開発をしています。

本当にいろいろと申し訳ないです。
深く反省して、次はないようにしていきたいです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 逆三角関数等々。。。

#5

投稿記事 by softya(ソフト屋) » 12年前

atan2を使ったほうがすっきりするのでatan2をオススメします。
そのまま使わずにx,yを逆にしたり+-をひっくり返す必要性があるかもしれません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ulllllllr
記事: 5
登録日時: 12年前

Re: 逆三角関数等々。。。

#6

投稿記事 by ulllllllr » 12年前

そうですか、ありがとうございます
今から、エラー箇所の特定など含めて、取り組みます。

大体、書き終わったら、今度はコードタグをしっかりつけて、コードを載せたいと思います。

ulllllllr
記事: 5
登録日時: 12年前

Re: 逆三角関数等々。。。

#7

投稿記事 by ulllllllr » 12年前

atan2 に換えてみたところ、いつものようなエラーが起きなくなりました!
ありがとうございます!

変えた部分は、AngleOut 内部のみです。

コード:

double AngleOut(
	double x, double y		//// それぞれ底辺、垂直線 ////
){

	double r;		//// 角度 格納用 ////

	r = atan2( y, x ) * ( 180.0 / 3.14159265358979 );		//// atan()でタンジェントからラジアンを出し、さらにラジアンを角度に変えて、r に格納 ////

return r;
}
ただ、相変わらず、5, 6, 7_sprite は表示されないままです。
もうちょっと調べてきます。なにか、気になるところがありましたら、ぜひ教えてください。

box
記事: 2002
登録日時: 15年前

Re: 逆三角関数等々。。。

#8

投稿記事 by box » 12年前

ulllllr さんが書きました:

コード:

		else if( 5  >= tgr && tgr > 25 ) wep_hgar_sprite = 5;            //// 5_sprite
		else if( 25 >= tgr && tgr > 45 ) wep_hgar_sprite = 6;           //// 6_sprite
		else if( 45 >= tgr && tgr > 65 ) wep_hgar_sprite = 7;           //// 7_sprite
5以下で、かつ、25より大きいなどという状況は起きるはずがないように思います。

あと、私だったら、もっと見やすくなるように下のように書きます。
まあ、好みの問題ですけど。
少なくとも、三角関数を使っているからには math.h をインクルードしているわけで、
処理系がせっかく用意してくれている円周率の値を使うのが筋ではないか、と。
バグを出さない最善と思われる方法は「自分でよけいなコードを書かないこと」だと思います。

コード:

#include <math.h>

double AngleOut(double x, double y)      //// それぞれ底辺、垂直線 ////
{
    return atan2(y, x) * 180.0 / M_PI;       //// atan()でタンジェントからラジアンを出し、さらにラジアンを角度に変えて、r に格納 ////
}
最後に編集したユーザー box on 2012年11月27日(火) 20:38 [ 編集 1 回目 ]
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

ulllllllr
記事: 5
登録日時: 12年前

Re: 逆三角関数等々。。。

#9

投稿記事 by ulllllllr » 12年前

ありがとうございます!

本当ですね。今思えば、何でこんなミスを。。。


戻り値として、関数呼び出し等するやり方があるのですね。勉強になりました。
M_PIですが、私の環境だと、定義されていないと出てしまいます。


これまで、回答してくださった方々、本当にありがとうございました。
初めてのトピック(?)で、迷惑をかけてしまうこともありましたが、大変勉強になりました。
いつか、回答できるような立場になりたいです。
では。

nil
記事: 428
登録日時: 14年前

Re: 逆三角関数等々。。。

#10

投稿記事 by nil » 12年前

M_PIはmath.hをincludeする前に
_USE_MATH_DEFINES
をdefineしないと定義されません。

ulllllllr
記事: 5
登録日時: 12年前

Re: 逆三角関数等々。。。

#11

投稿記事 by ulllllllr » 12年前

ありがとうございます。

閉鎖

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