2009年06月16日

ゲーム数学5(円と線分の当たり判定)

円と線分との当たり判定

ソースを見ていたら、昔作った円と線分との当たり判定の関数が出てきましたので公開してみます。

内容としましては、半径rの円の中心(x, y)(sx1, sy1)(sx2, sy2)を結ぶ線分との当たり判定です。
考え方としては円の中心から線分へ垂直に交わる直線を想定し、その交点を求めます。
その交点は円と直線との最短距離になりますのでその点から円の中心の距離と半径の長さを比べて当たり判定しています。



  /**
   * 円と線分の当たり判定
   */
  public void judgeHitScopeLine(int sx1, int sy1, int sx2, int sy2) {
      int dx, dy;
      
      // 線分の端と端の距離をx,y軸個別に求めます
      int sx = sx2 - sx1;
      int sy = sy2 - sy1;
      
      // x軸方向に位相差が存在する場合は円の中心から線分へ垂直に交わる直線と線分の交点を求めます。
      if(sx != 0) dx = ((y-sy1)*sx*sy + x*sx*sx - sx1*sy*sy) / (sx*sx + sy*sy);
      // 位相差がない場合はsx1=sx2になっているので線分のx方向の位相差はない
      else dx = sx1;
      
      // y軸方向の位相差が存在する場合は円の中心から線分へ垂直に交わる直線と線分の交点を求めます。
      if(sy != 0) dy = ((x-sx1)*sx*sy + y*sy*sy - sy1*sx*sx) / (sy*sy +sx*sx);
      // 位相差がない場合はsy1=sy2になっているので線分のy方向の位相差はない
      else dy = sy1;
      
      // 当たり判定する必要があるか
      if(isjudgeHitScopeLine(sx1, sy1, sx2, sy2)) {
          // 円の中心から求めた交点の距離と半径を比べて当たり判定する
          if((x-dx)*(x-dx)+(y-dy)*(y-dy) < r*r) return true; 
      }
      return false;
  }
  /**
   * 当たり判定するかどうかの判定
   */
  private boolean isjudgeHitScopeLine(int sx1, int sy1, int sx2, int sy2) {
      // 線分の端から円と接触している可能性があるかどうか判定する
      if(x <= (Math.max(sx1, sx2) + r) && x >= (Math.min(sx1, sx2) - r)) {
          if(y <= (Math.max(sy1, sy2) + r) && y >= (Math.min(sy1, sy2) - r)) return true;
      }
      return false;
  }

ラベル:六本木店長
posted by ラクサス at 11:53| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2009年06月09日

tail -f でログファイルを出力するときに、文字コードを変換する方法

linuxなどで、OSの文字コードとログファイルの文字コードが異なるため、「tail -f test.log」 でログを出力すると文字化けする場合は、以下のコマンドで解決します。


tail -f test.log | nkf -u -e (EUCに変換)
※OSがEUCで、ファイルがUTF-8などの場合

tail -f test.log | nkf -u -w
 (UTF-8に変換)
※OSがUTF-8で、ファイルがEUCなどの場合

ポイントはnkfの「-u」オプションです。
-u : 出力時に、バッファリングしない。
ラベル:どなん
posted by ラクサス at 19:36| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2009年02月02日

ゲーム数学4

ゲームの基本は当たり判定なので
今回も当たり判定の話をしたいと思います。

球と球(バウンディングスフィア(以下BS))の当たり判定を使うと処理は軽くなりますが
判定する範囲が大雑把になるという弱点もあります。
そこでBSで当たり判定する方法のひとつを紹介します。

説明しやすいので人間の例で説明します。

まず間違った例です。
体の回りに大量の小さな球を配置し、すべての球と当たり判定を行う。
これは非常に処理が重くなるし、BSを使う最大の理由「処理が軽い」に反した行為です。
これでは意味がありません。


右手を限定して話を進めます。

1.まず手をまっすぐ上に挙げた手の先から地面までをすっぽり包む球と当たり判定を行います。

2.当たっているとすると右肘から右手先まで包む球と当たり判定を行います。

3.当たっているとすると右手を包む球と当たり判定を行います。



こうすることで当たっている可能性が高い物にだけ細かい当たり判定をする仕組みにします。
例の場合は極端に3回順を追って当たり判定しましたが、
普通のゲームの場合2回。場合によっては3回ほど順を追えばかなり正確に当たり判定できます。
これにより無駄の処理を省き軽く、しかも正確に当たり判定することが可能です。
ラベル:六本木店長
posted by ラクサス at 11:55| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2009年01月16日

