逆三角関数等々。。。
Posted: 2012年11月27日(火) 17:44
お初に質問させていただきます。
現在、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;
}
現在、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;
}