<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title>Codelogy</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/" />
   <link rel="self" type="application/atom+xml" href="http://www.codelogy.org/atom.xml" />
   <id>tag:www.codelogy.org,2008://28</id>
   <updated>2008-08-01T07:21:17Z</updated>
   
   <generator uri="http://www.sixapart.com/movabletype/">Movable Type 3.33-ja</generator>

<entry>
   <title>3Dモデルファイルの独自形式制作（１回目）</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/08/3d.html" />
   <id>tag:www.codelogy.org,2008://28.10908</id>
   
   <published>2008-08-01T03:03:33Z</published>
   <updated>2008-08-01T07:21:17Z</updated>
   
   <summary> 3D系プログラムをしていると、どうしてもついて回るのが読み込みモデリングファイ...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="C++" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
3D系プログラムをしていると、どうしてもついて回るのが読み込みモデリングファイルの形式です。<br>
私は普段DirectXを使っていますので、標準形式のXFileを使えばよいではないかということになりそうですが、XFileの方言はひどいものがある上に上位にあたるXNAではXFileをサポートしないといったことになっており散々です。<br>
よくデザイナーさんが使うmaya, 3ds max, LightWave3Dなどのソフトがありますが、それぞれのエクスポーターで出力するXFileも方言があり、Root Frameにアニメーション情報を含んだり、含まなかったり、メッシュの名前をつけたりつけなかったりと様々です。<br>
（他にもアニメーションの名前をつけたりつけなかったりするものまで・・・）<br>
当然標準のビューアのみで対応できるはずもなく、マテリアル色がおかしくなったり、アニメーションが壊れたり、描画すらされなかったりといった結果になります。<br>
<br>
それぞれのソフトに対応したエクスポーターを書いてもよいのですが、現在進行中プロジェクトではmaya, max, light waveすべてからのデータが送られてくるため、３つもエクスポータを書くのはさすがに無理です。<br>
ですので、これらの問題を埋めるためにAutodesk社が標準とするFBXというファイル形式から必要な情報を抜き出し独自形式にコンバートしたいと思います。<br>
<br>
今回はお仕事用としてのメモも兼ねますので、すぐに次の情報をアップしたいと思います。今回はFBXのパース、バージョンが上がったSDKの使い方がメインです。<br>
</p>]]>
      <![CDATA[<p>
FBXにはAutodesk社が提供しているFBX SDKなるものがあり簡単にパース、エクスポートできる・・・はずなのですが、標準でメモリリークをしたり、デバイスハンドラを作成するだけのプログラムでwarningが300以上出たりと黒い話が絶えません。(200611)<br>
そしてこのたび2009.1という（恐らく2009年1月バージョン）未来バージョンらしきものにバージョンアップされましたので使用してみることにしました。<br>
</p>

<h3 class = "section">ビルド前設定</h3>
とりあえず昔作ったパーサをビルドしようとすると、全く動きません。何やらビルド前オプションやインクルードディレクトリにも変更があったようですので設定を行います。<br>
以下VisualStudio 2005の設定です。<br>

<ul>
<li>追加のインクルードファイルパスに\Autodesk\FBX\FbxSdk\2009.1\include; \Autodesk\FBX\FbxSdk\2009.1\include\kbaselib;を設定</li>
<li>ライブラリファイルパスに\Autodesk\FBX\FbxSdk\2009.1\libを設定</li>
<li>追加の依存ファイルにfbxsdk_md2005d.libを設定</li>
<li>プリプロセッサ定義 : WIN32;_DEBUG;_CONSOLEK_PLUGIN;K_FBXSDK;K_NODLL;_CRT_SECURE_NO_DEPRECATE</li>
</ul>

なぜライブラリ内ですらインクルードファイルパスが相対で書かれてないのかとか、コマンド引数を指定しないとデバイスハンドラ作成メソッドすら使えないのかとか、色々言いたいことはありあますが、とりあえず設定はこれで大丈夫です。<br>
また、今回からUnicode文字セットが使えるようになりました。<br>
日本語ディレクトリ名が存在すると読み込めないのは相変わらずのようです。<br>
また、日本語ディレクトリが存在してファイルが読み込めなかった場合、ファイルが存在しないエラーではなく、サポートしていないファイル形式エラーを返してくるので注意が必要です<br><br>

<h3 class = "section">何はともあれインポート（読み込み）</h3>
<p>
バージョンアップにより各種オブジェクト生成関数名、ファイルフォーマット定義マクロ、オブジェクト作成方法など色々変更されましたので旧バージョンのままだとやはり使えません。<br>
<br>
以前のバージョンでは全体の管理クラスであるKFbxSdkManagerオブジェクトの作成にKFbxSdkManager::CreateKFbxSdkManagerメソッドを使用していましたが今回からメソッド名が変わりました。<br>
まずこのオブジェクト生成と同時にインポートしてくる情報を受け取るためのKFbxSceneオブジェクトを生成します。<br>
</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
KFbxSdkManager *pSdkManager = NULL; 
KFbxScene      *pScene = NULL;

pSdkManager = KFbxSdkManager::Create();
pScene = KFbxScene::Create(pSdkManager, <em class="str">""</em>);
</pre>
</td>
</tr>
</table>
<p>
続いてインポータオブジェクトを生成します。<br>
ここではファイルフォーマットの設定を行いますが、ここも旧バージョンとは違い直接ASCII文字やバイナリコードであることを示すためのマクロがKFbxImporterからなくなっています。<br>
またKFbxStreamOptionsFbxReaderというインポート用オプションが追加され、以前はKFbxImporterで設定していた読み込むべきデータをこちらで設定することになります。<br>
</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
<em class="cmt">// インポータ作成</em>
KFbxImporter* pImporter = KFbxImporter::Create(pSdkManager, <em class="str">""</em>);

<em class="cmt">// インポートする情報を設定するオプション</em>
KFbxStreamOptionsFbxReader* lImportOptions=KFbxStreamOptionsFbxReader::Create(pSdkManager, <em class="str">""</em>);

<em class="cmt">// ファイルフォーマットをファイルから取得</em>
<em class="kwd">if</em>(!pSdkManager-&gt;GetIOPluginRegistry()-&gt;DetectFileFormat(file, iFileFormat)) {
    <em class="cmt">// ファイルフォーマット取得に失敗した場合</em>
    iFileFormat = pSdkManager-&gt;GetIOPluginRegistry()-&gt;GetNativeReaderFormat();
}

<em class="cmt">// インポータにファイルフォーマットを設定</em>
pImporter-&gt;SetFileFormat(iFileFormat);

<em class="cmt">// インポータ初期化</em>
<em class="kwd">const</em> <em class="kwd">bool</em> bImportStatus = pImporter-&gt;Initialize(file);

<em class="cmt">// ファイルバージョンを取得</em>
pImporter-&gt;GetFileVersion(iFileMajor, iFileMinor, iFileRevision);

<em class="kwd">if</em>(!bImportStatus) {  <em class="cmt">// インポータ初期化失敗の場合エラーを表示</em>
    puts(<em class="str">"FBXImporterの初期化に失敗しました\n"</em>);
    printf(<em class="str">"エラー内容: %s\n\n"</em>, pImporter-&gt;GetLastErrorString());

    <em class="kwd">if</em>(pImporter-&gt;GetLastErrorID() == KFbxIO::eFILE_VERSION_NOT_SUPPORTED_YET || 
        pImporter-&gt;GetLastErrorID() == KFbxIO::eFILE_VERSION_NOT_SUPPORTED_ANYMORE) 
    {
        puts(<em class="str">"FBX SDK 2009.1がサポートしていないバージョンのファイルです\n"</em>);
    }
}
</pre>
</td>
</tr>
</table>

<p>
いよいよデータ取得に入ります。<br>
今回はノードをたどり必要情報を抜き出すところまではやりませんのでオプションを設定し、シーンオブジェクトに必要情報をロードするだけです。<br>
</p>

<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
<em class="cmt">// インポートする情報を設定</em>
<em class="cmt">// とりあえずパースしたいので全てtrueで必要情報は全部読み込みます</em>
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_MATERIAL, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_TEXTURE, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_LINK, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_SHAPE, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_GOBO, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_ANIMATION, <em class="kwd">true</em>);
lImportOptions-&gt;SetOption(KFBXSTREAMOPT_FBX_GLOBAL_SETTINGS, <em class="kwd">true</em>);

bStatus = pImporter->Import(pScene, lImportOptions);
</pre>
</td>
</tr>
</table>

<p>
これでシーンオブジェクトの中に必要情報が格納されました。<br>
最後に後片付けを行います
</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
lImportOptions->Destroy();
lImportOptions = NULL;
pImporter->Destroy();
pSdkManager->Destroy();
pSdkManager = NULL;
</pre>
</td>
</tr>
</table>
<p>
次回はシーンオブジェクトから必要情報を抜き出作業になります。<br>
また今回作成したファイルはこちらです。<br>
<a href="http://www.codelogy.org/FBXImporter.cpp">ファイルをダウンロード</a><br>
<br>
担当：松浦（３Ｄ標準形式ｷﾃｸﾚｰ！）
</p>]]>
   </content>
</entry>
<entry>
   <title>VertexDeclarationとFVF</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/07/vertexdeclarationfvf.html" />
   <id>tag:www.codelogy.org,2008://28.10811</id>
   
   <published>2008-07-03T09:51:14Z</published>
   <updated>2008-07-11T08:31:30Z</updated>
   
   <summary>   私がよく見ている掲示板で気になる書き込みがありました。   プログラマ独自...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  私がよく見ている掲示板で気になる書き込みがありました。
  プログラマ独自のシェーダを使うときFVFは使えないので VertexDeclaration で頂点宣言を行わないといけない、といったものです。
  さすがにそれはないだろう・・・といった声もあるかと思われますが、シェーダプログラムがスキップされる等といった反論がありましたので実証してみました。
</p>
<p>
  ここ数週間プログラマブルシェーダばかり扱っていたため、ほとんど VertexDeclaration を使用していたのでFVFの宣言方法を確認しておきます。
  <a href = "http://msdn.microsoft.com/ja-jp/library/cc324487.aspx">MSDN</a>にある情報を元に定義しました。
</p>
]]>
      <![CDATA[<h3 class="section">頂点宣言・頂点バッファの生成</h3>
<p>
  まず、VertexDeclaration では頂点の設定を以下のように行います。<br />
</p>
<ul>
<li>頂点要素、使用法を決定</li>
<li>頂点フォーマットとして宣言</li>
</ul>

<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
D3DVERTEXELEMENT9 vertexElements[] = {  <em class="cmt">// 頂点要素の決定</em>
    {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_POSITION, 0},  <em class="cmt">// 頂点位置座標として使用する</em>
    D3DDECL_END()  <em class="cmt">// 頂点要素終了</em>
};

<em class="cmt">// 頂点フォーマットを宣言</em>
LPDIRECT3DVERTEXDECLARATION9 pVertexDecl;
pD3DDevice-&gt;CreateVertexDeclaration( vertexElements, &amp;pVertexDecl );</pre></td>
  </tr>
</table>

<p>
  続いてこれと同様の頂点宣言をFVFで行います。
  FVFは VertexDeclarationの ラッパー (だと思っている) なので、さらに簡単に宣言されます。
</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
pD3DDevice-&gt;SetFVF( D3DFVF_XYZ );  <em class="cmt">//
float3の要素をもつ頂点フォーマットを宣言</em>
</pre></td>
  </tr>
</table>

<p>
これで頂点宣言は終了しました。続いてこれに基づく頂点バッファを生成します。
</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
<em class="cmt">// VertexDeclarationでは以下のように頂点バッファを生成します</em>
pD3DDevice-&gt;CreateVertexBuffer( 3*<em
class="kwd">sizeof</em>(MY_VERTEX_POS),  <em class="cmt">//
作成する頂点バッファサイズ</em>
                                D3DUSAGE_WRITEONLY,       <em
class="cmt">// 使用法を定義</em>
                                0,                        <em
class="cmt">// FVFを使用しない</em>
                                D3DPOOPL_MANAGED,         <em
class="cmt">// リソースの管理方法</em>
                                &amp;pVB_POS,                 <em
class="cmt">// 生成される頂点バッファ</em>
                                NULL )
<em class="cmt">// FVFでは以下のように頂点バッファを生成します</em>
pD3DDevice-&gt;CreateVertexBuffer( 3*<em
class="kwd">sizeof</em>(MY_VERTEX_POS),  <em class="cmt">//
作成する頂点バッファサイズ</em>
                                D3DUSAGE_WRITEONLY,       <em
class="cmt">// 使用法を定義</em>
                                D3DFVF_XYZ,               <em
class="cmt">// float3要素を持つFVFを指定</em>
                                D3DPOOPL_MANAGED,         <em
class="cmt">// リソースの管理方法</em>
                                &amp;pVB_POS,                 <em
class="cmt">// 生成される頂点バッファ</em>
                                NULL )
</pre></td>
  </tr>
</table>
<p>
  これでバッファ生成は終了しました。次の描画処理は共通です。
</p>

<h3 class="section">描画処理</h3>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
<em class="cmt">//頂点バッファの中身を埋める</em>
MY_VERTEX_POS* v0;
pVB_POS-&gt;Lock( <em class="lit">0</em>, <em class="lit">0</em>, (<em class="kwd">void</em>**)&amp;v0, <em class="lit">0</em> );

<em class="cmt">// 各頂点の位置</em>
v0[<em class="lit">0</em>].p = D3DXVECTOR3(-<em class="lit">1.0f</em>,  <em class="lit">1.0f</em>, <em class="lit">0.0f</em> );
v0[<em class="lit">1</em>].p = D3DXVECTOR3( <em class="lit">1.0f</em>, -<em class="lit">1.0f</em>, <em class="lit">0.0f</em> );
v0[<em class="lit">2</em>].p = D3DXVECTOR3(-<em class="lit">1.0f</em>, -<em class="lit">1.0f</em>, <em class="lit">0.0f</em> );
pVB_POS-&gt;Unlock();

<em class="cmt">// ビューポートの取得</em>
D3DVIEWPORT9    vp;
<em class="kwd">if</em>(FAILED(pD3DDevice-&gt;GetViewport(&amp;vp))) {
    <em class="kwd">return</em> E_FAIL;
}

<em class="cmt">// アスペクト比の計算</em>
<em class="kwd">float</em> aspect;
aspect = (<em class="kwd">float</em>)vp.Width / (<em
class="kwd">float</em>)vp.Height;

<em class="cmt">// プロジェクション行列の初期化</em>
D3DXMatrixIdentity(&amp;m_proj);
D3DXMatrixPerspectiveFovLH(&amp;m_proj, D3DXToRadian(<em class="lit">45.0f</em>), aspect,
<em class="lit">1.0f</em>, <em class="lit">1000.0f</em>);

<em class="cmt">// ビューイング行列の初期化</em>
D3DXMatrixIdentity(&amp;m_view);
D3DXMatrixLookAtLH(&amp;m_view,
    &amp;D3DXVECTOR3( <em class="lit">0.0f</em>, <em class="lit">0.0f</em>, -<em class="lit">6.0f</em>),
    &amp;D3DXVECTOR3( <em class="lit">0.0f</em>, <em class="lit">0.0f</em>,  <em class="lit">0.0f</em>),
    &amp;D3DXVECTOR3( <em class="lit">0.0f</em>, <em class="lit">1.0f</em>,  <em class="lit">0.0f</em>));

<em class="cmt">// エフェクトの読み込み</em>
LPD3DXBUFFER    errors = <em class="lit">0</em>;
D3DXCreateEffectFromFile(pD3DDevice, TEXT(<em
class="str">"copy.fx"</em>), 0, 0, D3DXSHADER_DEBUG, 0,
&amp;m_pEffect, &amp;errors);
<em class="kwd">if</em>(errors){
       <em class="kwd">return</em> E_FAIL;
}

<em class="cmt">// テクニックのハンドルの取得</em>
m_hTech     = m_pEffect-&gt;GetTechniqueByName(<em
class="str">"BasicTech"</em>);

<em class="cmt">// シェーダープログラムのグローバル変数のハンドルの取得</em>
m_hWvp      = m_pEffect-&gt;GetParameterByName(0, <em
class="str">"g_wvp"</em>);    <em class="cmt">// world * view *
proj</em>
m_hColor0   = m_pEffect-&gt;GetParameterByName(0, <em
class="str">"g_color"</em>);
</pre></td>
  </tr>
</table>
<p>
この後の描画設定で頂点ストリームの設定を行います
VertexDeclarationで定義した場合には使用する頂点宣言を設定します。FVFでは必要ありません。
</p>

<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
<em class="cmt">// VertexDeclで定義した場合下をコメントを外す</em>
<em class="cmt">// pD3DDevice-&gt;SetVertexDeclaration(pVertexDecl);   </em>
pD3DDevice-&gt;SetStreamSource( 0, m_pVB_POS, 0, <em
class="kwd">sizeof</em>(MY_VERTEX_POS) );

<em class="cmt">// 色を設定→白</em>
D3DXVECTOR4 tmpColor;
tmpColor.x = 1.0f;
tmpColor.y = 1.0f;
tmpColor.z = 1.0f;
tmpColor.w = 1.0f;

<em class="cmt">// テクニックの設定</em>
m_pEffect-&gt;SetTechnique(m_hTech);

<em class="cmt">// シェーダーのグローバル変数の値の設定</em>
m_pEffect-&gt;SetMatrix(m_hWvp, &amp;(m_view*m_proj));
m_pEffect-&gt;SetVector(m_hColor0, &amp;tmpColor);
m_pEffect-&gt;CommitChanges();

<em class="cmt">// テクニックの実行</em>
m_pEffect-&gt;Begin(0, 0);
m_pEffect-&gt;BeginPass(0);

<em class="cmt">// 三角形の描画処理</em>
pD3DDevice-&gt;DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1);

m_pEffect-&gt;EndPass();
m_pEffect-&gt;End();
</pre></td>
  </tr>
</table>

<h3 class="section">結果</h3>
<p>
  結果は以下の画像のとおりです。
  今回使用したシェーダは入力された色情報 (r, g, b) それぞれに 0.5 を掛けて出力するだけのものです。
  VertexDeclaration でもFVFでも同様にシェーダが適用されています。<br />
  <img src="http://www.codelogy.org/archives/images/photo-20080703-095114-0.jpg" alt="" />
</p>
<p>
  また今回使用したソースコード全文はこちらです。<br />
  <a href="http://www.codelogy.org/FVFshader.zip">ファイルをダウンロード</a>
</p>
<div class="signature">
  担当: 松浦 (自分が何を実装しているか知らないほど怖いことはない)
</div>
]]>
   </content>