ゲーム数学3

前回は静止時の球と球との当たり判定を記述しましたが
これではゲームに適応することはできません。

ゲームの球というのは常に動き回っているので
動く球と球との当たり判定が必要になってきます。


半径RAの球Aが(XA,YA,ZA)にあり1フレームごとに(xa,ya,za)動くとします。
半径RBの球Bが(XB,YB,ZB)にあり1フレームごとに(xb,yb,zb)動くとします。
この2つの球の当たり判定を行います。



まず考えなくてはならないのは前フレームに球A,Bはどこにあったかということです。
球Aが(XA-xa,YA-ya,ZA-za)に球Bが(XB-xb,YB-yb,ZB-zb)にあったことがわかります。
つまりこの2点でしか当たり判定していないので、
球Bが画面真ん中にあり、球Aが画面端から端まで1フレームで移動してしまった場合当たり判定されず
球Aが球Bをすり抜けてしまうバグが発生します。
ここで0<t<1 媒介変数tを使い、この間に存在したはずの当たり判定を行います。
小数点は使いたくないので10倍して行います。


for (int t = 0; t < 10; t++) {
  int XX = ((XA*10)-xa*t) - ((XB*10)-xb*t);
  int YY = ((YA*10)-ya*t) - ((YB*10)-yb*t);
  int ZZ = ((ZA*10)-za*t) - ((ZB*10)-zb*t);
  if (XX*XX + YY*YY + ZZ*ZZ <= (RA+RB)*(RA+RB)*100) {
    // 当たってるよ
  }
}



媒介変数tを回す回数は球の大きさや移動距離と判定する精度、処理の重さなどによって調整が必要です。
今回は整数型で行いましたが、浮動小数点型でも行うことは可能です。
ラベル:六本木店長
posted by ラクサス at 16:14| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2009年01月06日

ゲーム数学2(バウンディングスフィア)

今回は当たり判定の基本の球と球との当たり判定(バウンディングスフィア)
についてお話したいと思います。


半径RAの球Aが中心(XA,YA,ZA)にあるとき
半径RBの球Bが中心(XB,YB,ZB)と当たり判定を行う


ルート処理を入れると重くなるために二乗した状態で判定を行います。


if ((XA-XB)*(XA-XB) + (YA-YB)*(YA-YB) + (ZA-ZB)*(ZA-ZB) <= (RA+RB)*(RA+RB)) {
// 当たってますよ
}



接してる時当たり判定したくない場合は

if ((XA-XB)*(XA-XB) + (YA-YB)*(YA-YB) < (RA+RB)*(RA+RB)) {
// 当たってますよ
}

とイコールをはずせば判定できます。
ラベル:六本木店長
posted by ラクサス at 15:41| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2008年10月21日

ゲーム数学1

私がRAXUSにはいる前勤めていたのがゲーム会社でしたので
若干ですがゲーム数学について書きたいと思います。

一番最初にゲームを作る際に向いているのがシューティングです。
今回はシューティングの玉の軌道の管理についてです。

まず玉の軌道を考える上で大切なのは『軸』です。
今回は2次元軸でお話しますので「X軸」と「Y軸」で考えます。
普通の数学と違って左上を基準に考えるので「Y軸」の動きが逆となります。
それと、もうひとつ必ず『軸』が存在しましす。
ものが運動する場合必ず『時間軸』というものが重要になってきます。
この「X軸」「Y軸」「時間軸」を管理することによって玉の運動が実現できます。


今回は"Y=X*X"(二次曲線)の軌道を描く玉を考えて見ましょう。
ただし、1秒ごとに常にX軸方向に1動くものとします。




ここで「X軸」「Y軸」「時間軸」の3次元で考えないといけないと思ってはいけません。
そう考えるとここで行き詰まる可能性が高いです。
ここで考えないといけないことは " X軸とY軸の運動を別々にして考える " ことです。
つまり、『「X軸」と「時間軸」の運動』と『「Y軸」と「時間軸」の運動』とで分けて考えるわけです。

まず「X軸」と「時間軸」の運動を考えて見ましょう。
秒単位の時間経過の変数を仮に「T」とした場合、
「1秒ごとに常にX軸方向に1動くものとします。」と書いてありますので
1秒後はX=1、2秒後はX=2、3秒後は・・・つまり"X=T"となるわけです。

