2011/12/17(土)すけーる・よーぴっちろーる・とらんすれーと
コピペして使うがよい。
using System;
class MatrixLib {
/// <summary>
/// 3Dの[拡縮→回転→平行移動]変換行列を作る。
/// </summary>
/// <param name="xScale">X軸方向倍率</param>
/// <param name="yScale">Y軸方向倍率</param>
/// <param name="zScale">Z軸方向倍率</param>
/// <param name="yawRotate">ヨー角度(360.0で一周)</param>
/// <param name="pitchRotate">ピッチ角度(360.0で一周)</param>
/// <param name="rollRotate">ロール角度(360.0で一周)</param>
/// <param name="xTranslate">X軸方向移動量</param>
/// <param name="yTranslate">Y軸方向移動量</param>
/// <param name="zTranslate">Z軸方向移動量</param>
/// <returns></returns>
public static D3DMatrix Transform3D(double xScale, double yScale, double zScale, double yawRotate, double pitchRotate, double rollRotate, double xTranslate, double yTranslate, double zTranslate)
{
  D3DMatrix m = D3DMatrix.Identity;
  double cosYaw = Cos(yawRotate), sinYaw = Sin(yawRotate);
  double cosPitch = Cos(pitchRotate), sinPitch = Sin(pitchRotate);
  double cosRoll = Cos(rollRotate), sinRoll = Sin(rollRotate);
  m.M11 = (float)(xScale * (cosRoll * cosYaw + sinRoll * sinPitch * sinYaw));
  m.M12 = (float)(xScale * sinRoll * cosPitch);
  m.M13 = (float)(xScale * (sinRoll * sinPitch * cosYaw - cosRoll * sinYaw));
  m.M21 = (float)(yScale * (yScale * cosRoll * sinPitch * sinYaw - sinRoll * cosYaw));
  m.M22 = (float)(yScale * cosRoll * cosPitch);
  m.M23 = (float)(yScale * (sinRoll * sinYaw + cosRoll * sinPitch * cosYaw));
  m.M31 = (float)(zScale * cosPitch * sinYaw);
  m.M32 = (float)(zScale * -sinPitch);
  m.M33 = (float)(zScale * cosPitch * cosYaw);
  m.M41 = (float)xTranslate;
  m.M42 = (float)yTranslate;
  m.M43 = (float)zTranslate;
  m.M44 = 1f;
  return m;
}
/// <summary>
/// 2Dの[拡縮→回転→平行移動]変換行列を作る。
/// </summary>
/// <param name="scaleX">X軸方向倍率</param>
/// <param name="scaleY">Y軸方向倍率</param>
/// <param name="angle">回転角度(360.0で一周)</param>
/// <param name="transX">X軸方向平行移動</param>
/// <param name="transY">Y軸方向平行移動</param>
/// <returns>作られた行列</returns>
public static D3DMatrix Transform2D(double scaleX, double scaleY, double angle, double transX, double transY)
{
  D3DMatrix m = D3DMatrix.Identity;
  double cos = Cos(a), sin = Sin(a);
  m.M11 = (float)(cos * scaleX);
  m.M12 = (float)(sin * scaleX);
  m.M21 = (float)(-sin * scaleY);
  m.M22 = (float)(cos * scaleY);
  m.M33 = 1.0f;
  m.M41 = (float)transX;
  m.M42 = (float)transY;
  m.M44 = 1.0f;
  return m;
}
static double Sin(double a) { return Math.Sin(a / 180d * Math.PI); }
static double Cos(double a) { return Math.Cos(a / 180d * Math.PI); }
static double Tan(double a) { return Math.Tan(a / 180d * Math.PI); }
static double Asin(double d) { return Math.Asin(d) / Math.PI * 180d; }
static double Acos(double d) { return Math.Acos(d) / Math.PI * 180d; }
static double Atan(double d) { return Math.Atan(d) / Math.PI * 180d; }
static double Atan2(double y, double x) { return Math.Atan2(y, x) / Math.PI * 180d; }
}
2010/12/14(火)デザインパターンなんて勉強しなくてもいい?
デザインパターンは誰かとプログラムを組むときのコミュニケーションの手段になる。
でも、誰かと協力してプログラムを書くのでなければ、それは必要ない。
本当にそうだろうか。
もしあなたが一人でプログラムを書いていたとしても、
30分前のあなたと協力しなくてはならないし、
1時間前のあなた、3時間前のあなた、昨日のあなた、
先週のあなたと協力しなくては、大きなプログラムは完成しないだろう。
誰かと協力しないでプログラムを組むなんてコトはそうそうない。
誰かって言うのは、文字通り他の誰かかもしれないし、来週のあなたかもしれない。
常に相手にわかりやすいプログラムを書くっていうのはやはり重要だと主張したい。
環境がどんどんよくなっている今の時代では、
覚えておかなきゃいけないことも変わってきているように思う。
関数の使い方は都度IntelliSenceが教えてくれる。
オブジェクト指向やポリモルフィズムがプログラミング言語に取り入れられて、
同時に大量のシンボルや変数に注意を払う必要もなくなっている。
バグは減り、生産性をあげることができている。
忘却の時代。OOPのイディオムやデザインパターンがそれらを支えている。
言語が道具であるのと同じで、デザインパターンも道具であるとは思う。
ある「実現したいこと」がオブジェクトコンストラクタでが十分なのなら、
わざわざFactoryを使う必要もないが、それではできないこともある。
そういうときに、パターンを知っていれば近道ができるという程度のもの。
それはパズルの解法の一つになるのではないかと。
便利だと思ったら使えばいいし、そう思わなかったら勉強しなくてもいいのかもしれない。
それでも、パターンに沿った教科書通りの実装というのは理解しやすいものだ。
ゲームを作るときだって、お決まりのアルゴリズムがあるのと同じぐらいおきまりのパターンがあるのだ。
たしかに、そのパターンに名前はついていないかもしれないけれど、
それをデザインパターンと呼ばずして何と呼ぶんだ。
2010/06/18(金)RenderStateManager.cs
void SetRenderState<T>(RenderState state, T value); T GetRenderState<T>(RenderState state);
SlimDXのDirect3D9のRenderState周りに関してGetとSetメソッドしかない。
なんで RenderStateManagerとかないの? ググったらGone.とか書いてあるページが出てきたけど。
正直不便。なので、Managed DirectXライクに、その辺をラップするRenderStateManagerを作ったりなど。
この辺欲しい人他にもいるんじゃないかなぁと思って公開してみるテスト。
2010/05/31(月)最適化実験+1
クラスライブラリ側がVector3(float, float, float)を要求するとき、
それをラップするクラスはどうするべきかと考えていた。
さらに、内部の型が違う場合について調べてみた。
2010/05/30(日)最適化実験
暗黙的型変換の最適化に関する実験。
2010/05/03(月)mp3infp を C# で使うためのクラスライブラリ
TCO Q.Round1 が rescheduled だったのを知らなかったので、
mp3infp.dll を C#から使えるようにポーティングしていました。
C#からMP3ファイルのタグ情報を取得したいなぁと思ったのですが、
自前でフォーマット読んであーだこーだやるよりは、ライブラリで確実にと。
いつもタグエディタとして大変お世話になっているmp3infpに頼ることにしました。
このクラスライブラリの特徴
- mp3infpが扱えるすべての形式に対応。
- Unicode形式の保存にも対応。
- ソースコードをあなたのプロジェクトにコピペするだけで使える。
- ゆるゆるライセンス
例
    // タグ情報を読み込んで表示してみる。
    Environment.CurrentDirectory = @"E:/Music";
    TagInfo tag1 = MP3infp.LoadTag(@"[丹下桜] SAKURA/14. New Frontier.mp3");
    Console.WriteLine(tag1.Title + " / " + tag1.Artist);