</entry>
<entry>
   <title>Ruby でも型チェック</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/06/ruby.html" />
   <id>tag:www.codelogy.org,2008://28.10740</id>
   
   <published>2008-06-16T04:00:00Z</published>
   <updated>2008-06-16T07:14:52Z</updated>
   
   <summary>   動的型付け (スクリプト) 言語では、データ型のチェックが実行時にしか行わ...</summary>
   <author>
      <name></name>
      
   </author>
   
   <category term="23" label="Ruby" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  動的型付け (スクリプト) 言語では、データ型のチェックが実行時にしか行われないため、プログラムの妥当性検証・デバッグといった作業が困難になります。<br />
  例えば、Ruby でプログラムを書いていて、次のようなバグに悩まされたことのある人は多いのではないでしょうか。
</p>
<ul>
<li><b>Integer</b> オブジェクトを参照しているべき変数が、他の型のオブジェクトを参照している。</li>
<li>そのオブジェクトが「いつ」「どこで」代入されたものなのか分からない。</li>
</ul>
<p>
  この手のバグは、問題の発生 (不正な型の代入) と発覚 (エラーの発生) の位置が離れてしまうので、非常に厄介。
  発生箇所を絞り込むのが難しいため、プログラムを広範囲に渡って見直すハメになります。