次に「Y軸」と「時間軸」の運動を考えて見ましょう。
「X軸」と「Y軸」は同じ時間軸上に成り立っていますので、時間的に同期しないといけません。
なので「X軸」と同じ時間経過の変数を「T」とします。
"Y=X*X"と先ほど出した"X=T"を組み合わせて解くと"Y=T*T"と求められます。

blogネタ20080925.JPG

つまり座標で書くと、(X, Y)=(T, T*T)に表示し、Tを更新し続ければ完了です。
少し改良すれば横に向かって放たれた大砲の弾の軌道なんかもすぐに実装できます。
また、3次元で考える場合はおなじように「Z軸」と「時間軸」の運動を増やすだけで実現できます。

ラベル:六本木店長
posted by ラクサス at 14:24| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2008年09月12日

SSD(フラッシュメモリードライブ)

SSDとは"Solid State Drive"の略で別名フラッシュメモリードライブと呼ばれ、ハードディスクドライブ(以下HDD)と同じ規格のインターフェイスを持っています。
今このSSDがHDDに代わる高速記憶媒体として注目されています。

SSDはHDDのようにディスクを持ちません。
なので、データの読み書き時HDDのような物理的な手間(読み取り装置をディスク上で移動させ、ディスク上の目的のデータがヘッド位置まで回転させる手間)が必要ありません。
このため、HDDに比べてデータの読み書きが高速化されています。
どれくらい高速かというと順次読み出しで、HDDが約100MB/秒なのに比べてSSDは一番速い物で約250MB/秒。ランダム読み出しだとHDDが約70MB/秒なのに比べてSSDは約170MB/秒。
現在でもHDDに比べて倍以上の速度が出ますが、まだSSDはさらに読み込み速度が高速化されるかと思います。
また消費電力の面でもHDDのようにディスクを回転させる必要がないため、大幅に少なくなっています。
さらに、ディスクを回す駆動部分やディスクの読み書きのためのヘッドが存在しないため、耐衝撃性もHDDに比べて高いです。

「じゃあSSDにすればいいじゃないか」という話になりそうですが、フラッシュメモリはハードディスクに比べて非常に高価なため、今現在では市販されているもので最大容量で128GBほど。
値段はというと5万円から10万円するものまであります。
500GBが1万円ほどで買えてしまうHDDに比べるとコストパフォーマンスは非常に悪いです。
つまり、今現在ではSSD単体での活用が難しく、頻繁にアクセスするデータはSSDに保存しておき、使う頻度が少ないデータや普段使わないデータなどはHDDに保存しておくといった、HDDとSSDを併用で使用するような方法が今一番SSDを活かせる使い方だと思います。
ラベル:六本木店長
posted by ラクサス at 11:04| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2008年09月05日

forループを高速化する方法

forループを高速にする方法は、ループ内で処理をどれだけ少なくするかが重要ですが、逆に処理を遅くしている処理がないか確認してみましょう。

よく、配列の分だけforでループする処理を行いますが、ループする回数はcount関数を使って数えます。
このとき、ありがちな書き方として、forの条件文の中でcount関数を使ってはいないでしょうか。

for($i=0; $i<count($ary); $i++)
{
    処理
}

この書き方ですと、forがループするたび配列の数を数えることになり、非常にコストがかかります。


実際に実験してみます。

// 配列を作成
for($i=0; $i<100000000; $i++)
{
    $ary[$i] = $i;
}

echo "開始->" . date("H:i:s") . "<br>\n";

// forの条件で毎回countした場合
for($i=0; $i<count($ary); $i++)
{
    $a++;
}

echo "終了->" . date("H:i:s") . " $a 回<br>\n";


echo "開始->" . date("H:i:s") . "<br>\n";

// 先にcountした場合
$cnt = count($ary);
for($i=0; $i<$cnt; $i++)
{
    $b++;
}

echo "終了->" . date("H:i:s") . " $b 回<br>\n";


開始->16:11:05
終了->16:11:10 10000000 回

開始->16:11:10
終了->16:11:12 10000000 回



今回の環境では、count関数の書く場所により2倍以上の差が出ました。
ちょっとした書き方の違いで性能が大きく変わるので、気をつけましょう。
ラベル:どなん
posted by ラクサス at 12:39| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2008年09月03日

