よく判らん関数をつくった

えと、オブジェクトをとある点を中心に周回させたい時がしばしばある。こういう時は極座標を用いると便利だ。

  loop
  {
    const float Radius = 100.0;
    static float Phase = 0.0;

    Obj.x = Center.x + Radius * cos( Phase );
    Obj.y = Center.y + Radius * sin( Phase );

    Phase += 2*PI/30;    // 30ループで一周する
  }

Centerってのが回転の中心なんだけど、Radiusを一定にして、Phaseを0〜2PIまでグルグル回してやれば、回転をする。これ頻出。

んで、同じようなパラメータを与えてやると、とある点を中心に四角形を軌跡に描くようにすると何かに使えるかなぁと思った。こんな場合は、下のような関数を作ればいいと思った。

んで、それを実装。既にあるのか知らんですが、SquareSinとでも命名

float ShiftSquareSin( float Angle )
{
  if( Angle < PI )
  {
    if( Angle < PI/2 )  // 0 〜 PI/2のとき
    {
      return 1.0;
    }
    else               //  PI/2 〜 PIのとき
    {
      return 3.0 - 2.0*Angle/(PI/2);
    }
  }
  else
  {
    if( Angle < PI*3/2 )  // PI 〜 PI*3/2のとき
    {
      return -1.0;
    }
    else                  //  PI*3/2 〜 2*PIのとき
    {
      return 2.0*Angle/(PI/2) - 7.0;
    }
  }
}

float SquareSin(float Angle)
{
  return ShiftSquareSin( Angle - PI/4 );
}

float SquareCos(float Angle)
{
  return ShiftSquareCos( Angle + PI/4 );
}

こんな感じ。実際は場合分けを減らすために、PI/4だけずらした関数をつくりました。これで、

  loop
  {
    const float Radius = 100.0;
    static float Phase = 0.0;

    Obj.x = Center.x + Radius * SquareCos( Phase );
    Obj.y = Center.y + Radius * SquareSin( Phase );

    Phase += 2*PI/30;    // 30ループで一周する
  }

こんな風に書くと、キャラが四角く動くって寸法ですね。


ごめん、嘘ついた。固定少数大好きっ子の私はfloatなんて使わないよーだ

int ShiftSquareSin(int Angle )
{
  Angle &= 4095;  // 4096で1周とする単位を使用していて、それを正規化する

  if( Angle < 2048 )
  {
    if( Angle < 1024 )
      return 65536;
    else
      return 65536*3 - (Angle<<7);  // 65536*2*Angle/1024
  }
  else
  {
    if( Angle < 3072 )
      return -65536;
    else
      return (Angle<<7) - 65536*7;
}

int SquareSin(int Angle){return ShiftSquareAngle(Angle-512);}
int SquareCos(int Angle){return ShiftSquareAngle(Angle+512);}