</p>
]]>
      <![CDATA[<h3 class="section">check_type の導入</h3>

<p>
  こうしたバグへの対処を容易にするため、私はメソッドの冒頭で引数の型をチェックするようにしています。
</p>
<table class="code">
<tr>
  <td class="caption">student.rb</td>
  </tr>
<tr>  <td><pre>require <em class="str">'date'</em>
require <em class="str">'check_type'</em>

<em class="cmt"># 「学生」クラス</em>
<em class="kwd">class</em> Student

    attr :id
    attr :fname
    attr :lname
    attr :birthday

    <em class="cmt"># 初期化</em>
    <em class="kwd">def</em> initialize(id, lname, fname, birthday)
        @id       =check_type(Integer, id,       <em class="kwd">false</em>);
        @lname    =check_type(String,  lname,    <em class="kwd">false</em>);
        @fname    =check_type(String,  fname,    <em class="kwd">false</em>);
        @birthday =check_type(Date,    birthday, <em class="kwd">false</em>);
    <em class="kwd">end</em>
<em class="kwd">end</em> <em class="cmt"># class Stundent</em></pre></td>
  </tr>
<tr>
  <td class="caption">check_type.rb</td>
  </tr>
<tr>  <td><pre>
<em class="cmt"># 型チェック</em>
<em class="kwd">def</em> check_type(type, instance, nullable =<em class="kwd">false</em>)

    <em class="kwd">if</em> (instance.nil?)
        <em class="kwd">unless</em> (nullable)
            <em class="kwd">raise</em> ArgumentError.new(<em class="str">"non-nil constraint vioration"</em>)
        <em class="kwd">end</em>
    <em class="kwd">else</em>
        <em class="kwd">unless</em> (instance.kind_of?(type))
            raise(ArgumentError::new(<em class="str">"type mismatch: #{instance.class} for #{type}"</em>))
        <em class="kwd">end</em>
    <em class="kwd">end</em>

    <em class="kwd">return</em> instance
<em class="kwd">end</em></pre></td>
  </tr>
</table>

<p>
  メソッドに不正な型の引数を渡すと、<b>ArgumentError</b> が発生します。
</p>
<table class="code">
<tr>
  <td class="caption">test.rb</td>
  </tr>
<tr>  <td class="sample"><pre>
require <em class="str">'student'</em>

s =Student::new(<em class="lit">200</em>, <em class="str">'Narita'</em>, <em class="str">'Sho'</em>, <em class="str">'1981/07/05'</em>)</pre></td>
  </tr>
<tr>  <td class="result"><pre>
% student.rb:20:in `check_type': type mismatch: String for Date (ArgumentError)
from student:13:in `initialize'
from test.rb:3:in `new'</pre></td>
  </tr>
</table>

<p>
  また、<code>check_type</code> を各メソッドの冒頭に配置することで、そのメソッドがどんな型の引数をとるのか明示することにもなるため、オススメです。
</p>
<div class="see_also">
  関連エントリ: <a href="http://www.codelogy.org/archives/2007/10/post_4.html">配列やハッシュテーブルを構造体の代わりに使う奴はヤキ
</a>
</div>
<div class="signature">
  担当: 成田 (型チェックの鬼)
</div>
]]>
   </content>
</entry>
<entry>
   <title>Medical show and Business expo 2008 レポート</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/06/medical_show_and_business_expo.html" />
   <id>tag:www.codelogy.org,2008://28.10707</id>
   
   <published>2008-06-05T11:58:45Z</published>
   <updated>2008-06-05T12:16:02Z</updated>
   
   <summary> ５月２８日から３１日にかけまして、東京国際フォーラムにてMedical sho...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="レポート" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
５月２８日から３１日にかけまして、東京国際フォーラムにてMedical show and Business Expo 2008に参加してきました。今回はそのレポートと学んだことについてご報告します。<br>
<br>
参加しました医療系展示会では主にハードウェアの展示が多く、ソフトウェアを公開されていブースは私たちを除いては一社しかありませんでした。<br>
ですので、今回のコラムは技術的な内容ではなく、展示会におけるプレゼンテーションでの成功点と失敗点を私なりにまとめてみました。<br>
<br>
これらの点を次回以降の改善点、また対策としてみていただければ幸いです。
</p>]]>
      <![CDATA[<p>
まず失敗点、不評だった点についてまとめます。<br>
</p>
<h3 class="section">失敗点</h3>
<p>
・不自由な日本語<br>
最初に問題となったのは、あまりにも不適切な日本語でした。<br>
技術者同士、もしくは友人として技術を解説する場合と異なり、常に敬語、わかりやすい言葉の選択をせまらられた際、とたんに日本語が不自由になります。<br>
最初の３人のお客様にご解説をする際、先輩のヘルプを求めるといった始末でした。<br>
<br>
それ以降は次第に頭もまわり、発言で詰まることはなくなったのですが数人のお客様に不明瞭な説明を行い、先輩にも迷惑をかけてしまいました。<br>
少なくとも３度、実際にお客様にご解説するシミュレーションを行うことが必須です。<br>
<br>
・まぎらわしい展示品<br>
次に問題となったのは広報用のプレートでした。<br>
馴染みがあるお客様はご理解いただけたのですが、小さい文字・ルーペというプレートから目に関する医療だと勘違いされたとご指摘をいただきました。<br>
コンテンツとしては価値があるデザインも、場所を選ばなくては勘違いを生みやすいため注意が必要です。<br>
<br>
・欲張った説明<br>
解説が慣れてくるにつれ問題になってきた点が、欲張りすべてを解説しようとする姿勢です。<br>
私たちはそれぞれのプロジェクトに対し理解があるため、短時間で全てのコンテンツを紹介できている、と考えていたため、お客様の理解する暇を奪ってしまっていました。<br>
それに気づいたのは、駆け足で映像にあわせて説明を行った際のことでした。<br>
注意すべき点は、お客様の表情、声、視線などです。<br>
<br>
これに注意をしつつご解説を行ったところ、余裕をもったお話をすることができるようになりました。<br>
</p>

<p>
次に重要点、成功点についてまとめます。<br>
</p>
<h3 class="section">成功点</h3>
<p>
・積極性とキーワード<br>
まず重要だと感じたことが積極性・キーワードについてです。<br>
ブースの前を通られるお客様は、よほどの大ブースでない限り一目でこちらの展示品を認識されることは困難です。<br>
そのためパンフレットなどを配り、認識していただくのですが、今回は３つのプロジェクトということ、また機材を持ち込み実践できないこと、などからパンフレットを渡すだけでは不十分でした。<br>
<br>
そこで以下のようなキーワードを用いてお客様の注意を引くことにしました。<br>
</p>
<ul>
<li>バーチャルリアリティ</li>
<li>フリーハンドな家電操作</li>
<li>介護ロボット、パワードスーツ</li>
</ul>
<p>
これらの単語はお客様に少しの興味と面白さをご理解いただく点で大変有用でした。<br>
つまり、プロジェクトとして出展する内容のキーワード（一般的な言葉、面白さを含む）を頭にいれておくことが重要となります。<br>
<br>
またプロジェクトの内容とは関係ない展示品も重要ということに気づきました。<br>
写真をごらんください。(*写真を取り込み中です、少しお待ちください）<br>
<br>
左側、豚の着ぐるみのディスプレイです。<br>
こちらは１０～３０代の女性の方、大学生の方に大変受けがよく、このディスプレイから派生してお話を聞いていただくことができました。<br>
<br>
左手前、社長の名刺とアクセスカード<br>
デザイン、点字もある親切さがよいのですが２枚あるためどちらをお渡しすべきか悩むことが・・・。<br>
<br>
右奥、AR用カタログ<br>
こちらは主に医療最前線でご活躍なされている方にご好評でした。<br>
ARの実装方法、機能、使い方を解説する際、また見た目のインパクトもありました。<br>
<br>
右側中央、chumby<br>
小型ディスプレイに興味があられる方、chumbyをご存知の方、かわいさを求める方にご好評でした。<br>
豚型ディスプレイから話を持っていくこともできたため、使いやすいのですが、映像サイズが小さいため、詳細解説は難しいといった問題点もあります。<br>
<br>
右側手前、ブース用パンフレット<br>
今回は立ち位置がブース左側だったため、このパンフレットを取りに行くと豚型ディスプレイを隠してしまうといった問題がありました。<br>
よって常に６，７枚携行しお客様に見えやすいよう持ってみました。<br>
<br>
・展示内容以外の理解<br>
メディカル系のエキスポはあまり出展経験がないため、頻繁にお客様よりどういった会社なのか、とお尋ねされることがありました。<br>
その場合はまず、本来の業務をお伝えし、加えて今回メディカル系ということで３Ｄを前面に押し出した展示をしております、とご説明することで、出展した内容以外のお仕事をいただける可能性があります。<br>
今回のエキスポではWebシステム設計を依頼していただきましたり、展示物以外の話でも盛り上がる場面が
多々ありました。<br>
これにより、普段の業務をよく理解しておく必要性を感じました。<br>
<br>
・会話技術を盗む<br>
社長や、人が多く集まっているブースの説明を聞いていると私がご説明する内容以外に、さらに幅広い位置からのご説明をされていることに気づきます。<br>
それらがお客様を長い時間ひきつけ、余裕を持って全てのプロジェクトを解説できることにつながっているようでした。<br>
プログラムコードと同じようにうまい人の技術を盗むことは重要です。<br>
</p>

<h3 class="section">結び</h3>
<p>
今回のエキスポでは技術的な利点だけではなく、プレゼンテーション、営業的な利点も多く得ることができました。<br>
これらはマシンと向かい合っているときには経験できず、また学生である私にはほとんど味わったことがないものです。<br>
次回以降のエキスポにはこれらを元に準備をすすめ、また会場で更なるプレゼンテーション能力を得たいと思います。<br>
それでは、つたないレポートでしたがこのあたりで。<br>
<br>
担当：松浦<br>
</p>
]]>
   </content>
</entry>
<entry>
   <title>Office OpenXMLの解説</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/05/office_openxml.html" />
   <id>tag:www.codelogy.org,2008://28.10626</id>
   
   <published>2008-05-08T09:47:10Z</published>
   <updated>2008-05-08T09:58:00Z</updated>
   
   <summary> GPUで並列処理の続きの記事がまだできていませんので、今回は別の記事を用意しま...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<div class="caption"><p>
GPUで並列処理の続きの記事がまだできていませんので、今回は別の記事を用意しました。</br>
</br>
OpenXMLは<a href = 
"http://office.microsoft.com/ja-jp/products/default.aspx">Microsoft 
Office2007</a>で新たに採用された文章フォーマットです。</br>
Microsoft独自のバイナリデータではなく、新たにXMLで記述された規格を採用したことで、外部アプリケーションから</br>
データ内容を操作しやすくなりました。</br>
しかしながら、データ操作の際<a href = 
"http://www.ecma-international.org/">ECMA</a>のOpenXML仕様書(Part 4: Markup 
Language Reference)を参照するわけですが、５千ページを超えているpdfですので
ファイルを開くだけでマシンがカクカクする私にとっては大問題です。</br>
</br>
よって今回Microsoft Excelのセル内容、レイアウトを変更するにあたって特に必要な部分についてまとめました。</br>
</p>
]]>
      <![CDATA[<h3 class="section">フォルダ構成</h3>
<p>
まず、Excelファイルであるxlsxファイルを展開してみます。</br>
すると次のようなフォルダ構成となっています。</br>
</p>
　　root</br>
　　　|- _rels</br>
　　　|</br>
　　　|- docProps</br>
　　　|</br>
　　　|- xl</br>
　　　|</br>
　　　|- [Content_Types].xml</br>
</p>
<p>
この中で表内のデータを操作する場合に必要なのはxlフォルダです。</br>
そのフォルダ内で書き換えが必要なxmlは次の二つです。</br>
<ul>
 <li>xl\worksheets\sheet○.xml（○の中には何枚目のシートであるといった番号が振られます）</li> <li>xl\styles.xml</li></ul>それでは実際にファイル内容を変更してみましょう。</p><p><h3 class="section">ファイルフォーマット、ビューの定義（sheet.xml）</h3>セル内のデータに変更を加えるのでsheet1.xmlを元に説明します。</br>まずは行頭のxmlフォーマット定義部です。ここはほぼテンプレートなので変更する必要はないでしょう。</br>UTF-8フォーマットで書かれているということを定義しています。</br></p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
&lt;?xml version=<em class="str">"1.0"</em> encoding=<em class="str">"UTF-8"</em> standalone=<em class="str">"yes"</em>?&gt;
    &lt;worksheet xmlns=<em class="str">"http://schemas.openxmlformats.org/spreadsheetml/2006/main"</em> 
    xmlns:r=<em class="str">"http://schemas.openxmlformats.org/officeDocument/2006/relationships"</em>&gt;
    </pre>
  </td>
</tr></table>
<p>次にシートのビューの状態に��いて設定する項目があります。</br>シートのビューとはExcelでそのxlsxファイルをオープンした時に、どのようにファイルが表示されるかという事です。</br></p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
&lt;dimension ref=<em class="str">"A1:D2"</em>/&gt;
&lt;sheetViews&gt;&lt;sheetView tabSelected=<em class="str">"1"</em> workbookViewId=<em class="str">"0"</em>&gt;
        &lt;selection activeCell=<em class="str">"D2"</em> sqref=<em class="str">"D2"</em>/&gt;
    &lt;/sheetView&gt;
&lt;/sheetViews&gt;
&lt;sheetFormatPr defaultRowHeight=<em class="str">"13.5"</em>/&gt;
    </pre>
  </td>
</tr></table>
<p>ここで使われているタグについて説明します。<ul> <li>dimention : シートのデータが入っている左上のセル番号:右下のセル番号を登録</li> <li>sheetView : シートのビューIDとExcelで表示されるタブの番号を指定します</li> <li>selection : 現在Excel画面でカーソルがアクティブになっているセル（どこでもよいと思われます）</li> <li>shee
 tFormatPr : ロウのデフォルトの縦幅は13.5（point？）と定義されています    （styles.xmlでスタイルが決定できるのですが・・・、なぜここでも定義する必要があるのかは不明）</li></ul>ここまででフォーマット定義、ビューの定義が終わりいよいよセルのデータ操作となります。</p><p><h3 class="section">セル内データの操作（sheet.xml）</h3>理解しやすくするために、セルにデータを入力してみます。<ul> <li>A1 : 1（数値としての1）</li> <li>B1 : 2007/05/07（日付）</li> <li>C1 : ３列目（文字列）  </li> <li>D1 : hogehoge（文字列）</li> <li>D2 : 8（数値としての8）</li></ul>xmlは以下のようになります。</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
&lt;sheetData&gt;
    &lt;row r=<em class="str">"1"</em> spans=<em class="str">"1:4"</em>&gt;
        &lt;c r=<em class="str">"A1"</em>&gt;&lt;v&gt;1&lt;/v&gt;&lt;/c&gt;
        &lt;c r=<em class="str">"B1"</em> s=<em class="str">"1"</em>&gt;&lt;v&gt;39575&lt;/v&gt;&lt;/c&gt;
        &lt;c r=<em class="str">"C1"</em> t=<em class="str">"s"</em>&gt;&lt;v&gt;0&lt;/v&gt;&lt;/c&gt;
        &lt;c r=<em class="str">"D1"</em> t=<em class="str">"s"</em>&gt;&lt;v&gt;1&lt;/v&gt;&lt;/c&gt;
    &lt;/row&gt;&lt;row r=<em class="str">"2"</em> spans=<em class="str">"1:4"</em>&gt;
        &lt;c r=<em class="str">"D2"</em>&gt;&lt;v&gt;8&lt;/v&gt;&lt;/c&gt;
    &lt;/row&gt;
&lt;/sheetData&gt;
&lt;phoneticPr fontId=<em class="str">"1"</em>/&gt;&lt;pageMargins left=<em class="str">"0.7"</em> right=<em class="str">"0.7"</em> top=<em class="str">"0.75"</em> bottom=<em class="str">"0.75"</em> header=<em class="str">"0.3"</em> footer=<em class="str">"0.3"</em>/&gt;
&lt;/worksheet&gt;
    </pre>
  </td>
</tr></table>
<p>それではここのタグは詳細に解説したいと思います。<ul> <li>sheetDataタグ : シート情報の開始タグです。アトリビュートはありません。</li> <li>rowタグ : 行の開始タグです（アトリビュート : r 行番号を指定します,spans 開始�列:終了列で指定します）</li> <li>cタグ : セル開始タグです（アトリビュート : 量が多いため後述します） <li>vタグ : セル内の値を保持するタグです。 <li>phoneticPrタグ : フォントを変更しているようですが・・・特に操作したことがありませんorz</li> <li>pageMarginsタグ : ページ上下左右のマージンサイズを変更できます</li></ul>cタグのアトリビュートについて列挙します<ul> <li>r : 行列番号を指定します</li> <li>s : 1を指定すると時刻を（年/月/日）のフォーマットで表示します</li> <li>t : sを指定するとstringテーブルを格納したxmlファイルから参照します、またstrを指定することでvタグ内に直接文字列を書き込むことができます。</li></ul>よって何もない空のsheet.xmlを操作する場合dimention, spansを使用サイズ分設定した後、新たにcタグを作りvタグに値を設定すればよいということです。（実はdimentionは特に設定しなくても動きますが、念のため）実際にE1セルに�新しい内容を追加してみました。</br>こちらが変更前です。</p><img src="http://www.codelogy.org/archives/images/photo-20080508-094709-0.gif"></br><p>以下の行を追加します。
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
&lt;c r=<em class="str">"E1"</em> t=<em class="str">"str"</em>&gt;&lt;v&gt;new&lt;/v&gt;&lt;/c&gt;
    </pre>
  </td>
</tr></table>
</p><img src="http://www.codelogy.org/archives/images/photo-20080508-094709-1.gif"></br><p>正常に変更されました。もしファイルオープンに失敗する場合は以下の点に注意してください。<ul> <li>文字フォーマットはUTF-8で保存しているかどうか</li> <li>Book1.xlsxを解凍したときにでてくるBook1フォルダごと圧縮していないかどうか（圧縮するのはその下の３つのフォルダと１つのxmlファイルだけです）</li></ul>今回セルの内容操作だけでかなり長文となってしまいました。</br>スタイルや罫線、配色については次の機会に説明したいと思います。</br></br>さらに説明しきれなかったタグの説明や、アトリビュートの詳細説明を後日リファレンスとしてまとめたいと思います。</br></br>担当：松浦</p></div>
]]>
   </content>
</entry>
<entry>
   <title>GPUでレイトレーシング (補足)</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/05/gpu_2.html" />
   <id>tag:www.codelogy.org,2008://28.10620</id>
   
   <published>2008-05-06T13:08:00Z</published>
   <updated>2008-05-07T00:23:14Z</updated>
   
   <summary>   前回のGPUレイトレーシングについてもう少し補足したほうがよさそうでしたの...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  前回の<a href = "http://www.codelogy.org/archives/2008/05/gpu_1.html">GPUレイトレーシング</a>についてもう少し補足したほうがよさそうでしたので、補足します。<br />
  今回はGPUのジョブの単位、メモリの扱い、画面分割の割り当てを図を用いて説明します。
</p>]]>
      <![CDATA[<h3 class="section">GPUのジョブの単位</h3>

<p>
  まず、GPUのコアとそのジョブの単位であるグリッド、ブロックとスレッドの関係について列挙します。
</p>
<ul>
<li>GPUに送られるジョブの単位はグリッド</li>
<li>グリッドはブロックとスレッドによって構成される</li>
<li>グリッドのライフタイムは10秒 (10秒ルール)</li>
<li>１個のブロックは１個のコアに対してのみ割り当てられる<br />
(注: つまり一個のコアに対しては複数のブロックが割り当てられる、ということ)</li>
<li>ブロックはスレッドで構成され、１個のブロックに最大512スレッド実行できる</li>
<li>32スレッドをまとめたものを1warpと呼ぶ<br />
(注：1個のコアには8個のストリーミングプロセッサが積まれている。その1個が4スレッド並列動作をおこなう。<br />
&nbsp;それによって、4*8=32スレッド (1warp) ということ)</li>
</ul>
<p>
  これらは図01のような関係となっています。<br />
  <br />
  <img src = "http://www.codelogy.org/archives/images/2008/05/06/01.gif" alt="図01" /><br />
  図01<br />
</p>

<p>
  スレッド１個１個で GPUMain が走り、それらはブロック単位でコアに渡されます。<br />
  warp とよばれるスレッドの集合が適宜入れ替えられ、32本ずつ並列動作します。この方法を最大限にいかせるスレッド数として192スレッドという値が出されています。
</p>

<h3 class="section">GPUのメモリについて</h3>
<p>
  今回のトピックで頻繁に使われるグローバルメモリ、シェアードメモリについて説明します。<br />
  以下の二つの内容については、私が作成したプログラムの範囲に限定して、のことです。
</p>
<p>
  まず、グローバルメモリとはすべてのコアから参照でき、大容量、低速です。<br />
  シェアードメモリに収まりきらないデータや、読み込む規則が定まらないデータなどがおかれます。
</p>
<p>
  次にシェアードメモリとはブロック内でスレッド間でのみ共有できる容量の小さい高速なメモリです。<br />
  参照回数が多いオブジェクトや環境情報などがおかれます。<br />
  シェアードメモリの内容はブロック内でのみ有効で、同じコア内の別ブロックとは共有できません。<br />
  （それに、どのブロックをどのコアに置くといった設定がありません。）
</p>

<h3 class="section">基本的なピクセル並列</h3>
<p>
  X軸の画素をブロック内のスレッド１つ１つに割り当て、Y軸の画素をそれぞれのブロック単位で処理します。<br />
  この内容は図02のようになります。<br />
  <br />
  <img src = "http://www.codelogy.org/archives/images/2008/05/06/02.gif" alt="図02" /><br />
  図02
</p>
<p>
  &gt; 図02の方法において、画素をスレッドに割り当てた場合、レイと交差するオブジェクトを左端から右端までメモリに蓄える必要があります。<br />
  メモリキャッシュや、不要なロードを抑えるためにもこの方法は適当ではありません。<br />
  ただし、この内容は限られた状況、つまり1度にオブジェクトがすべてシェアードメモリに収まるような状況はあまりありません。
</p>

<h3 class="section">ブロック単位のピクセル分割</h3>
<p>
  &gt; ピクセル１個に対しスレッド１個を割り当て、2*2, 4*4, 8*8,... ピクセルのブロックといった感じでマルチコアに割り当てます<br />
  混乱を避けるためにあえてこのような言い回しをしました。<br />
  図03を見てください。<br />
  <br />
  <img src = "http://www.codelogy.org/archives/images/2008/05/06/03.gif" alt="図03" /><br />
  図03
</p>
<p>
  青い枠でかこった部分 (ピクセルのブロック) をGPUのジョブのブロックとしてマルチコア1個に割り当てます。<br />
  このように左上端から右下端までの範囲、といった形でロードするオブジェクトを判別することができます。<br />
  またすでに読み込まれているオブジェクトの参照が多く行われるため、高速です。
</p>

<h3 class="section">CPUとGPU間のメモリ遅延</h3>
<p>
  余談につっこみがありましたので一応。<br />
  GPUから直接画像をキックという件についてですが、なぜこんな話を出してきたかというとCPU、GPU間のメモリ遅延は空間分割を行い必要なものだけをストア、ロードを繰り返したとしても処理の大半の時間を持って行かれます。<br />
  よって実験目的なりなんなりの関数として「一応あってもいい」のではないかと・・・。<br />
  実際にソフトウェアとして使用できるかどうかはまた別問題です。
</p>
]]>
   </content>
</entry>
<entry>
   <title>GPUでレイトレーシングを並列処理</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/05/gpu_1.html" />
   <id>tag:www.codelogy.org,2008://28.10609</id>
   
   <published>2008-05-02T11:28:13Z</published>
   <updated>2008-05-03T02:26:28Z</updated>
   
   <summary>   以前やったGPUで並列処理の続きとして今回はGPUでレイトレーシングを行い...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  以前やった<a href="http://www.codelogy.org/archives/2007/12/gpu.html">GPUで並列処理</a>の続きとして今回はGPUでレイトレーシングを行いたいと思います。<br />
  レイトレーシングはリアルな画像を作り出す反面、計算に大変時間がかかることはよく知られています。<br />
  その処理をいかに高速化できるか？というのが今回のコラムの目的です。
</p>
]]>
      <![CDATA[<h3 class="section">基本的なピクセル並列</h3>
<p>
  GeForce8x 系のアーキテクチャが基本的にマルチスレッドで動作することは以前に触れました。<br />
  まず考え付く方法としてピクセル単位の並列化が考えられると思います。<br />
  具体的に言うとX軸の画素をブロック内のスレッド１つ１つに割り当て、Y軸の画素をそれぞれのブロック単位で処理します。<br />
  この方法はオブジェクトが少なく、またピクセル数が並列動作の最大パフォーマンスが出せるスレッド数 (192スレッド以上) に近づくほど効率がよくなります。<br />
  ソースコードは以下のような感じとなります
</p>

<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
<em class="cmt">////////////////////////////////////////////////////////////////////////</em>
<em class="cmt">// GPU処理エントリポイント</em>

<em class="kwd">#define</em> SCREEN_WIDTH  <em class="lit">512</em>
<em class="kwd">#define</em> SCREEN_HEIGHT <em class="lit">512</em><em class="cmt">// 512*512の画像を出力するとしました。</em>

__global__
<em class="kwd">void</em> GPUMain(
    Display* fOut,       <em class="cmt">// 画面ピクセルの位置と色を格納した構造体</em>
    Object* fIn,         <em class="cmt">// オブジェクト情報を格納した構造体</em>
    Environment *fIn_env <em class="cmt">// 環境情報を格納した構造体</em>
    )
{
    <em class="kwd">const</em> <em class="kwd">unsigned</em> <em
class="kwd">int</em> pixelx = threadIdx.x; <em class="cmt">// ピクセルXにスレッド1個を対応</em>
    <em class="kwd">const</em> <em class="kwd">unsigned</em> <em
class="kwd">int</em> pixely = blockIdx.x;  <em class="cmt">// ピクセルYにブロック１個を対応</em>

    __shared__ Object object[MAXOBJ];        <em class="cmt">// オブジェクトのデータ量により
                                             // シェアードメモリに蓄えれる物体数が変化します。</em>
    <em class="kwd">if</em>(<em class="lit">0</em>&lt;=pixelx &amp;&amp; pixelx &lt; MAXOBJ)
    {
        object[pixelx] = fIn[pixelx];        <em class="cmt">// sharedメモリにストア</em>
    }
    __syncthreads();                         <em class="cmt">// ストア終了まで待つ</em>

    <em class="cmt">// レイトレーシング機能をまとめた関数とします。</em>
    <em class="cmt">// ピクセル位置、オブジェクト情報、環境情報から視線追跡を行い出力ピクセルを算出します。</em>
    <em class="cmt">// 今回この内部は並列化していませんので割愛させていただきます。</em>
    RayTrace(pixelx, pixely, object, fIn_env, &amp;fOut[SCREEN_WIDTH * pixely + pixelx]);
}</pre></td>
  </tr>
</table>

<p>
  しかし一般的にこのような限られた状況で行うレイトレーシングは稀です。<br />
  以前も触れましたがsharedメモリの容量は小さいので、このままでは完全にストアできるオブジェクトはわずか
数十個〜数百個です。
  オブジェクト情報をシェアードメモリを使用せずグローバルメモリから読み込めば難しく考える必要もありませんが、高速化といった観点からははずれてしまいます。
</p>

<h3 class="section">ブロック単位のピクセル分割</h3>
<p>
よって解決策として画面分割とピクセル単位の並列化を併用します。
画面分割によってブロック内に含まれるオブジェクトに対してのみ計算処理を行えるようになります。
また、ピクセル１個に対しスレッド１個を割り当て、2*2, 4*4, 8*8,... ピクセルのブロックといった感じで
マルチコアに割り当てます。
この方法を実装したプログラムは次のようになります。
</p>
<table class="code" cellspacing="4">
<tr>
  <td>
    <pre>
<em class="kwd">#define</em> SCREEN_WIDTH  <em class="lit">512</em>
<em class="kwd">#define</em> SCREEN_HEIGHT <em class="lit">512</em> <em class="cmt">// 512*512の画像を出力するとしました。</em>

<em class="kwd">#define</em> PIXLE_BLOCK_SIZE <em class="lit">8</em> <em class="cmt">// 8*8ピクセルのブロック単位で処理をすると設定</em>

__global__
<em class="kwd">void</em> GPUMain(
    Display* fOut,        <em class="cmt">// 画面ピクセルの位置と色を格納した構造体</em>
    Object* fIn,          <em class="cmt">// オブジェクト情報を格納した構造体</em>
    Environment *fIn_env  <em class="cmt">// 環境情報を格納した構造体</em>
    )
{
    <em class="kwd">const</em> <em class="kwd">unsigned</em> <em class="kwd">int</em> pixelx = threadIdx.x; <em class="cmt">// ピクセルXにスレッド1個を対応</em>
    <em class="kwd">const</em> <em class="kwd">unsigned</em> <em class="kwd">int</em> pixely = threadIdx.y; <em class="cmt">// ピクセルYにスレッド1個を対応</em>

    __shared__ Object object[MAXOBJ];        <em class="cmt">// シェアードメモリはブロック内で有効</em>
    <em class="kwd">if</em>(<em class="lit">0</em>&lt;=pixelx &amp;&amp; pixelx &lt; MAXOBJ)
    {
        object[pixelx] = fIn[pixelx];        <em class="cmt">// sharedメモリにストア</em>
    }
    __syncthreads();

    RayTrace(pixelx + (blockIdx.x % <em class="kwd">64</em>) * PIXEL_BLOCK_SIZE,  <em class="cmt">// 走査するピクセルのX座標を設定</em>
        pixely +  (blockIdx.x / <em class="lit">64</em>) * PIXEL_BLOCK_SIZE,      <em class="cmt">// 走査するピクセルのY座標を設定</em>
        object, fIn_env, &amp;fOut[SCREEN_WIDTH * pixely + pixelx]);
}</pre></td>
  </tr>
</table>

<p>
  この方法を使用すれば以前のプログラムより多くのオブジェクトを高速に処理することが可能になります。<br />
  しかしこの方法を実装しても画面いっぱいにオブジェクトが含まれる場合やブロック内の数個のピクセル処理に多くの時間を必要とした場合、ブロック全体のパフォーマンスが落ちます。<br />
  また、CUDAには10秒ルールという制約があり、１つのジョブに10秒以上時間がかかると強制的に処理が中断されます。<br />
  そういうタスクを行う場合はCPUに一度処理を戻さなければならないのですが、それを繰り返すことによりメモリ内容を転送するディレイが発生します。<br />
  これらの問題解決策として空間分割を行い、レイ、ボクセル単位で並列化する方法があるのですが、それはまた次の機会にということで・・・。
</p>
<p>
  後これは愚痴なんですが、計算した内容を直接画面にキックする関数くれよ・・・と。<br />
  CPUに戻す手間なんとかなりませんか・・・。
</p>
<div class="signature">
  担当: 松浦
</div>
]]>
   </content>
</entry>
<entry>
   <title>XMLライブラリの紹介 (2)</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/05/xml.html" />
   <id>tag:www.codelogy.org,2006://28.10005</id>
   
   <published>2008-05-01T08:00:00Z</published>
   <updated>2008-05-01T08:27:40Z</updated>
   
   <summary>   前のエントリからかなり間が空いてしまいましたが、XML ライブラリの紹介の...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="C++" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="13" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
   <category term="36" label="XML" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  <a href="http://www.codelogy.org/archives/2007/12/a.html">前のエントリ</a>からかなり間が空いてしまいましたが、XML ライブラリの紹介の続きです。
</p>
<p>
  読み込んだXML文書のツリー構造をたどって各要素に対する処理を行うのは、手間がかかります。<br />
  今回は、フレームワークを利用して XML 文書を解釈 (interpret) する方法について説明します。
</p>

]]>
      <![CDATA[	<!-- Section 1 ========================================================= -->
<h3 class="section">1. xml::Interpreter の継承</h3>

<p>
  まず、<a href="http://www.nowhere.co.jp/~narita/library/xml/doc/Interpreter/index.html">xml::Interpreter</a> を継承して、独自のインタプリタクラスを定義します。<br />
  ユーザは、<b>xml</b>::<b>Interpreter</b> の仮想関数 <a href="http://www.nowhere.co.jp/~narita/library/xml/doc/Interpreter/reference/index.html#PROC">Proc</a> をオーバーライドすることで、その動作を定義することができます。
</p>
<p>
  例として、XHTMLファイルを読み込み、以下の属性値を抜き出して表示するインタプリタを作成してみましょう。</p>
<ul>
<li>a 要素の href 属性</li>
<li>img 要素の src 属性</li>
</ul>
<p>	この場合は、要素に対する動作だけを記述すればよいので、オーバライドするのは Proc の書式 4. のみとなります。</p>

<table class="code">
<tr>
  <td class="caption">MyInterpreter.h</td>
  </tr>
<tr>
  <td>
    <pre>
<em class="kwd">#include</em> <em class="str">"xml/xmlInterpreter.h"</em>

<em class="cmt">//ユーザ定義XMLインタプリタ</em>
<em class="kwd">class</em> MyInterpreter : <em class="kwd">public</em> xml::Interpreter {
<em class="kwd">protected</em>:

    <em class="cmt">//virtual: Interpreter</em>
    <em class="kwd">virtual</em> <em class="kwd">void</em> Proc(<em class="kwd">const</em> xml::Elem*);

};</pre></td>
  </tr>
<tr>
  <td class="caption">MyInterpreter.cpp</td>
  </tr>
<tr>
  <td>
    <pre>
<em class="kwd">#include</em> <em class="str">"MyInterpreter.h"</em>

<em class="kwd">#include</em> <em class="str">"narita/String.h"</em>
<em class="kwd">#include</em> <em class="str">"xml/xmlElem.h"</em>

<em class="cmt">//要素の処理</em>
<em class="kwd">void</em> MyInterpreter::Proc(<em class="kwd">const</em> xml::Elem* lpElem){

    <em class="kwd">const</em> String&amp; name =lpElem-&gt;<a href="http://www.nowhere.co.jp/~narita/library/xml/doc/Elem/reference/index.html#NAME">Name</a>();

    <em class="kwd">if</em> (name == <em class="str">"a"</em>){
        String href =lpElem-&gt;Attribute(<em class="str">"href"</em>);
        <em class="kwd">if</em> (href) puts(href);
    }
    <em class="kwd">else</em> <em class="kwd">if</em> (name == <em class="str">"img"</em>){
        String src =lpElem-&gt;Attribute(<em class="str">"src"</em>);
        <em class="kwd">if</em> (src) puts(src);
    }

    xml::Interpreter::Proc(lpElem);

    <em class="kwd">return</em>;
}</pre></td>
  </tr>
</table>


<!-- Section 2 ========================================================= -->
<h3 class="section">2. 処理の実行</h3>

<p>
  それでは実際に、作成したインタプリタを使用して<a href="./xml.html">このページのXHTMLデータ</a> を解釈してみましょう。<br />
  上記リンクを右クリックして「対象をファイルに保存(<span style="text-decoration: underline;">A</span>)...」を選び、"sample.xml" という名前で保存してください。
</p>

<table class="code">
<tr>
  <td><pre>
<em class="kwd">#include</em> <em class="str">"xml/xmlDocument.h"</em>
<em class="kwd">#include</em> <em class="str">"xml/xmlParseException.h"</em>

<em class="kwd">#include</em> <em class="str">"MyInterpreter.h"</em>

<em class="kwd">int</em> main(){

    <em class="cmt">//XMLデータの読み込み ------------------------------</em>

    xml::Document* lpDoc;

    <em class="kwd">try</em> {
        lpDoc =xml::Document::<a href="http://www.nowhere.co.jp/~narita/library/xml/doc/Document/reference/index.html#LOAD">load</a>(<em class="str">"sample.xml"</em>);
    }
    <em class="kwd">catch</em> (xml::ParseException&amp; e){
        e.Print(stderr);
        exit(EXIT_FAILURE);
    }

    <em class="cmt">//インタプリタ処理 ----------------------------------</em>

    MyInterpreter i;

    <em class="kwd">try</em> {
        i.<a href="http://www.nowhere.co.jp/~narita/library/xml/doc/Interpreter/reference/index.html#INIT">Init</a>(lpDoc);
        i.<a href="http://www.nowhere.co.jp/~narita/library/xml/doc/Interpreter/reference/index.html#RUN">Run</a>();
    }
    <em class="kwd">catch</em> (xml::InterpretException&amp; e){
        e.Print(stderr);
        exit(EXIT_FAILURE);
    }

    <em class="cmt">//データの解放</em>
    xml::Document::<a href="http://www.nowhere.co.jp/~narita/library/xml/doc/Document/reference/index.html#RELEASE">release</a>(lpDoc);

    <em class="kwd">return</em> <em class="lit">0</em>;
}</pre></td>
  </tr>
<tr>
  <td class="result">
    <pre>
http://www.codelogy.org//img/codelogy.png
http://www.codelogy.org/
http://www.codelogy.org/archives/2007/05/codelogy.html
http://www.nowhere.co.jp/~narita/library/xml/doc/Interpreter/index.html
http://www.nowhere.co.jp/~narita/library/xml/doc/Interpreter/reference/index.html#PROC
http://www.nowhere.co.jp/~narita/library/xml/doc/Elem/reference/index.html#NAME./xml.html
http://www.nowhere.co.jp/~narita/library/xml/doc/Document/reference/index.html#LOAD
http://www.nowhere.co.jp/~narita/library/xml/doc/Interpreter/reference/index.html#INIT
http://www.nowhere.co.jp/~narita/library/xml/doc/Interpreter/reference/index.html#RUN
http://www.nowhere.co.jp/~narita/library/xml/doc/Document/reference/index.html#RELEASE
http://www.codelogy.org/archives/2006/01/xml.html
http://www.codelogy.org/archives/2007/05/codelogy.html
http://www.codelogy.org/
http://www.codelogy.org/archives.html
http://www.codelogy.org/atom.xml
http://www.sixapart.jp/movabletype/
http://validator.w3.org/check?uri=referer
http://www.w3.org/Icons/valid-xhtml10</pre></td>
  </tr>
</table>

<p>
  このように、できるだけ少ない手間でXMLデータの処理を記述できるようフレームワークを設計してみました。<br />
  「ここをこうした方が良い」などの意見があれば、ぜひお寄せください。
</p>

<div class="signature">
  担当: 成田
</div>]]>
   </content>
</entry>
<entry>
   <title>Haskell でバグの出にくいプログラミング (4) ローカルスコープによる変数代入の模倣</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/04/haskell_4.html" />
   <id>tag:www.codelogy.org,2008://28.10487</id>
   
   <published>2008-04-06T10:03:45Z</published>
   <updated>2008-04-06T10:16:43Z</updated>
   
   <summary> 前回は、副作用である変数代入という概念が純粋関数型言語である Haskell ...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="Haskell" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="8" label="haskell" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
<a href="http://www.codelogy.org/archives/2008/01/haskell_3.html">前回</a>は、副作用である変数代入という概念が純粋関数型言語である Haskell には存在しないということを書きました。 今回と次回は、そのような変数という概念を純粋関数的に模倣した Haskell の State モナドについて書こうと思います。
</p>
<p>今回は、State モナドの説明の前段階として、ローカルスコープを用いた変数代入の模倣についてです。</p>
]]>
      <![CDATA[<h3 class="section">ローカルスコープの妙技</h3>
<p>前回の記事で載せたコードをもう一度掲載します。</p>
<table class="code" cellspacing="4">
  <tr>
    <td><pre>x = <em class="lit">3</em>

main = <em class="kwd">print</em> x
    <em class="kwd">where</em>
      x = <em class="lit">100</em></pre></td>
  </tr>
</table>
<p>このプログラムは、x の値を出力するというものですが、出力される値は where 節内で定義された x です。 一見すると、x という変数に値を代入しているようにも見えますが、実際は main 関数内で局所的に定義された別の x であり、 グローバルスコープがローカルスコープによって部分的に隠蔽されているだけで、グローバルスコープにある x の値は不変です。 当然ながら、このような動作は純粋関数的です。</p>
<p>このローカルスコープをうまく使うことで、変数を使っているように見せることができます。</p>
<table class="code" cellspacing="4">
  <tr>
    <th>Haskell</th>
    <th>Haskell のコードと等価な C++ のコード</th>
  </tr>
  <tr>
    <td><pre>hoge x =
    <em class="kwd">let</em> y = <em class="lit">3</em> + x
        z = <em class="lit">2</em> * x <em class="kwd">in</em>
    <em class="kwd">let</em> x = y + z <em class="kwd">in</em>
    <em class="lit">2</em> * x

main =
    <em class="kwd">print</em> $ hoge <em class="lit">6</em></pre></td>
    <td><pre>#include &lt;iostream&gt;

<em class="kwd">int</em> hoge(<em class="kwd">const</em> <em class="kwd">int</em> x){
  <em class="kwd">const</em> <em class="kwd">int</em> y = <em class="lit">3</em> + x;
  <em class="kwd">const</em> <em class="kwd">int</em> z = <em class="lit">2</em> * x;
  {
    <em class="kwd">const</em> <em class="kwd">int</em> x = y + z;
    <em class="kwd">return</em> <em class="lit">2</em> * x;
  }
}

<em class="kwd">int</em> main(<em class="kwd">void</em>){
  std::cout &lt;&lt; hoge(<em class="lit">6</em>) &lt;&lt; std::endl;
  <em class="kwd">return</em> <em class="lit">0</em>;
}</pre></td>
  </tr>
</table>
<p>解りやすさのため、C++ のコードも併記しました。 Haskell のコードでは、ローカルスコープを定義できる let 〜 in ... 構文を使用しました。 それによって、x の値が上書きされているように見えるプログラムを組むことができます。</p>
<h3 class="section">関数の引数で隠蔽</h3>
<p>当然ながら、関数の引数もローカルスコープ内に入っているので、さきほどのプログラムを関数の組み合わせで書くことができます。</p>
<table class="code" cellspacing="4">
  <tr>
    <td><pre>hoge x =
    <em class="kwd">let</em> bar x = <em class="lit">2</em> * x <em class="kwd">in</em>
    <em class="kwd">let</em> foo y z = bar (y + z) <em class="kwd">in</em>
    foo (<em class="lit">3</em> + x) (<em class="lit">2</em> * x)

main =
    <em class="kwd">print</em> $ hoge <em class="lit">6</em></pre></td>
  </tr>
</table>

<p>特に、Haskell では無名関数をλ式というもので作ることができるので、それを用いると関数名を省けて、手軽に書くことができます。</p>
<table class="code" cellspacing="4">
  <tr>
    <td><pre>hoge x =
    (\y z -> (\x -> <em class="lit">2</em> * x) (y + z)) (<em class="lit">3</em> + x) (<em class="lit">2</em> * x)

main =
    <em class="kwd">print</em> $ hoge <em class="lit">6</em></pre></td>
  </tr>
</table>
<p>λ式は、(\引数リスト -> 処理) という風に定義されます。 前々述のコードと見比べてみると、分かりやすいかと思います。</p>

<h3 class="section">ローカルスコープを抜けると過去だった</h3>
<p>しかし、当然ながらローカルスコープを抜けてしまうと、代入されたように見えた値が元に戻ってしまいます。 そのため、変数代入をローカルスコープで模倣する場合、変更があった先の処理は全てそのローカルスコープ内にいれてやる必要があります さらに、変更がある度にλ式や let 構文を何回も使う必要があり、面倒ですし、読みにくそうです。</p>
<p>そこで、このようなローカルスコープによる変数代入を模倣しつつ、ローカルスコープから勝手に出れないようにする仕組みがあると便利です。 次回は、そのような仕組みを実際に定義し、State モナドの説明をしようと思います。</p>

<div class="signature">
担当：齋藤 (刻々と状態の変化する現実世界はローカルスコープが無限に入れ子になっているのでいつかスタックオーバーフローする、と言ってみるテスト)
</div>
]]>
   </content>
</entry>
<entry>
   <title>宣言の位置</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/04/post_9.html" />
   <id>tag:www.codelogy.org,2008://28.10480</id>
   
   <published>2008-04-05T08:00:00Z</published>
   <updated>2008-05-01T08:27:58Z</updated>
   
   <summary>        C言語では、ローカル変数の宣言を関数の始めに宣言する必要がありま...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="C++" scheme="http://www.sixapart.com/ns/types#category" />
   
   <category term="13" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<div class="section">
  <p>
    C言語では、ローカル変数の宣言を関数の始めに宣言する必要がありました。<br />
    これを習慣としているのか、C++ でもローカル変数・オブジェクトの宣言を関数の開始位置で行う人がいます。
  </p>
  <table class="code">
  <tr>
    <td>
      <pre>
<em class="cmt">//分散を求める関数 (C++スタイル宣言)</em>
<em class="kwd">int</em> variance(<em class="kwd">const</em> Array&lt;<em class="kwd">double</em>&gt;&amp; ad){
    assert(ad);

    <em class="kwd">double</em> dSum =<em class="lit">0</em>;

    <em class="kwd">int</em> i;
    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;ad.size; ++i) dSum +=ad[i];

    <em class="kwd">double</em> dAvr   =dSum/ad.size;
    <em class="kwd">double</em> dSumSq =<em class="lit">0</em>;

    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;ad.size; ++i){

        <em class="kwd">double</em> dTmp =ad[i] - dAvr;

        dSumSq +=dTmp*dTmp;
    }

    <em class="kwd">return</em> dSumSq/ad.size;
}</pre></td>
    <td>
      <pre>
<em class="cmt">//分散を求める関数 (Cスタイル宣言)</em>
<em class="kwd">int</em> variance(<em class="kwd">const</em> Array&lt;<em class="kwd">double</em>&gt;&amp; ad){
    assert(ad);

    <em class="kwd">double</em> dSum   =<em class="lit">0</em>;
    <em class="kwd">double</em> dSumSq =<em class="lit">0</em>;
    <em class="kwd">double</em> dAvr;
    <em class="kwd">double</em> dTmp;
    <em class="kwd">int</em> i;

    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;ad.size; ++i) dSum +=ad[i];

    dAvr =dSum/ad.size;

    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;ad.size; ++i){

        dTmp =ad[i] - dAvr;

        dSumSq +=dTmp*dTmp;
    }

    <em class="kwd">return</em> dSumSq/ad.size;
}</pre></td>
    </tr>
  </table>
  <p>
    それでも動作には何の支障もありませんが、変数の「宣言」と「実際に使われ始める位置」が離れてしまうため、プログラムがやや読みづらくなります。
    また、上例のCスタイルの方では、２番目のループ内でのみ使われる変数 <code>dTmp</code> のスコープが関数全体に及んでしまうのも、あまり良い状況ではないでしょう。<br />
    しかし、C++ が変数・オブジェクトの宣言を関数の任意の位置で行えるようになっているのは、このような可読性に関する (些末な) 問題のためだけではありません。
    これには、C にはなかった「クラス」「オブジェクト」が大きく関係しています。
  </p>
</div>]]>
      <![CDATA[<div class="section">
  <p>
    <b>int</b>, <b>double</b> などのプリミティブ (組み込み) 型の変数に加えて、C++ ではクラス型のオブジェクトを扱います。
    クラス型のオブジェクトの振る舞いはユーザが (ある程度) 自由に定義することができます。
    例えば、「コンストラクタによって初期化することはできるが、それ以降の変更は許可しない」というオブジェクト作ることも不可能ではありません。
  </p>
  <table class="code">
  <tr>
    <td>
        <pre>
<em class="kwd">class</em> Result {
<em class="kwd">public</em>:

    <em class="cmt">//construction</em>
    Result (<em class="kwd">const</em> Result&amp;);
    Result (<em class="kwd">double</em> dAvr, <em class="kwd">double</em> dVar);

    <em class="cmt">//member access (getting)</em>
    <em class="kwd">double</em> Average() <em class="kwd">const</em>;
    <em class="kwd">double</em> Variant() <em class="kwd">const</em>;

<em class="kwd">protected</em>:

    <em class="kwd">double</em> m_dAvr;
    <em class="kwd">double</em> m_dVar;

<em class="kwd">protected</em>:

    <em class="cmt">//operator</em>
    Test&amp; <em class="kwd">operator</em> = (<em class="kwd">const</em> Test&amp;);

};</pre></td>
    <td>
      <pre>
<em class="cmt">//コピーコンストラクタ</em>
Result::Result(<em class="kwd">const</em> Result&amp; r)
: m_dAvr(r.m_dAvr), m_dVar(r.m_dVar) {
}

<em class="cmt">//コンストラクタ</em>
Result::Result(<em class="kwd">double</em> dAvr, <em class="kwd">double</em> dVar)
: m_dAvr(dAvr), m_dVar(dVar) {
}

<em class="cmt">//代入 [forbidden to be used]</em>
Result&amp; Result::<em class="kwd">operator</em> = (<em class="kwd">const</em> Result&amp;){
    abort();
}

<em class="cmt">//「平均」の取得</em>
<em class="kwd">double</em> Result::Average() <em class="kwd">const</em> {
    <em class="kwd">return</em> m_dAvr;
}

<em class="cmt">//「分散」の取得</em>
<em class="kwd">double</em> Result::Variance() <em class="kwd">const</em> {
    <em class="kwd">return</em> m_dVar;
}</pre></td>
    </tr>
  </table>
  <p>
    さて、このクラスを使って、最初の例の variance 関数を、分散だけでなく平均の値も返すことができる関数に変更してみましょう。<br />
    C++スタイルの宣言を使用するコード は問題なく変更できましたが、Cスタイルの宣言ではこれができません。
    関数の開始時点では、コンストラクタに渡す値が決定されていないためオブジェクトを作ることができず、かと言って、これらの値が計算されてからオブジェクトを作るのでは、Cスタイル宣言のルールに違反してしまいます。
  </p>
  <table class="code">
  <tr>
    <td>
      <pre>
<em class="cmt">//平均・分散を求める関数 (C++スタイル宣言)</em>
<em class="kwd">int</em> variance(<em class="kwd">const</em> Array&lt;<em class="kwd">double</em>&gt;&amp; ad){
    assert(ad);

    <em class="kwd">double</em> dSum =<em class="lit">0</em>;

    <em class="kwd">int</em> i;
    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;ad.size; ++i) dSum +=ad[i];

    <em class="kwd">double</em> dAvr   =dSum/ad.size;
    <em class="kwd">double</em> dSumSq =<em class="lit">0</em>;

    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;ad.size; ++i){

        <em class="kwd">double</em> dTmp =ad[i] - dAvr;

        dSumSq +=dTmp*dTmp;
    }

    Result res(dAvr, dSumSq/ad.size);

    <em class="kwd">return</em> res;
}</pre></td>
    <td>
      <pre>
<em class="cmt">//平均・分散を求める関数 (Cスタイル宣言)</em>
<em class="kwd">int</em> variance(<em class="kwd">const</em> Array&lt;<em class="kwd">double</em>&gt;&amp; ad){
    assert(ad);

    <em class="kwd">double</em> dSum   =<em class="lit">0</em>;
    <em class="kwd">double</em> dSumSq =<em class="lit">0</em>;
    <em class="kwd">double</em> dAvr;
    <em class="kwd">double</em> dTmp;
    <em class="kwd">int</em> i;
    Result res; <em class="cmt">//コンパイルエラー</em>

    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;ad.size; ++i) dSum +=ad[i];

    dAvr =dSum/ad.size;

    <em class="kwd">for</em> (i=<em class="lit">0</em>; i&lt;ad.size; ++i){

        dTmp =ad[i] - dAvr;

        dSumSq +=dTmp*dTmp;
    }

    <em class="kwd">return</em> res;
}</pre></td>
    </tr>
  </table>
  <p>
    もちろん、この問題を解決する手段はないわけではありません。
    ざっと考えただけでも、以下のような方法があげられます。
  </p>
  <ul>
  <li>Result オブジェクトの宣言後の値変更を認める。(代入を許可 | Set～系のメンバ関数を追加 | メンバ変数を <b>public</b> 宣言) </li>
  <li>それぞれ平均, 分散を <b>dounle</b> で返す関数を作り、その戻り値をコンストラクタに渡す。</li>
  <li><b>new</b> 演算子を使ってオブジェクトを作成し、そのアドレスを返す。</li>
  </ul>
  <p>
    しかし、これらの方法では、
  </p>
  <ul>
  <li>メンバへのアクセス制約を緩めてしまう。</li>
  <li>計算の重複が生じる。(平均を二回計算することになる。)</li>
  <li>呼び出し側で、返されたアドレスに対して <b>delete</b> を行う必要性がある。</li>
  </ul>
  <p>
    といった不都合が生じてしまい、お世辞にもスマートなやり方とは言えません。
  </p>
  <p>
    そもそも、こういったやり方を選ぶのであれば、C++ のクラスではなく、C の構造体を使っていれば良いわけです。
    クラス, オブジェクトを使ってさえいれば、C++ プログラミング (≒オブジェクト指向) というわけではありません。<br />
    C++ は基本的に C 言語の文法を受け継いではいますが、C とは異なる言語仕様・コーディングの「思想」に基づいて作られています。
    これをきちんと理解していない人が書くプログラムは、「C++使ってるけど、やってることはC」になってしまいがち。
    新しいパラダイムにシフトする際は、合わない習慣はスッパリと捨て去ることが肝心です。
</p>
</div>
<div class="signature">
  担当: 成田 (a native C++ writer)
</div>]]>
   </content>
</entry>
<entry>
   <title> 0からはじめる計算幾何学 第04回 過去のプログラムの有効活用</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/03/0_03.html" />
   <id>tag:www.codelogy.org,2005://28.10404</id>
   
   <published>2008-03-08T14:00:00Z</published>
   <updated>2008-03-11T13:49:10Z</updated>
   
   <summary> 昔書いたプログラムをもう一度使えないかと考えることは、多くのプログラマにとって...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="計算幾何学" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
昔書いたプログラムをもう一度使えないかと考えることは、多くのプログラマにとって（そしてエントリのネタを探す私にとっても）重要なことです。
今日は、過去の遺産を有効活用して楽に問題を解いた事例を紹介しましょう。UVa Online Judge の 10012番、<a href="http://icpcres.ecs.baylor.edu/onlinejudge/index.php?option=com_onlinejudge&page=show_problem&problem=953">How Big Is It?</a> です。
</p>
]]>
      <![CDATA[<p>
まずは問題の概要を説明しましょう。
</p>

<blockquote>
<p>
いくつかの円が与えられます。これらの円を全て含むことが出来る最小の長方形の横幅を求めるプログラムを作成しなさい。ただし、どの円も長方形の底辺に接するように含めなければなりません。
</p>
<div class="cite">
<a href="http://icpcres.ecs.baylor.edu/onlinejudge/index.php?option=com_onlinejudge&page=show_problem&problem=953">http://icpcres.ecs.baylor.edu/onlinejudge/index.php?option=com_onlinejudge&page=show_problem&problem=953</a>
</div>
</blockquote>

<p>
<a href="http://www.codelogy.org/archives/2007/12/zero03.html">以前のエントリ</a>で紹介した問題とほとんど同じ問題です。大きく違うところは以下の2つ。
<ul><li>「長方形の横幅の最小値が閾値以下か？」が「長方形の横幅の最小値はいくつか？」になった</li>
<li>「二つの円の間にもう一つの小さな円が入り込むことはない」という仮定がなくなった</li></ul>
それでは、以前のコードを書き換えてこれらの変更に対応させましょう。
</p>

<p>
まずは前者ですが、これは特筆すべきこともありません。ただ書き換えるのみです。
</p>

<table class="code">
<tr>
  <td><pre>
<em class="cmt">/*</em> 
<em class="cmt">円の半径の並び、円の個数を引数として受け取る。</em>
<em class="cmt">円を詰められる最小の長方形の横幅を返す。</em>
<em class="cmt">( next_permutationは順列を生成する。algorithmヘッダの中で定義されている)</em>
<em class="cmt">*/</em>
double execute(<em class="kwd">int</em> *radii, <em class="kwd">int</em> rNum){
  <em class="kwd">double</em> result;

  sort(radii, radii+rNum);
  result = calculate(radii, rNum);

  <em class="kwd">while</em> (next_permutation(radii, radii+rNum))
    result = min(result, calculate(radii, rNum))
  <em class="kwd">return</em> result;
}</pre></td>
  </tr>
</table>

<p>
これに比べて、後者の変更は厄介です。アルゴリズムから考え直さなければいけません。
</p>

<p>
与えられた半径とその並べる順番に対してそれを詰められる長方形の最小の幅を返す、次のようなアルゴリズムを考えてみました。
</p>
<ul>
<li>1つ目の円は、長方形の左端に置く。</li>
<li>2つ目以降の円は、今までに長方形に詰めた円の中で中心が一番右側のものに接するように置く。ただし、それが不適切な置き方になってしまったときは、右から2番目の円に接するように置く。それでも駄目なら右から3番目、4番目・・・と試していく。</li>
<li>円の「不適切な置き方」というのは、その円が別の円と重なってしまう、あるいは長方形の左端のさらに左側にはみ出してしまうような置き方である。</li>
<li>全ての円を詰め終わったら、全ての円の右端の位置を調べ、その中で最も右側にあるものの左右方向の位置を返す。</li>
</ul>

<p>
さて、ここで不安になるのが計算量です。上記のアルゴリズムはO(n<sup>3</sup>)のオーダになっています。さらにこれを可能な円の並べ方の数だけ繰り返しますので、結局O(n<sup>3</sup> × n!)の時間が必要になります。<br />
一見絶望的なオーダですが、問題文によると円の数は最大で8個と書かれていますので、これでも十分間に合います。<br />
それでは、実装してみましょう。
</p>

<table class="code">
<tr>
  <td><pre>
<em class="cmt">円の個数の最大値</em>
<em class="kwd">const</em> <em class="kwd">int</em> MAX_R = <em class="lit">8</em>;

<em class="cmt">/*</em>
<em class="cmt">円の半径の配列と円の個数を引数として受け取る。</em>
<em class="cmt">配列の通りに円を詰めたときの横幅を返す。</em>
<em class="cmt">*/</em>
<em class="kwd">double</em> calculate(<em class="kwd">double</em> *radii, <em class="kwd">int</em> rNum){
  <em class="cmt">// 円の中心の横方向の座標を格納する配列。</em>
  <em class="cmt">// 長方形の左端を0.0とする。</em>
  <em class="kwd">double</em> position[MAX_R];

  position[0]=radii[0];

  <em class="kwd">for</em> (<em class="kwd">int</em> i=1; i&lt;rNum; i++){
    <em class="kwd">int</em> adjacence = i;
    <em class="kwd">bool</em> invalid_place;

    <em class="kwd">do</em> {
      adjacence--;

      <em class="cmt">// 1番目の円の隣に(i)番目の円を置く場合</em>
      if (adjacence==0){
        position[i] = max(position[i], radii[i]);
        break;
      }

      <em class="cmt">// adjacence 番目の円の隣に i 番目の円を置く場合</em>
      position[i] = position[adjacence] + width(radii[adjacence], radius[i]);

      <em class="cmt">// 不適切な置き方かどうかチェック</em>
      invalid_place = false;
      <em class="cmt">// 他の円との重なりをチェック</em>
      <em class="kwd">for</em> (<em class="kwd">int</em> j=0; j&lt;adjacence && !invalid_place; j++)
        invalid_place = lap(radii, position, j, i);

      <em class="cmt">// 長方形からのはみ出しをチェック</em>
      invalid_place = invalid_place ||  position[i]&lt;=radii[i];

    } <em class="kwd">while</em> (invalid_place);

  }

  <em class="cmt">// 円の右端を計算</em>
  <em class="kwd">double</em> result[MAX_R];

  <em class="kwd">for</em> (<em class="kwd">int</em> i=0;i&lt;rNum;i++)
    result[i]=position[i]+radii[i];

  <em class="cmt">// 最大のものを返す</em>
  <em class="kwd">return</em> *max_element(result, result+rNum);
}

<em class="cmt">半径 r1 の円と半径 r2 の円を並べたとき、それらの中心の</em>
<em class="cmt">横方向の距離を返す。</em>
<em class="kwd">double</em> width(<em class="kwd">double</em> r1,<em class="kwd">double</em> r2){
  <em class="kwd">return</em> sqrt((r1+r2)*(r1+r2)-(r1-r2)*(r1-r2));
}

<em class="cmt">r1_index番目の円とr2_index番目の円が重なっているかどうかを返す。</em>
<em class="cmt">2つの円の中心同士の距離と、半径の和を比較することで求める。</em>
<em class="kwd">bool</em> lap(<em class="kwd">double</em> *radii, <em class="kwd">double</em> *position, <em class="kwd">int</em> r1_index, <em class="kwd">int</em> r2_index){
	<em class="kwd">double</em> r1_x = position[r1_index];
	<em class="kwd">double</em> r2_x = position[r2_index];
	<em class="kwd">double</em> r1_y = radii[r1_index];
	<em class="kwd">double</em> r2_y = radii[r2_index];

	<em class="kwd">return</em> (Molar_Morrison(r2_x-r1_x, r2_y-r1_y) &lt; radii[r1_index]+radii[r2_index]);
}

</pre></td>
  </tr>
</table>
<p>
分かりづらい点といえば、「1番目の円の隣に i 番目の円を置く場合」の部分でしょうか。<br />
このケースでは、「置いた円が長方形をはみ出しているか」のチェックを行い、はみ出していれば長方形の左端と接するように置きなおすことになります。ここで、はみ出しているかどうかは position[i] &lt; radii[i] を使って判定できますので、結局 position[i] = max(position[i], radii[i]); と書けば、はみ出しているかのチェックとその場合の値の書き換えが同時に出来ることになります。
</p>

<p>
接している2つの円の横幅を求める処理は、入力値がdouble型になってテーブル引きが出来なくなった関係で、毎回計算するように書き換えました。これをwidth関数としてまとめています。<br />
また、2つの円の重なりを判定するlap関数にMolar_Morrison関数を使ってみました。これは(x, y)ベクトルの長さを計算する関数ですが、詳細は<a href="http://www.codelogy.org/archives/2008/02/post_8.html#more">こちら</a>をご覧ください。
</p>

<p>
このようにして、無事プログラムは完成しました。<br />
プログラムを再利用することのメリットは、一度打ったコードをもう一度打ち直さないという作業の省略のみにとどまりません。アルゴリズムだけを読み取って再利用すれば、一度行った試行錯誤をもう一度繰り返さないという、思考の省略もできるのです。<br />
もちろん、プログラムからアルゴリズムを読み取るためには、そのプログラムが綺麗に描かれていることが重要になってきます。「この関数をコピーして使うことはもうないから」などと言わず、常に読みやすいコードを書くことを心がけたいものです。
</p>

<div class="signature">担当:田山</div>]]>
   </content>
</entry>
<entry>
   <title>コメントつけろよ</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/02/comment.html" />
   <id>tag:www.codelogy.org,2008://28.10329</id>
   
   <published>2008-02-24T07:00:00Z</published>
   <updated>2008-05-01T09:02:18Z</updated>
   
   <summary>   プログラマは自分でコードを書くことができるだけでなく、他人が書いたコードを...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="コード保守" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  プログラマは自分でコードを書くことができるだけでなく、他人が書いたコードを (ある程度は) 読むことができなければなりません。
  その際に最もゲンナリさせられるのが、<a href="http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF)">コメント</a>が全くないソースコードです。</p>
<p>
  腕の立つプログラマのコードというのはきちんと構造化されいるため、コメントに頼らずとも作者の意図をきちんと読み取ることができます。
  しかし、そのようなコードを書くプログラマは、コメントもきちんと付けるもの。
  むしろ、初心者や読みづらいコードを書くプログラマほど、コメントも疎かになる傾向があるようです。<br />
  彼らが自分のソースコードにコメントを付けない理由として挙げるものとしては、
</p>
<dl>
<li>時間がなかったから。(急いで修正したから。)</li>
<li>公開するつもりのないコードだから。</li>
<li>コメントを付けると、コメントに頼ってコードを読むようになってしまうから。</li>
<li>コメントを入れるのと、素人のコードっぽく見えるから。</li>
<li><a href="http://d.hatena.ne.jp/minekoa/20080125/1201263076">コードの可読性は品質には影響しない。可読性をあげて良いことがあるのか？</a></li>
</ul>
<p>
  などなど……。（いずれも、実際に言われたことがある。)<br />
  人それぞれに事情や主義主張があるのは分かりますが、正直「そのコードの保守運用をさせられるこっちの身にもなってくれ」と言いたくなります。(そして、実際に言っています。^^;)
</p>
]]>
      <![CDATA[<h3 class="section">コメントのないコードの例</h3>
<div class="section">
  <p>
    次に示す関数は、西暦 1年 1月 1日からの経過日数から日付を計算し、yyyy/mm/dd の形式で表示するものです。<br />
    紀元前の日付や閏年も考慮に入れているため、なかなかに複雑なコードになっています。<br />
    それにも関わらず、コメントが一切ないので読みづらいことこの上ありません。<br />
    このコードを読め (あるいはデバッグしろ) と言われたら、誰だって (´д｀;)ｴｪｰ となるのではないでしょうか。
  </p>
  <table class="code">
  <tr>
    <td><pre>
<em class="kwd">const</em> <em class="kwd">int</em> MONTH_DAYS[] ={
    <em class="lit">0</em>, <em class="lit">31</em>, <em class="lit">28</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>
};

<em class="kwd">const</em> <em class="kwd">int</em> MONTH_DAYS_BHX[] ={
    <em class="lit">0</em>, <em class="lit">31</em>, <em class="lit">29</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>
};

<em class="kwd">bool</em> bissextile(<em class="kwd">int</em> y){
    assert(y);
    <em class="kwd">return</em> !(y % <em class="lit">4</em>) &amp;&amp; (y % <em class="lit">100</em> || !(y % <em class="lit">400</em>));
}

<em class="kwd">void</em> printDate(<em class="kwd">int</em> nIdentity){

    <em class="kwd">if</em> (nIdentity &gt;= <em class="lit">0</em>){

        <em class="kwd">int</em> y =<em class="lit">1</em>;
        <em class="kwd">int</em> m =JAN;

        <em class="kwd">for</em> (;;){

            <em class="kwd">if</em> (bissextile(y)){

                <em class="kwd">if</em> (nIdentity &lt; <em class="lit">366</em>){
                   <em class="kwd">while</em> (nIdentity &gt;= MONTH_DAYS_BHX[m]) nIdentity -=MONTH_DAYS_BHX[m++]; 
                   <em class="kwd">break</em>;
                }
                nIdentity -=<em class="lit">366</em>;
            }
            <em class="kwd">else</em> {

                <em class="kwd">if</em> (nIdentity &lt; <em class="lit">365</em>){
                    <em class="kwd">while</em> (nIdentity &gt;= MONTH_DAYS[m]) nIdentity -=MONTH_DAYS[m++]; 
                    <em class="kwd">break</em>;
                }
                nIdentity -=<em class="lit">365</em>;
            }

            ++y;
         }

        printf(<em class="str">"%04d/%02d/%02d\n"</em>, y, m, nIdentity + <em class="lit">1</em>);
    }
    <em class="kwd">else</em> {
 
        nIdentity =-(nIdentity + <em class="lit">1</em>);

        <em class="kwd">int</em> y = -<em class="lit">1</em>;
        <em class="kwd">int</em> m =DEC;

        <em class="kwd">for</em> (;;){

            <em class="kwd">if</em> (bissextile(y)){

                <em class="kwd">if</em> (nIdentity &lt; <em class="lit">366</em>){

                    <em class="kwd">while</em> (nIdentity &gt;= MONTH_DAYS_BHX[m]) nIdentity -=MONTH_DAYS_BHX[m--];

                    printf(<em class="str">"%04d/%02d/%02d\n"</em>, y, m, MONTH_DAYS_BHX[m] - nIdentity);
                    <em class="kwd">break</em>;
                }
                nIdentity -=<em class="lit">366</em>;
            }
            <em class="kwd">else</em> {

                <em class="kwd">if</em> (nIdentity &lt; <em class="lit">365</em>){

                    <em class="kwd">while</em> (nIdentity &gt;= MONTH_DAYS[m]) nIdentity -=MONTH_DAYS[m--];

                    printf(<em class="str">"%04d/%02d/%02d\n"</em>, y, m, MONTH_DAYS[m] - nIdentity);
                    <em class="kwd">break</em>;
                }
                nIdentity -=<em class="lit">365</em>;
            }

            --y;
        }
    }

    <em class="kwd">return</em>;
}</pre></td>
    </tr>
  </table>
</div>

<h3 class="section">コメントを入れてみる</h3>
<div class="section">
  <p>
    では、このコードにコメントを入れてみましょう。<br />
    どれだけ読みやすくなるかを、自分の目で確かめてください。
  </p>
  <table class="code">
  <tr>
    <td><pre>
<em class="cmt">//月の日数 (平年用)</em>
<em class="kwd">const</em> <em class="kwd">int</em> MONTH_DAYS[] ={
    <em class="lit">0</em>, <em class="lit">31</em>, <em class="lit">28</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>
};

<em class="cmt">//月の日数 (閏年用)</em>
<em class="kwd">const</em> <em class="kwd">int</em> MONTH_DAYS_BHX[] ={
    <em class="lit">0</em>, <em class="lit">31</em>, <em class="lit">29</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>, <em class="lit">30</em>, <em class="lit">31</em>
};

<em class="cmt">//閏年の判定</em>
<em class="kwd">bool</em> bissextile(<em class="kwd">int</em> y){
    assert(y);
    <em class="kwd">return</em> !(y % <em class="lit">4</em>) &amp;&amp; (y % <em class="lit">100</em> || !(y % <em class="lit">400</em>));
}

<em class="cmt">//日付の計算・表示)</em>
<em class="kwd">void</em> printDate(<em class="kwd">int</em> nIdentity){

    <em class="kwd">if</em> (nIdentity &gt;= <em class="lit">0</em>){
        <em class="cmt">//紀元 (A.D.) ----------------------------------------------------------</em>

        <em class="cmt">//西暦元年 1月から開始</em>
        <em class="kwd">int</em> y =<em class="lit">1</em>;
        <em class="kwd">int</em> m =JAN;

        <em class="cmt">//１年未満になるまで、日数を引く</em>
        <em class="kwd">for</em> (;;){

            <em class="kwd">if</em> (bissextile(y)){
                <em class="cmt">//閏年の場合</em>

                <em class="kwd">if</em> (nIdentity &lt; <em class="lit">366</em>){
                   <em class="kwd">while</em> (nIdentity &gt;= MONTH_DAYS_BHX[m]) nIdentity -=MONTH_DAYS_BHX[m++]; 
                   <em class="kwd">break</em>;
                }
                nIdentity -=<em class="lit">366</em>;
            }
            <em class="kwd">else</em> {
                <em class="cmt">//平年の場合</em>

                <em class="kwd">if</em> (nIdentity &lt; <em class="lit">365</em>){
                    <em class="kwd">while</em> (nIdentity &gt;= MONTH_DAYS[m]) nIdentity -=MONTH_DAYS[m++]; 
                    <em class="kwd">break</em>;
                }
                nIdentity -=<em class="lit">365</em>;
            }

            ++y; <em class="cmt">//１年先 (未来) へ</em>
         } <em class="cmt">// for(;;)</em>

        printf(<em class="str">"%04d/%02d/%02d\n"</em>, y, m, nIdentity + <em class="lit">1</em>);
    }
    <em class="kwd">else</em> {
         <em class="cmt">//紀元前 (B.C.) --------------------------------------------------------</em>

        nIdentity =-(nIdentity + <em class="lit">1</em>);

        <em class="cmt">//紀元前 1年12月から開始</em>
        <em class="kwd">int</em> y = -<em class="lit">1</em>;
        <em class="kwd">int</em> m =DEC;

        <em class="cmt">//１年未満になるまで、日数を引く</em>
        <em class="kwd">for</em> (;;){

            <em class="kwd">if</em> (bissextile(y)){
                <em class="cmt">//閏年の場合</em>

                <em class="kwd">if</em> (nIdentity &lt; <em class="lit">366</em>){

                    <em class="kwd">while</em> (nIdentity &gt;= MONTH_DAYS_BHX[m]) nIdentity -=MONTH_DAYS_BHX[m--];

                    printf(<em class="str">"%04d/%02d/%02d\n"</em>, y, m, MONTH_DAYS_BHX[m] - nIdentity);
                    <em class="kwd">break</em>;
                }
                nIdentity -=<em class="lit">366</em>;
            }
            <em class="kwd">else</em> {
                <em class="cmt">//平年の場合</em>

                <em class="kwd">if</em> (nIdentity &lt; <em class="lit">365</em>){

                    <em class="kwd">while</em> (nIdentity &gt;= MONTH_DAYS[m]) nIdentity -=MONTH_DAYS[m--];

                    printf(<em class="str">"%04d/%02d/%02d\n"</em>, y, m, MONTH_DAYS[m] - nIdentity);
                    <em class="kwd">break</em>;
                }
                nIdentity -=<em class="lit">365</em>;
            }

            --y; <em class="cmt">//１年前 (過去) へ</em>
        } <em class="cmt">// for(;;)</em>
    }

    <em class="kwd">return</em>;
}</pre></td>
    </tr>
  </table>
  <p>
    このようにコメントが付けられていれば、プログラマの意図がコード中に明示されるため、読む側は頭の中で流れを整理しやすくなり、バグの特定なども容易になります。

  </p>
</div>

]]>
   </content>
</entry>
<entry>
   <title>Scala で遊んでみました</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/02/scala.html" />
   <id>tag:www.codelogy.org,2008://28.10303</id>
   
   <published>2008-02-17T11:46:39Z</published>
   <updated>2008-02-17T12:22:02Z</updated>
   
   <summary> 最近よく名前を聞くようになった Scala という言語で遊んでみました。 ...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<div class="section">
<p>最近よく名前を聞くようになった <a href="http://www.scala-lang.org/">Scala</a> という言語で遊んでみました。</p>
</div>
]]>
      <![CDATA[<h3 class="section">Scala の特徴</h3>
<div class="section">
<blockquote cite="http://ja.wikipedia.org/wiki/Scala">
<p>Scala (スカラ、Scalable Language) はオブジェクト指向言語と関数型言語の特徴を統合したマルチパラダイムのプログラミング言語である。</p>
<address><a href="http://ja.wikipedia.org/wiki/Scala">wikipedia</a></address>
</blockquote>
<p>様々な特徴があるようなのですが、個人的に気になったのが、</p>
</div>

<ul>
  <li>型推論を用いた静的型付けの言語である</li>
  <li>パターンマッチが使える</li>
  <li>遅延評価がある</li>
  <li>構文解析のためのパーサーコンビネータが標準ライブラリにある</li>
  <li>Java や .NET Framework のライブラリが使える</li>
  <li>標準ライブラリに Actor と呼ばれる Erlang のような文法の軽量プロセスがある</li>
</ul>
<div class="section">
<p>です。 理由としては、前半 4 つは Haskell の特徴でもあるので、Haskell 使いとしては見逃せません。 Java の Swing は使い慣れているので、GUI を作るのが楽そうだし、Erlang のような並列処理については前々から使ってみようと思っていたからです。</p>
</div>

<h3 class="section">チュートリアルに沿って</h3>
<div class="section">
<p>手始めに、<a href="http://www.scala-lang.org/docu/files/ScalaTutorial.pdf">A Scala Tutorial for Java programmers</a> (<a href="http://homepage.mac.com/takashi_miyamoto/scala/ScalaTutorial.pdf">和訳</a>) というチュートリアルを読み進めていきました。 Scala の概要を説明するのが目的だそうです。 (チュートリアルが古いのか、println 関数は、Console.println でないとコンパイルが通りませんでした。)</p>

<h4>全てはオブジェクト</h4>
<div class="section">
<p>Scala では全てのもの (関数や数など) はオブジェクトとして定義されています。 そのため、関数型言語のように、関数を別の関数の引数にしたり、関数を返す関数を定義することが自然にできます。 例えば、以下のプログラム</p>
<table class="code"><tr><td><pre><em class="lit">1</em> + <em class="lit">2</em> * <em class="lit">3</em> / x</pre></td></tr></table>
は、
<table class="code"><tr><td><pre><em class="lit">1</em>.+(<em class="lit">2</em>.*(<em class="lit">3</em>./(x)))</pre></td></tr></table>
<p>と同じ意味で、数字オブジェクトに四則演算のオペレータが定義されていることが窺えます。</p>
<p>上記のような四則演算以外でも、オブジェクトのメソッドの引数が一意に定まる場合、「.」とカッコを省略することができるようです。 例えば、以下のような書き方ができます。</p>
<table class="code"><tr><td><pre><em class="kwd">import</em> javax.swing._ <em class="cmt">//* の代わりに _ を使うようです</em>
<em class="kwd">import</em> java.awt._

<em class="kwd">object</em> SwingTest{
  <em class="kwd">def</em> main(args: Array[String]) = {
    <em class="kwd">var</em> frame = <em class="kwd">new</em> JFrame
    frame setDefaultCloseOperation (JFrame EXIT_ON_CLOSE)
    frame setSize <em class="kwd">new</em> Dimension (<em class="lit">640</em>, <em class="lit">480</em>)
    frame setVisible <em class="kwd">true</em>
  }
}</pre></td></tr></table>
<p>Java の Swing を呼び出して、640x480 のウインドウを出す例ですが、main 内の frame のメソッド呼出しが Java のそれとはかなり違います。 さらに、setDefaultCloseOperation と setSize はともに 1 引数ですが、前者にはカッコがあって、後者はありません。 こうしないとコンパイルが通らないからです。 ためしに、setDefaultCloseOperation の引数を 3 * 2 にしてみたら、カッコなしでもコンパイルが通りました。 どうやら、演算子の優先順位と左結合、右結合によってうまくいったりいかなかったりするようです。</p>
</div>

<h4>無名関数</h4>
<div class="section">
<p>関数型言語のいうところのλ式と似たようなものである無名関数が使えます。</p>
<table class="code"><tr><td><pre><em class="kwd">import</em> javax.swing._
<em class="kwd">import</em> java.awt._
<em class="kwd">import</em> java.awt.event._

<em class="kwd">class</em> ActionListenerProc(f: ActionEvent =&gt; Unit) <em class="kwd">extends</em> ActionListener{

  <em class="kwd">override</em> <em class="kwd">def</em> actionPerformed(ev: ActionEvent) = { f(ev) }

}

<em class="kwd">object</em> SwingTest2{

  <em class="kwd">def</em> createUI(pane: JPanel) = {
    <em class="kwd">var</em> but = <em class="kwd">new</em> JButton
    <em class="cmt">// 無名関数を使っている</em>
    but addActionListener (<em class="kwd">new</em> ActionListenerProc (ev =&gt; Console.println(ev)))
    pane add but
  }

  <em class="kwd">def</em> main(args: Array[String]) = {
    <em class="kwd">var</em> frame = <em class="kwd">new</em> JFrame
    frame setDefaultCloseOperation (JFrame EXIT_ON_CLOSE)
    frame setSize <em class="kwd">new</em> Dimension (<em class="lit">640</em>, <em class="lit">480</em>)

    createUI ((frame getContentPane).asInstanceOf[JPanel])

    frame setVisible <em class="kwd">true</em>
  }
}</pre></td></tr></table>
<p>無名関数は、({引数} =&gt; {式}) という形で宣言することができます。 複数の引数がある場合、({引数1} =&gt; {引数2} =&gt; ... =&gt; {式}) という風に宣言できます。 上記のプログラムは、無名関数を使って、ボタンが押されたら ActionEvent の内容を出力します。</p>
</div>

<h4>パターンマッチ</h4>
<div class="section">
<p>パターンマッチの例のため、Haskell でいうところの Maybe を定義してみました。 Maybe は計算が失敗する可能性のある時に返すものです。 まったく同じものが、Scala では Option というオブジェクトとして存在します。</p>
<table class="code"><tr><td><pre><em class="cmt">//Maybe</em> の定義
<em class="kwd">abstract</em> <em class="kwd">class</em> Maybe[A]
<em class="kwd">case</em> <em class="kwd">class</em> Just[A](v: A) <em class="kwd">extends</em> Maybe[A]{
  <em class="kwd">val</em> value = v
}
<em class="kwd">case</em> <em class="kwd">class</em> Nothing[A] <em class="kwd">extends</em> Maybe[A]


<em class="kwd">object</em> MaybeTest{

  <em class="kwd">def</em> find[A](l:List[A], key:A): Maybe[A] = {
    <em class="kwd">for</em>(x &lt;- l) <em class="kwd">if</em> (x == key) <em class="kwd">return</em> Just(x)
    <em class="kwd">return</em> Nothing[A]
  }

  <em class="kwd">def</em> search[A](db:List[A], key:A) = {
    <em class="cmt">// Maybe[A] を使ったパターンマッチ</em>
    find(db, key) <em class="kwd">match</em> {
      <em class="kwd">case</em> Just(v) =&gt;
        Console.println(v + <em class="str">": found"</em>)
      <em class="kwd">case</em> Nothing() =&gt;
        Console.println(key + <em class="str">": not found"</em>)
    }
  }

  <em class="kwd">def</em> main(args: Array[String]) = {
    <em class="kwd">val</em> db = List(<em class="str">"Narita"</em>, <em class="str">"Saito"</em>, <em class="str">"Matsuura"</em>, <em class="str">"Tayama"</em>)

    search(db, <em class="str">"Narita"</em>)
    search(db, <em class="str">"Nihei"</em>)
  }

}</pre></td></tr></table>
<p>パターンマッチできるクラスは、case class で定義する必要があります。 基底クラスを一つ作り、それを継承した case class を複数作る、というのが一般的です。 上記の例では、抽象クラス Maybe[A] (ジェネリック型。A は型パラメータ) を継承して、パターンマッチ可能な Just[A](v: A) と Nothing[A] というクラスを定義しています。</p>
<p>search メソッドの中で match {} という構文を用いて、find メソッドの返り値に対してパターンマッチを行っています。 それぞれのパターンの =&gt; の直前に if 文を書いて制限を加えることもできます。</p>
</div>

<h4>型推論</h4>
<div class="section">
<p>型推論を用いて、型を明記することなく静的に型をチェックできるはずなのですが、メソッドの引数には型を付けなくてはならないようで、あまりありがたみがありません。</p>
<table class="code"><tr><td><pre><em class="kwd">trait</em> Show{
  <em class="kwd">def</em> show(): String
}

<em class="kwd">class</em> Hoge <em class="kwd">extends</em> Show{
  <em class="kwd">override</em> <em class="kwd">def</em> show() = <em class="str">"Hoge"</em>
}

<em class="kwd">object</em> InfTest{
  <em class="cmt">//a show を使っているのだから、Show くらい推論してほしい</em>
  <em class="kwd">def</em> print(a: Show) = { Console println (a show) }

  <em class="kwd">def</em> main(args: Array[String]) = {
    print(new Hoge)
  }

}</pre></td></tr></table>
<p>trait を用いて、Mixin 専用のクラスを作ることができます。 この例では、文字列を返すメソッド show を持つ Show クラスを定義します。 それを Hoge が Mixin して、show メソッドを定義します。 そして、InfTest の print メソッドは、引数 a の show メソッドを呼び、それをコンソールに出力します。 ここで、この print メソッドの引数は Show クラスと推論して欲しいのですが、引数 a の型を明記しないとコンパイルエラーがでます。 メソッドのオーバーロードやクラススコープなどによって、同名のメソッドが存在しうるため、型の推論ができないのではないかと思われます。</p>
</div>
</div>

<h3 class="section">所感</h3>
<div class="section">
<p>チュートリアルを読んだ程度ですが、大雑把に Scala の使い方が分かりました。 構文にはなんだか曖昧な部分が多いように感じられましたが「しばらく書いていれば何となく分かる」感じの言語でした。</p>
<p>マルチパラダイム言語と呼ばれていますが、どちらかというとまだオブジェクト指向よりな部分が多いと思います。 Java よりオブジェクトの種類が細分化され、singleton なら object, Mixin 専用なら trait, パターンマッチ可にする case, 従来のクラスと同じ class などがあるようです。 継承の仕方や型の表現に対してもいくつかの表現があり、覚えなければならない規則はなかなか多そうです。</p>
<p>遅延評価、パーサコンビネータ、Erlang ライクな並列処理についても、もう少し遊んでみてから書こうと思います。</p>
</div>
<div class="signature">
<p>担当：齋藤 (まだ Haskell の方が好き)</p>
</div>]]>
   </content>
</entry>
<entry>
   <title>平方根を使わないピタゴラス加算</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/02/post_8.html" />
   <id>tag:www.codelogy.org,2007://28.10233</id>
   
   <published>2008-02-07T14:00:00Z</published>
   <updated>2008-05-01T08:30:43Z</updated>
   
   <summary> 二次元座標上の2点間の距離を求めたいとき、複素数の絶対値を求めたいとき、その他...</summary>
   <author>
      <name></name>
      
   </author>
         <category term="アルゴリズム" scheme="http://www.sixapart.com/ns/types#category" />
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
二次元座標上の2点間の距離を求めたいとき、複素数の絶対値を求めたいとき、その他いろいろなときに x = √(a<sup>2</sup> + b<sup>2</sup>) という式を使います（これをpythagorean additionと言うそうです）。これを実装するとき、 
</p>
<table class="code">
<tr><td><pre>
sqrt( a*a + b*b )
</pre></td></tr>
</table>
<p>
という文がよく使われますが、この文を無闇に使っていると、あまり嬉しくない事態を引き起こすことになります。
</p>]]>
      <![CDATA[<p>
さて、この文ののどこがいけないのでしょうか。<br />
賢明な皆さまはもうお気づきでしょうが、a*a + b*bはオーバーフローを引き起こすおそれがあるのです。変数の値域を保証できるのならともかく、そうでなければ次に挙げる3つの対策のいずれかを採るべきです。
</p>

<h3>1.式変形</h3>
<p>
a' = max( |a|, |b| ),<br />
b' = min( |a|, |b| )<br />
とおくと、<br />
<br />
√(a<sup>2</sup> + b<sup>2</sup>) = a'√(1 + (b'/a')<sup>2</sup>) <br />
<br />
と変形できます。この式を使うとオーバーフローのリスクを減らすことができます。<br />
実装する際は、うっかり0除算のチェックを忘れないように注意してください。<br />
</p>

<h3>2.hypot()関数を使う</h3>
<p>
C ( C++ )言語の math.h ( cmath ) ヘッダには hypot() という関数が定義されていて、double型の引数 a, b に対し √(a<sup>2</sup> + b<sup>2</sup>) をdouble型で返してくれます。この関数は（返り値がdouble型に収まる限り）オーバーフローを起こさないように設計されているはずですので、安心して使うことができます。
</p>

<h3>3.Moler-Morrison Algorithmを使う</h3>
<p>
さて、こちらが今日の本題です。<br />
Cleve Moler と Donald Morrison は、√(a<sup>2</sup> + b<sup>2</sup>)を求めるための、短く、堅牢で、正確で、そして四則演算しか使わないアルゴリズムを発表しました。これをC++言語で書き直したものを御覧下さい。
</p>

<table class="code">
<tr><td><pre>
<em class="kwd">double</em> Molar_Morrison(<em class="kwd">double</em> a, <em class="kwd">double</em> b){
  a = fabs(a);  b = fabs(b);
  <em class="kwd">if</em> (a &lt; b)   swap(a, b);
  <em class="kwd">if</em> (b == <em class="lit">0</em>)  <em class="kwd">return</em> a;

  <em class="kwd">const</em> <em class="kwd">int</em> ITERATION_NUMBER = <em class="lit">3</em>;

  double s;  
  <em class="kwd">for</em> (<em class="kwd">int</em> i=<em class="lit">0;</em> i&lt;ITERATION_NUMBER; i++){
    s=(b/a)*(b/a);
    s/=<em class="lit">4</em>+s;
    a+=<em class="lit">2</em>*a*s;
    b*=s;
  }

  <em class="kwd">return</em> a;
}
</td></tr></pre>
</table>
<p>
このアルゴリズムの動作の肝を説明します。<br />
√((a+2as)<sup>2</sup> + (bs)<sup>2</sup>) は、式変形をしてみると √(a<sup>2</sup> + b<sup>2</sup>) に全く等しいことが分かります。また明らかに s<1なので、bの値は0に収束していきます。したがって、aは次第に√(a<sup>2</sup> + b<sup>2</sup>)に収束していくと言えるのです。
</p>
<p>
さて、プログラム中に ITERATION_NUMBER という定数が登場します。<br />
これは「この回数だけループを繰り返せばdouble型で十分な精度が得られる」という数字です。ループを3回繰り返せば20桁の精度で解を求めることができ、また1回繰り返すごとに精度の桁数は少なくとも3倍になることが分かっています。
</p>
<p>
このプログラムは実行速度の面では若干の不安が残りますが、forループをアンローリングし、コンパイラの最適化オプションを使うなどの高速化を施せば、hypot()関数にも引けを取らない速度まで改善させることが出来ます。
</p>
<p>
また、オーバーフローのリスクが少ないこと、四則演算のみで確かに計算できていることにも注目してください。
</p>
<p>
実装の簡単さ・分かりやすさから、つい安直な方法を選んでしまいがちです。が、一時は面倒でも確実な方法を採ったほうが、最終的に面倒が少ないに違いないのです。
</p>
<p>
担当：田山（<a href="http://en.wikipedia.org/wiki/Pythagorean_addition">ピタゴラス加算の記号もある</a>らしいのですが、どう見ても排他的論理和です）
</p>]]>
   </content>
</entry>
<entry>
   <title>[OpenCV] 動的背景更新とオブジェクトの認識</title>
   <link rel="alternate" type="text/html" href="http://www.codelogy.org/archives/2008/01/opencv.html" />
   <id>tag:www.codelogy.org,2008://28.10168</id>
   
   <published>2008-01-17T13:45:08Z</published>
   <updated>2008-01-22T00:45:26Z</updated>
   
   <summary>   最近、画像処理についての会話をよく聞くので少し自分でもやってみました。  ...</summary>
   <author>
      <name></name>
      
   </author>
   
   
   <content type="html" xml:lang="ja" xml:base="http://www.codelogy.org/">
      <![CDATA[<p>
  最近、画像処理についての会話をよく聞くので少し自分でもやってみました。<br />
  今回使用したライブラリはIntel社のOpenCVというライブラリです。<br />
  <br />
  ダウンロードは以下のリンクより行えます。<br />
  <a href="http://sourceforge.net/projects/opencvlibrary/">http://sourceforge.net/projects/opencvlibrary/</a><br /><br />
  <br />
  このライブラリを使用することによって画像やWebカメラから入力した人間の顔や目の位置などが、わずか２０数行のコードで書くことができます。<br />
  今回はこれを使って背景画像を動的に更新し、そこに入ってきたオブジェクトを認識してみます。<br />
</p>
]]>
      <![CDATA[<h3 class ="section">1.処理の流れ</h3>
<div class="section">
  <ul style="list-style-type: decimal;">
  <li>Webカメラデバイスハンドラを作成し画像をキャプチャ</li>
  <li>画像をopenCVで取り扱う画像形式からからRGBに変換し、色の極端に変化したところのしきい値により背景と前景を区別する</li>
  <li>前景と判定されたピクセルのみを、出力画像にコピー</li>
  </ul>
  <p>
    背景画像の更新はキャプチャされた画像を重みつき差分で前回画像と合成し、それを比較することで背景とし、それとは異なる値を前景として出力します。
    処理の流れはこのような感じですが、あまり注意すべきこともないですので、コーディングしてみます。<br />
</p>
</div>

<h3 class ="section">2.ソースコード</h3>
<div class="section">
  <table class="code">
  <tr>
    <td><pre>
<em class="cmt">//main.cpp</em>
<em class="kwd">#include</em> <em class="str">&lt;stdio.h&gt;</em>
<em class="kwd">#include</em> <em class="str">&lt;cv.h&gt;</em>
<em class="kwd">#include</em> <em class="str">&lt;highgui.h&gt;</em>
<em class="kwd">#include</em> <em class="str">&lt;tchar.h&gt;</em>
<em class="kwd">#pragma comment</em>(<em class="kwd">lib</em>, <em class="str">"cv.lib"</em>)
<em class="kwd">#pragma comment</em>(<em class="kwd">lib</em>, <em class="str">"cvaux.lib"</em>)
<em class="kwd">#pragma comment</em>(<em class="kwd">lib</em>, <em class="str">"cvcam.lib"</em>)
<em class="kwd">#pragma comment</em>(<em class="kwd">lib</em>, <em class="str">"cvhaartraining.lib"</em>)
<em class="kwd">#pragma comment</em>(<em class="kwd">lib</em>, <em class="str">"highgui.lib"</em>)

<em class="kwd">#define</em> ALPHA    <em class="lit">0.1</em> <em class="cmt">// 背景合成の重み</em>
<em class="kwd">#define</em> RGB_DIFF <em class="lit">30</em>  <em class="cmt">// RGBの合計の差がこれ以下で前景判定</em>

<em class="kwd">int</em> main(<em class="kwd">int</em> argc, <em class="kwd">char</em> *argv[])
{
    IplImage *frame, *new_image, *bg_image, *fg_image, *mask_image;
    CvCapture *captureDev;

    <em class="cmt">// デバイスハンドラの作成</em>
    <em class="kwd">if</em>(!(captureDev = cvCaptureFromCAM(<em class="lit">0</em>))){
        MessageBox(<em class="str">NULL</em>, _T(<em class="str">"デバイスハンドラの作成に失敗しました。"</em>), _T(<em class="str">"エラー"</em>), MB_ICONEXCLAMATION);
        <em class="kwd">return</em> (-<em class="lit">1</em>);
    }

    <em class="cmt">// 初期化 </em>
    <em class="cmt">// 画面サイズを得るために一度キャプチャします</em>
    <em class="kwd">if</em>(!(frame = cvQueryFrame(captureDev))){
        MessageBox(<em class="">NULL</em>, _T(<em class="str">"画面サイズの取得に失敗しました。"</em>), _T(<em class="str">"エラー"</em>), MB_ICONEXCLAMATION);
        <em class="kwd">return</em>(-<em class="lit">2</em>);
    }

    cvNamedWindow(<em class="str">"input"</em>, CV_WINDOW_AUTOSIZE);
    cvNamedWindow(<em class="str">"output"</em>, CV_WINDOW_AUTOSIZE);

    <em class="kwd">const int</em> width = frame-&gt;width;
    <em class="kwd">const int</em> height = frame-&gt;height;
	
    <em class="cmt">// カメラからのキャプチャ画像をRGB変換した画像</em>
    new_image = cvCreateImage( cvSize( width, height), IPL_DEPTH_8U, <em class="lit">3</em>);
    <em class="cmt">// マスク画像</em>
    mask_image = cvCreateImage( cvSize( width, height), IPL_DEPTH_8U, <em class="lit">1</em>);
    <em class="cmt">// 前景画像</em>
    fg_image = cvCreateImage( cvSize( width, height), IPL_DEPTH_8U, <em class="lit">3</em>); 
    <em class="cmt">// 背景画像</em>
    bg_image = cvCreateImage( cvSize( width, height), IPL_DEPTH_32F, <em class="lit">3</em>);

    <em class="cmt">// メインループ</em>
    <em class="kwd">while</em>( cvWaitKey(<em class="lit">1</em>) != <em class="str">'q'</em> ){
        <em class="cmt">// キャプチャ</em>
        <em class="kwd">if</em>( !(frame = cvQueryFrame(captureDev)) )
        {
            MessageBox(<em class="usr">NULL</em>, _T(<em class="str">"キャプチャに失敗しました。"</em>), _T(<em class="str">"エラー"</em>), MB_ICONEXCLAMATION);
            <em class="kwd">goto</em> FINALIZE;
        }

        <em class="cmt">// frameの内容をRGB変換</em>
        cvCvtColor(frame, new_image, CV_HSV2RGB);
        <em class="cmt">// マスク画像作成</em>
        <em class="kwd">for</em> (<em class="kwd">int</em> i = <em class="lit">0</em>; i &lt; width * height; i++){

            <em class="kwd">unsigned</em> <em class="kwd">char</em> *uc_new_ptr = (<em class="kwd">unsigned char</em>*)&amp;new_image-&gt;imageData[i * <em class="lit">3</em>]; <em class="cmt">// カメラ画像のRGB画素ポインタ</em>
            <em class="kwd">unsigned</em> <em class="kwd">char</em> new_b = uc_new_ptr[<em class="lit">0</em>];
            <em class="kwd">unsigned</em> <em class="kwd">char</em> new_g = uc_new_ptr[<em class="lit">1</em>];
            <em class="kwd">unsigned</em> <em class="kwd">char</em> new_r = uc_new_ptr[<em class="lit">2</em>];

            <em class="kwd">float</em> *f_bg_ptr = (<em class="kwd">float</em>*)&amp;bg_image-&gt;imageData[(i * <em class="lit">3</em>) * <em class="kwd">sizeof</em>(<em class="kwd">float</em>)]; <em class="cmt">// 背景画像のRGB画素ポインタ</em>
            <em class="kwd">int</em> bg_b = (<em class="kwd">int</em>)f_bg_ptr[<em class="lit">0</em>];
            <em class="kwd">int</em> bg_g = (<em class="kwd">int</em>)f_bg_ptr[<em class="lit">1</em>];
            <em class="kwd">int</em> bg_r = (<em class="kwd">int</em>)f_bg_ptr[<em class="lit">2</em>];

            <em class="cmt">// 背景とカメラ画像の色の「距離」を計算</em>
            <em class="kwd">int</em> diff = abs((<em class="kwd">int</em>)new_b - bg_b) 
                + abs( (int)new_g - bg_g)
                + abs( (int)new_r - bg_r);

            <em class="kwd">if</em>(diff &gt; RGB_DIFF)
                Mask_image-&gt;imageData[i] = <em class="lit">1</em>; <em class="cmt">// 前景</em>
            <em class="kwd">else</em>
                mask_image-&gt;imageData[i] = <em class="lit">0</em>; <em class="cmt">// 背景</em>
        }

        <em class="cmt">// 背景差分で背景を更新する</em>
        cvRunningAvg( new_image, bg_image, ALPHA);

        <em class="cmt">// 前景画像（のコピー先）を黒くする</em>
        memset( fg_image->imageData, <em class="lit">0</em>, width * height * <em class="lit">3</em>);
        <em class="cmt">// 背景部分以外を前景画像にコピーする</em>
        cvCopy( new_image, fg_image, mask_image); 

        <em class="cmt">// ウィンドウ表示</em>
        <em class="cmt">// Webカメラからキャプチャした画像</em>
        cvShowImage(<em class="str">"input"</em>, frame);
        cvShowImage(<em class="str">"output"</em>, fg_image);
    }

FINALIZE:
    <em class="cmt">// 終了処理</em>
    cvDestroyWindow(<em class="str">"input"</em>);
    cvDestroyWindow(<em class="str">"output"</em>);
    cvReleaseImage( &amp;new_image);
    cvReleaseImage( &amp;fg_image);
    cvReleaseImage( &amp;bg_image);
    cvReleaseImage( &amp;mask_image);
    cvReleaseCapture(&amp;captureDev);

    <em class="kwd">return</em>(<em class="lit">0</em>);
}</pre></td>
    </tr>
  </table>
</div>

<h3 class ="section">3.実行結果</h3>
<div class="section">
  <p>
こちらが実行結果です。inputがキャプチャ画像、outputが背景と判断された部分を黒く表示しています。<br />
<img alt="image01.JPG" src="http://www.codelogy.org/image01.JPG" width="666" height="279" /><br /><br />
手をキャプチャしてみました。前景と判断された部分が判定されています。<br />
<img alt="image02.JPG" src="http://www.codelogy.org/image02.JPG" width="664" height="280" /><br /><br />
これらのように動的に背景画像を更新して、手のオブジェクトだけを抽出することができました。
機会がありましたら、次は手のモーションが何を行っているかなどの判定も行ってみようかと思います。
</p>
</div>
]]>
   </content>
</entry>

</feed>