タスクバー操作

仕事中や作業中にWindowsのタスクバーの表示の順番を入れ替えたいとか思ったことはありませんか?
ウィンドウを閉じてから開きなおすと入れ替わりますが面倒・・・
グループ化すると一応並べ代わりますが、開く個数が多いとまとめられて、何を開いてるのか分からないとか自分は良く起こります。

そういう時非常に役立つのが『Taskbar Shuffle』というソフトです。
このソフトは単純でドラッグアンドドロップでタスクバーの表示順を入れ替えることができます。
フリーソフトな上に非常に強力なので同じ悩みを持っている方にはぜひ使って欲しいです。
ソフト名で検索を掛ければDLサイトが出てくると思いますので、ぜひ使ってみてください。
ラベル:六本木店長
posted by ラクサス at 15:16| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2008年08月29日

パイオニアが16層400Gの光ディスクを開発

パイオニアがBlu-rayと同じ25G容量の光ディスクを16層に重ねて400Gの大容量再生専用光ディスクを開発しました。
再生していない他の記録層からのノイズを低減する構造を採用し、1層から16層までの読み込み精度もかなり高いと見られます。
しかも対物レンズの光学的仕様はBlu-rayの規格と同じであるため、互換性を持つことも可能だそうです。

しかし、問題なのは読み込み速度です。
Blu-rayドライブが市販の最速5倍速などですので、この速度で400G読み込んだとして最速で(60/5)*16=192分かかる計算になります。
3時間以上かかりますが、これは理想値で現実的にはさらに倍の6時間以上かかるのではないかと思います。
読み込み速度の問題で実用化はまだまだ先と思われます。

また、今回開発されたのは再生専用のディスクですが、記録型ディスクにもこの技術は使えるという発表もあり、パイオニアは今後大容量光ディスクの実現に向けて研究開発を進めるということです。

次世代光ディスクではないですが、記憶媒体として面白い技術だと思いますので、今後の動向に注目したいです。
ラベル:六本木店長
posted by ラクサス at 11:11| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2008年07月28日

自宅サーバNO.2(DNSサーバ)

サーバ構築の中でDNSサーバというものが出てきます。
DNSサーバとは、Domain Name Systemの略語でネームサーバと呼ぶ場合もあります。

DNSサーバの役割は、ドメイン名のIPアドレスやメールアドレスのメールサーバ名などを
検索しアクセスしてきた通信に教えてあげることです。
このときにドメイン名からIPアドレスを教えてもらう場合は正引き、
逆にIPアドレスからドメイン名を教えてもらう場合は逆引きといいます。

DNSサーバには 2種類あります。
まずDNSコンテンツサーバ。ドメイン名の管理しています。
次にDNSキャッシュサーバ。ドメイン名の検索業務をおこないます。

普通は、DNSサーバといえばDNSキャッシュサーバのことをさします。
「ネットワーク設定」などで入力しているのはこのDNSキャッシュサーバのIPアドレスです。
また、この2つのサーバの役割を間単に説明します。

  • DNSコンテンツサーバ
DNSコンテンツサーバの役割は、自分で管理するサーバのIPアドレス等のリソースレコードを保持し、
要求があったとき、それを返却することです。

  • DNSキャッシュサーバ
DNSキャッシュサーバの役割は、DNSクライアントから名前解決を依頼されたとき、
検索を行い、ドメイン名の解決を行うことです。

また、自宅サーバを立ち上げる際にDNSサーバ設定で注意してほしいのがIPアドレスです。
DNSサーバとは登録したドメインからIPアドレスを呼び出すものなので
接続をする毎々にIPアドレスが変わっていては毎回DNSサーバの設定を変えることになります。
IPアドレスが変わっているのに、DNSサーバの設定を変えてないということになると
自分のドメインから他人のPCにアクセスが行ってしまいます。
そこで、固定IPアドレスを取得してしまえば煩わしい設定を変える必要も
他人にアクセスが行ってしまう危険もなくなります。
ラベル:六本木店長
posted by ラクサス at 15:54| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2008年07月23日

自宅サーバNO.1(IPアドレス)

最近自宅にサーバを立てようと思い立ち
一台パソコンを潰してLinux(centOS5.1)を入れました。

