どうしてこのエントリーでWiiremoteの話をしないといけないのか、なんとなく 微妙ですが、まあいいや。 http://ameblo.jp/akihiko/entry-10047227655.html 傾き検出は、kako.comで公開されているコードをよく読んでください。 ただし(私が過去に読んだソースですが)「ズバリ正解」ではありません。 (グラフィックス上で傾きが表示されると言う意味では正解) X/Yなど比で、傾きに関係した値が出るのはたしかですが「これが何を意味する のか?」を考えてみてください。 高校生でもわかる「数学1的」に考えると「CosやSinをどうやって算出するか、 それが何を意味するか」ということに直結します。 上の話が、まったく「なんだかわけが判らない」という状態であれば、勉強もか ねて、比→傾き(の正負の極性)→角度まで算出してみるといいでしょう。 実際のプログラミングでは、アークサイン「asin」関数を使うと便利でしょう。 ただし、値はラジアンで与えなければならないので、以下のような式を使います。 Rotx = asin(RUx)180.0f/PIE; Roty = asin(RUy)180.0f/PIE; さらにZ軸については、とある理由から、こういう処理をします。 if (RUz<0.0f) { Rotx = 180.0f - Rotx; } if (Roty>90.0f) { Roty = 180.0f - Roty; } まさに数学1!なんですけど…勉強になりましたか? 以下、私が使っている角度算出部分のソースコード抜粋です。 コメントが一杯残ってますが、ご愛嬌。 //Aki le 7 mars 2007 double Wii_Remote_Input2(void) { static LARGE_INTEGER last,current; static double dt = 0.0f; //delta time (msec) static unsigned char lAx,lAy,lAz; //last acc value for filter ReadReport( hRsDevHandle , InputReport, &InputLength); if ( InputReport[0]==0x30 ) { button1=InputReport[1]; button2=InputReport[2]; } if ( InputReport[0]==0x31 ) { button1=InputReport[1]; button2=InputReport[2]; Wx = (Wx + InputReport[3]) /2.0f; Wy = (Wy + InputReport[4]) /2.0f; Wz = (Wz + InputReport[5]) /2.0f; //get current posture (rotation) Rx = (double)( Wx - Ox ) / 127.0f / ADXL330 ; Ry = (double)( Wy - Oy ) / 127.0f / ADXL330 ; Rz = (double)( Wz - Oz ) / 127.0f / ADXL330 ; R = sqrt (Rx * Rx + Ry * Ry + Rz * Rz ) ; double RUx,RUy,RUz; //unit vector RUx = Rx / R; RUy = Ry / R; RUz = Rz / R; // printf(“(Rx,Ry,Rz) ,R , Unit(R)= (%f,%f,%f), %f, (%f,%f,%f) “, Rx, Ry ,Rz, R, RUx, RUy ,RUz); //Get rotation degree // Rotx = asin(Rx/Ry)180.0f/PIE; Rotx = asin(RUx)180.0f/PIE; Roty = asin(RUy)180.0f/PIE; if (RUz<0.0f) { Rotx = 180.0f - Rotx; } if (Roty>90.0f) { Roty = 180.0f - Roty; } // Rotz = asin(RUy/RUx)180.0f/PIE; Rotz = 0.0f; // printf(“Rot(%f,%f,%f)\n”, Rotx, Roty ,Rotz ); //Cancel the initial gravity Ax = Rx - RUx * Gravity; Ay = Ry - RUy * Gravity; Az = Rz - RUz * Gravity; A = sqrt (Ax * Ax + Ay * Ay + Az * Az ) ; // printf(“(Ax,Ay,Az) ,A = (%f,%f,%f), %f\n”, Ax, Ay ,Az, A); //Get delta time last = current; QueryPerformanceCounter( ¤t ); QueryPerformanceFrequency( &freq ); dt= (double)(current.QuadPart - last.QuadPart) / (double)freq.QuadPart; //microsec //the first time or huge delay if ((dt==0) |
|
(dt>100)) { //you shouldn’t use the data in this time dt = 0.0f; //dt=0 means the velocity also be zero. } //Filter, if the input is lower than the Gravity, Ignore it. if (A>Gravity/5.0f) { //Get a velocity in this delta time (the initial gravity canceled) VCx = dt * Ax; VCy = dt * Ay; VCz = dt * Az; VC = sqrt (VCx * VCx + VCy * VCy + VCz * VCz ) ; // printf(“(VCx,VCy,VCz), VC = (%f,%f,%f), %f\n”, VCx, VCy ,VCz, VC); } else { VCx = VCy = VCz = VC = 0.0f; } } return dt; } |