とか
    // ID3v2 タグを ID3v1タグにコピーしてみる
    MP3infp mp3infp = new MP3infp(@"E:/Music/[水樹奈々] PHANTOM MINDS/02. Don't be long.mp3");
    // ID3v1がなかったら作る
    if (!mp3infp.ContainsMP3Tag(MP3infp.MP3TagType.ID3v1))
        mp3infp.AddMP3Tag(MP3infp.MP3TagType.ID3v1);
    TagInfo tag_v1 = mp3infp.LoadTag<TagInfo.MP3_ID3v1>();
    TagInfo tag_v2 = mp3infp.LoadTag<TagInfo.MP3_ID3v2>();
    // コピー元とコピー先で共通して有効な項目のみコピーして保存。
    TagInfo.Copy(tag_v2, tag_v1);
    tag_v1.Save();
    // ID3v2はUnicodeに変換して保存。
    tag_v2.SaveUnicode();
とか、そーいうことをC#からできるようになります。
mp3infpのお陰で、mp3ファイルのID3v1,ID3v2の他、RMPやOGG, WAV, AVI, mp4 などにも対応できるのが嬉しいですね。
素晴らしいプログラムをありがとうございました。
次のソースコードをプロジェクトに追加するだけで使えるよーになります。
ダウンロード
本体: mp3infp.cs (GitHub)
ライセンス: NYSL / http://www.kmonos.net/nysl/
動作に必要: Win32工作小屋 - mp3infp / http://win32lab.com/fsw/mp3infp/
mp3infp自体はLGPLですので、配布の際はご注意ください。
2010/02/27(土)画面の解像度を変える
chgdisp は終了すると戻っちゃうので、というわけでサクっと作った。
僕のマシンには、PATHの通った場所にいくつか簡単なアプリを置いてます。
- 1920.exe 画面解像度を 1920x1080 に変更して終了するだけのアプリ
- 1280.exe 画面解像度を 1280x1024 に変更して終了するだけのアプリ
- 1024.exe 画面解像度を 1024x768 に変更して終了するだけのアプリ
- 800.exe 画面解像度を 800x600 に変更して終了するだけのアプリ
- 640.exe 画面解像度を 640x480 に変更して終了するだけのアプリ
これを、Win+R のファイル名を指定して実行 から呼び出すわけです。
地味に便利です(特に遠隔地からVNCしてるとき)。
しかし、API呼ぶだけのアプリとかCのがラクすぎるだろ……と思った(今はCから移植した)。
2009/10/06(火)GSDKでゲームを作ろう[最終回]
ブロック崩しを作りました。
オブジェクト指向を理解していて、かつ、
ソース内に記述されているコメントを読んだら使い方はわかると思います。
おわり。
今回でめでたくこの連載は終了いたします!
今までご愛顧ありがとうございました!!
ついでにGSDKをバージョン1.1に更新しました。
今回のQoFRのためにいろいろと機能追加とバグフィクスがすさまじいです。
詳しくは、QoFRの開発日誌をご覧ください……
期末が終わるまで 夏休みが始まった 修羅場 その1 修羅場 その2 修羅場 その3 ←この辺の rev番号が若いやつはGSDKのリポジトリログです。
ろくなこと書いてないので役に立たなそうですね。
たぶん、次期バージョンはSlimDX使っての書き直しになるんじゃ? と思うので、
現在のGSDKはこれ以上アップデートしないかもしれません。