色々設定していくうちに良く出てくるのがIPアドレス。
その中にもプライベートIPアドレスとグローバルIPアドレスというものがあります。
知っている方も多いと思いますが、
グローバルIPアドレスとはインターネットを利用し、メールの送受信やWeb閲覧など行うためには
必須のものとなります。
グローバルIPは同じアドレスを複数のマシンへ付与できないので、限りがあります。
このため、企業内LANなど大量にパソコンを同一グローバルIPアドレスを使えるように
別にPCに割り当てたアドレスをプライベートIPアドレスといいます。
ゆえに、サーバへ内部アクセスする場合はプライベートIPがあればできますが、
外部アクセスをする際にはグローバルIPアドレスが必要になってきます。

プライベートIPアドレスとグローバルIPアドレスはIPアドレスが枯渇しないようにするための
技術とも言えなくもないと思います。

それでもIPアドレスがアジア諸国のインターネットの普及により枯渇してきています。
IPアドレスの枯渇の回避技術としてNATやIPv6というものがあります。

まずNATについて調べてみました。
NATとはインターネットを利用する際に、利用しようとしているプライベートIPアドレスに
一時的にグローバルIPアドレスを貸し出すという技術。
もちろん利用が終わればそのグローバルIPアドレスの割り当てを解除します。
ただし、実際に新しいグローバルIPアドレスを割り当てるのではなく
インターネットとネットワークの間をパケットが通り過ぎるときに
そのパケットを書き換えて、グローバルIPアドレスを持っているように振る舞わせます。
このときに発生するアドレスの書き換え処理のことをNAT(ネットワークアドレス変換)と言います。
この技術で、少ないグローバルIPアドレスでも、
複数のノードに対してインターネットへのアクセスを提供できます。
また、各ノードに対してグローバルIPアドレスを付ける必要がないので、
IPアドレスを節約できるだけでなく、インターネットから隔離することができます。
これはセキュリティから考えても非常に有用であることが分かります。

そして次にIPv6という技術です。
現在一般的に使用されているインターネットプロトコルIPv4に変わるものです。
IPv4が約4.3e+9個IPアドレスをもてるのに対し、IPv6は約3.4e+38個もてます。
IPv6では今までのIPアドレスと違う構造を持ちます。
今は32bitIPアドレスが一般的ですが、IPv6では128bitに表示になります。
また"."ではなく":"で区切ります。
[例] 255.255.255.255  →  ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff

いたるところでこれが普及すればIPアドレスの枯渇問題は解決されそうですが、
普及については、IPv4と似ているものの互換性は無いため、
ルータの取替えや新しいソフトウェアの開発・導入などで、お金がかかるため
いろいろなところで導入するまでに時間がかかりそうです。
しばらくはIPv6普及することはないですが、一応知識として持っておいて損ではないと思います。
ラベル:六本木店長
posted by ラクサス at 13:51| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする

2008年07月11日

携帯電話通信3G→4G

FOMAやソフトバンクの3G端末など次世代携帯通信と言われていました
3G(第3世代携帯)もその普及に伴って、当たり前に使っている方が非常に多いと思います。
そしてさらに次世代携帯として2010年頃登場するのが4G(第4世代携帯)です。

急に3Gより4Gに切り替わるわけではなく、間の世代というものが存在します。
FOMAハイスピードや3GハイスピードがそれにあたるものでHSDPA(High Speed Downlink Packet Access)と呼ばれています。
これが間の世代にあたるもので、「3.5G」とも呼ばれています。
Docomoはさらに「スーパー3G」というものを企画していて、これは「3.9G」などと呼ばれます。

3.5Gは3Gの転送速度の約5倍ですが、さらに3.9Gは3.5Gの転送速度の約2倍〜3倍といわれています。
4Gはさらに高速化を実現し、移動環境で100Mbps、準静止状態では1Gbpsと定義されています。

携帯電話の高性能化や、高速通信化にともなって、やることができることの幅が非常に広がってきています。
サービスの幅も広がり、携帯電話のサービスへの需要もさらに高まっていくでしょう。
一例としてストリーミグ高画質動画配信サイトのサービスやFlashLiteも更なる発展を見せるでしょうから、
それを利用したサービスなど多々考えられます。
そこで、いち早く次世代携帯の技術を身につけサービスを提供することは
ビジネス的にも経験的にも非常に重要なことだと思います。
ラベル:六本木店長
posted by ラクサス at 15:48| Comment(0) | TrackBack(0) | 技術情報 | このブログの読者になる | 更新情報をチェックする
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。