<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>NPO法人 natural science</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/" />
    <link rel="self" type="application/atom+xml" href="http://www.natural-science.or.jp/atom.xml" />
    <id>tag:www.natural-science.or.jp,2008-09-17://12</id>
    <updated>2012-05-16T00:01:38Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.261</generator>

<entry>
    <title>学都「仙台・宮城」サイエンス・デイ2012ホームページをリニューアルしました！</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120514115708.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13077</id>

    <published>2012-05-14T02:57:08Z</published>
    <updated>2012-05-16T00:01:38Z</updated>

    <summary> これまでの2007年から2012年までのデータを整理しました。見た目は変わりま...</summary>
    <author>
        <name>遠藤 理平</name>
        <uri>http://www.natural-science.or.jp/members/endo_rihei.php</uri>
    </author>
    
        <category term="学都「仙台／宮城」サイエンス・デイ2012" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="サイエンスデイ" label="サイエンスデイ" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<p>
これまでの2007年から2012年までのデータを整理しました。見た目は変わりませんが、jQuery を利用することでページ遷移が少ない構成にすることで、
ユーザビリティの向上を意図しました。
</p>

<p style="text-align:center">
<a href="http://www.science-day.com/"><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="20120514-1.gif" src="http://www.natural-science.or.jp/images/20120514-1.gif" width="600" height="600" class="mt-image-none" style="" /></span></a>
</p>


<h2>サイトマップ</h2>
<style type="text/css">
ul#sm {
	margin: 0px 0px 0px 10px;
}
ul#sm li{
	list-style-type: disc;
}
ul#sm ul.sub{
	margin: 0px 0px 0px 20px;
}
ul#sm ul.sub  li{
	list-style-type: circle;
}

ul#sm ul.sub  li li{
	list-style-type: square;
}

</style>

<ul id="sm" class="main">
<li><a href="http://www.science-day.com/about.php" class="toha">サイエンスデイとは？</a>
<ul class="sub">
<li><a href="http://www.science-day.com/about.php">開催趣旨</a>
</li>
<li><a href="http://www.science-day.com/concept.php">コンセプト</a>
</li>
<li><a href="http://www.science-day.com/gaiyou.php">開催概要</a>
</li>
<li><a href="http://www.science-day.com/message.php">応援メッセージ</a>
</li>
<li><a href="#">これまでの開催報告</a>
<ul class="sub">
<li><a href="http://www.science-day.com/result/2011.php">2011年</a>
</li>
<li><a href="http://www.science-day.com/result/2010.php">2010年</a>
</li>
<li><a href="http://www.science-day.com/result/2009.php">2009年</a>
</li>
<li><a href="http://www.science-day.com/result/2008.php">2008年</a>
</li>
<li><a href="http://www.science-day.com/result/2007.php">2007年</a>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="http://www.science-day.com/award.php" class="award">サイエンスデイAWARD</a>
<ul class="sub">
<li><a href="http://www.science-day.com/award.php">AWARD とは？</a></li>
<li><a href="http://www.science-day.com/award/process.php">審査・表彰のプロセス</a>
</li>
<li><a href="http://www.science-day.com/award/list.php">創設されたAWARD</a>
</li>
<li><a href="http://www.science-day.com/award/winner.php">これまでの受賞者</a>
</li>
<li><a href="http://www.science-day.com/award/houkoku.php">表彰式・交流パーティー</a>
</li>
</ul>
</li>
<li><a href="http://www.science-day.com/exhibit-list.php" class="boos">出展プログラム一覧</a>
</li>
<li><a href="http://www.science-day.com/annai.php" class="annai">出展案内・出展申込</a></li>
<li><a href="http://www.science-day.com/access.php" class="access">会場アクセス</a></li>
</ul>
]]>
        
    </content>
</entry>

<entry>
    <title>やってみようさんの集中講座（小学校4～6年生・中学生対象） ライントレースカーを作ってみよう！</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120501180836.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13075</id>

    <published>2012-05-01T09:08:36Z</published>
    <updated>2012-05-01T09:23:46Z</updated>

    <summary> 人間が床の線に沿って進むためには、足元の線を見ながら歩く必要があります。では、...</summary>
    <author>
        <name>八重樫 和之</name>
        
    </author>
    
        <category term="入門編" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="トランジスタ" label="トランジスタ" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="やってみようさん" label="やってみようさん" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<img src="http://www.natural-science.or.jp/images/20120501-5.gif" alt="ライントレースカーを作ってみよう！" />

<p style="font-size:medium;font-weight:600">
人間が床の線に沿って進むためには、足元の線を見ながら歩く必要があります。では、ロボットを線に沿って進ませるためには、どのような回路が必要でしょうか。本講座では、必要最小限の部品を用いて、床に引かれた線に沿って進むライントレースカーを制作します。本講座を通して、ライントレースカーが線の上を走る仕組みを理解し、そこに使われるトランジスタやセンサの仕組みを学ぶことを目的とします。
</p>
<p>
<img alt="20120501-4.gif" src="http://www.natural-science.or.jp/images/20120501-6.gif"  />
</p>


<h2>募集概要</h2>
<table>
<tr>
<td nowrap="nowrap" >開講日：<br />（２時間×４回）</td>
<td>
２０１２年５月２５日～６月１５日<br />
毎週金曜日　１９：００～２１：００<br />
<span style="font-weight:600">※連続してこれない場合には、平日夜に補講を行います</span>
</td>
</tr>
<tr>
<td nowrap="nowrap" >
場所：</td><td>FiveBridge（仙台市青葉区北目町４－７HSGビル３階）<a href="http://maps.google.co.jp/maps?q=%E5%AE%AE%E5%9F%8E%E7%9C%8C%E4%BB%99%E5%8F%B0%E5%B8%82%E9%9D%92%E8%91%89%E5%8C%BA%E5%8C%97%E7%9B%AE%E7%94%BA%EF%BC%94%EF%BC%8D%EF%BC%97+HSG%E3%83%93%E3%83%AB3%E9%9A%8E&ie=UTF8&ll=38.254548,140.875915&spn=0.002751,0.006035&z=18" target="_blank">地図</a></td>
</tr>
<tr>
<td nowrap="nowrap" >費用：</td><td>
8,000円（2時間×4回・部品代、テキスト代、保険代込み）<br />
<span style="font-size:x-small">※はんだごてセット（はんだごて、はんだ、はんだ吸収線、こて先クリーナー）をお持ちでない方は、別途購入（2,000円）が必要となります。</span>
</td>
</tr>
<tr>
<td nowrap="nowrap" >対象：</td><td>電子工作経験のある小学校4～6年生・中学生</td>
</tr>
<tr>
<td nowrap="nowrap" >
主催：</td><td>NPO法人 natural science</td>
</tr>
<tr>
<td nowrap="nowrap" >
後援：</td><td>仙台市教育委員会</td>
</tr>
<tr>
<td nowrap="nowrap" >お問い合せ：</td><td>022-721-2035</td>
</tr>
</table>

<h2>申し込み</h2>
<table>
<tr>
<td><span style="font-weight:600;color:#237D26">小学校4～6年生・中学生対象</span><br />
ライントレースカーを作ってみよう！
</td>
<td>開講日（全４回）２０１２年５月２５日～６月１５日<br />
毎週金曜日　１９：００～２１：００<br />
</td>
<td>
	<?php
	$kouzamei = "ライントレースカーを作ってみよう！";
	$nokori = "定員１０名";
	?>
<form action="http://www.natural-science.or.jp/colledge/index.php#contents" method="post">
<input type='hidden' name='kouzamei' value='<?php print $kouzamei ?>' />
<?php
if($nokori) print "<input value=\"$nokori\" style=\"width: 70px;\" type=\"submit\" />";
else print "<input value=\"申込む\" style=\"width: 50px;\" type=\"submit\" />";
?>
<input name="flag" value="mousikomi1" type="hidden">
</form>

</td>
</tr>
</table>
<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="tanki11.gif" src="http://www.natural-science.or.jp/images/tanki11.gif" width="171" height="171" class="mt-image-none" style="" /></span>
-->]]>
        
    </content>
</entry>

<entry>
    <title>やってみようさんの集中講座（小学生高学年対象） 7セグメントLEDで好きな数字を表示させよう！（小学生高学年対象）</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120501172255.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13074</id>

    <published>2012-05-01T08:22:55Z</published>
    <updated>2012-05-11T00:51:36Z</updated>

    <summary> ７セグメントLEDはデジタル時計をはじめ、私たちの身の回りの様々な場面で使われ...</summary>
    <author>
        <name>八重樫 和之</name>
        
    </author>
    
        <category term="入門編" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="led" label="LED" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="やってみようさん" label="やってみようさん" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="集中講座" label="集中講座" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<img src="http://www.natural-science.or.jp/images/20120501-3.gif" alt="7セグメントLEDで好きな数字を表示させよう！" />

<p style="font-size:medium;font-weight:600">
７セグメントLEDはデジタル時計をはじめ、私たちの身の回りの様々な場面で使われています。日常せ活でよく目にする７セグメントLEDですが、中の仕組みはどうなっているのでしょうか。本講座は、７セグメントLEDとスイッチを用いて好きな数字を表示させる回路を制作します。７セグメントLEDで数字を表示させるには、回路図を書いて考える必要があります。本講座を通して、回路図の役割を理解することを目的とします。
</p>
<p>
<img alt="20120501-4.gif" src="http://www.natural-science.or.jp/images/20120501-4.gif"  />
</p>


<h2>募集概要</h2>
<table>
<tr>
<td nowrap="nowrap" >開講日：<br />（２時間×４回）</td>
<td>
２０１２年５月２３日～６月１３日<br />
毎週水曜日　１９：００～２１：００<br />
<span style="font-weight:600">※連続してこれない場合には、平日夜に補講を行います</span>
</td>
</tr>
<tr>
<td nowrap="nowrap" >
場所：</td><td>FiveBridge（仙台市青葉区北目町４－７HSGビル３階）<a href="http://maps.google.co.jp/maps?q=%E5%AE%AE%E5%9F%8E%E7%9C%8C%E4%BB%99%E5%8F%B0%E5%B8%82%E9%9D%92%E8%91%89%E5%8C%BA%E5%8C%97%E7%9B%AE%E7%94%BA%EF%BC%94%EF%BC%8D%EF%BC%97+HSG%E3%83%93%E3%83%AB3%E9%9A%8E&ie=UTF8&ll=38.254548,140.875915&spn=0.002751,0.006035&z=18" target="_blank">地図</a></td>
</tr>
<tr>
<td nowrap="nowrap" >費用：</td><td>
8,000円（2時間×4回・部品代、テキスト代、保険代込み）<br />
<span style="font-size:x-small">※はんだごてセット（はんだごて、はんだ、はんだ吸収線、こて先クリーナー）をお持ちでない方は、別途購入（2,000円）が必要となります。</span>
</td>
</tr>
<tr>
<td nowrap="nowrap" >対象：</td><td>電子工作未経験の小学校4～6年生</td>
</tr>
<tr>
<td nowrap="nowrap" >
主催：</td><td>NPO法人 natural science</td>
</tr>
<tr>
<td nowrap="nowrap" >
後援：</td><td>仙台市教育委員会</td>
</tr>
<tr>
<td nowrap="nowrap" >お問い合せ：</td><td>022-721-2035</td>
</tr>
</table>



<h2>申し込み</h2>
<table>
<tr>
<td><span style="font-weight:600;color:#237D26">小学生高学年対象</span><br />
7セグメントLEDで好きな数字を表示させよう！
</td>
<td>開講日（全４回）２０１２年５月２３日～６月１３日<br />
毎週水曜日　１９：００～２１：００<br />
</td>
<td>
	<?php
	$kouzamei = "7セグメントLEDで好きな数字を表示させよう！";
	$nokori = "定員１０名";
	?>
<form action="http://www.natural-science.or.jp/colledge/index.php#contents" method="post">
<input type='hidden' name='kouzamei' value='<?php print $kouzamei ?>' />
<?php
if($nokori) print "<input value=\"$nokori\" style=\"width: 70px;\" type=\"submit\" />";
else print "<input value=\"申込む\" style=\"width: 50px;\" type=\"submit\" />";
?>
<input name="flag" value="mousikomi1" type="hidden">
</form>

</td>
</tr>
</table>
<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="tanki10.gif" src="http://www.natural-science.or.jp/images/tanki10.gif" width="171" height="171" class="mt-image-none" style="" /></span>
-->]]>
        
    </content>
</entry>

<entry>
    <title>やってみようさんの集中講座（小学生低学年対象） LEDで絵や文字をつくってみよう！</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120501171507.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13073</id>

    <published>2012-05-01T08:15:07Z</published>
    <updated>2012-05-11T00:52:01Z</updated>

    <summary> LEDは信号や電光掲示板、電球をはじめ、私たちの身の回りの様々な場面で使われて...</summary>
    <author>
        <name>八重樫 和之</name>
        
    </author>
    
        <category term="入門編" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="led" label="LED" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="やってみようさん" label="やってみようさん" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="集中講座" label="集中講座" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<img src="http://www.natural-science.or.jp/images/20120501-1.gif" alt="やってみようさんの「集中講座」 LEDで絵や文字をつくってみよう！" />

<p style="font-size:medium;font-weight:600">
LEDは信号や電光掲示板、電球をはじめ、私たちの身の回りの様々な場面で使われています。LEDは身近にある電子部品ですが、その仕組みを知る機会は多くはありません。LEDを光らせるにはどうすればいいでしょうか。本講座は、複数のLEDを基板上に配線することで絵や文字を表示させる回路を制作します。本講座を通して、電気回路の仕組みを理解することを目的とします。
</p>
<p>
<img alt="20120501-2.gif" src="http://www.natural-science.or.jp/images/20120501-2.gif"  />
</p>

<h2>募集概要</h2>
<table>
<tr>
<td nowrap="nowrap" >開講日：<br />（２時間×４回）</td>
<td>
２０１２年５月２２日～６月１２日<br />
毎週火曜日　１７：００～１９：００<br />
<span style="font-weight:600">※連続してこれない場合には、平日夜に補講を行います</span>
</td>
</tr>
<tr>
<td nowrap="nowrap" >
場所：</td><td>FiveBridge（仙台市青葉区北目町４－７HSGビル３階）<a href="http://maps.google.co.jp/maps?q=%E5%AE%AE%E5%9F%8E%E7%9C%8C%E4%BB%99%E5%8F%B0%E5%B8%82%E9%9D%92%E8%91%89%E5%8C%BA%E5%8C%97%E7%9B%AE%E7%94%BA%EF%BC%94%EF%BC%8D%EF%BC%97+HSG%E3%83%93%E3%83%AB3%E9%9A%8E&ie=UTF8&ll=38.254548,140.875915&spn=0.002751,0.006035&z=18" target="_blank">地図</a></td>
</tr>
<tr>
<td nowrap="nowrap" >費用：</td><td>
8,000円（2時間×4回・部品代、テキスト代、保険代込み）<br />
<span style="font-size:x-small">※はんだごてセット（はんだごて、はんだ、はんだ吸収線、こて先クリーナー）をお持ちでない方は、別途購入（2,000円）が必要となります。</span>
</td>
</tr>
<tr>
<td nowrap="nowrap" >対象：</td><td>電子工作未経験の小学校1～3年生</td>
</tr>
<tr>
<td nowrap="nowrap" >
主催：</td><td>NPO法人 natural science</td>
</tr>
<tr>
<td nowrap="nowrap" >
後援：</td><td>仙台市教育委員会</td>
</tr>
<tr>
<td nowrap="nowrap" >お問い合せ：</td><td>022-721-2035</td>
</tr>
</table>



<h2>申し込み</h2>
<table>
<tr>
<td><span style="font-weight:600;color:#237D26">小学生低学年対象</span><br />
LEDで絵や文字をつくってみよう！
</td>
<td>開講日（全４回）２０１２年５月２２日～６月１２日<br />
毎週火曜日　１７：００～１９：００<br />
</td>
<td>
	<?php
	$kouzamei = "LEDで絵や文字をつくってみよう！";
	$nokori = "定員１０名";
	?>
<form action="http://www.natural-science.or.jp/colledge/index.php#contents" method="post">
<input type='hidden' name='kouzamei' value='<?php print $kouzamei ?>' />
<?php
if($nokori) print "<input value=\"$nokori\" style=\"width: 70px;\" type=\"submit\" />";
else print "<input value=\"申込む\" style=\"width: 50px;\" type=\"submit\" />";
?>
<input name="flag" value="mousikomi1" type="hidden">
</form>

</td>
</tr>
</table>

<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="tanki9.gif" src="http://www.natural-science.or.jp/images/tanki9.gif" width="171" height="171" class="mt-image-none" style="" /></span>
-->]]>
        
    </content>
</entry>

<entry>
    <title>gnuplot の進化？ gnuplot の HTML5 (canvas 要素)化について</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120424164920.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13071</id>

    <published>2012-04-24T07:49:20Z</published>
    <updated>2012-04-24T07:52:43Z</updated>

    <summary> 昨今の HTML5 ブームは、グラフ描画ソフトの雄である「gnuplot」にも...</summary>
    <author>
        <name>遠藤 理平</name>
        <uri>http://www.natural-science.or.jp/members/endo_rihei.php</uri>
    </author>
    
        <category term="TIPS 集" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="canvas" label="canvas" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="gnuplot" label="gnuplot" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="html5" label="HTML5" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<p>
昨今の HTML5 ブームは、グラフ描画ソフトの雄である「<a href="http://www.gnuplot.info/" target="_blank">gnuplot</a>」にも飛び火しています。
HTML5 とはウェブページ作成用の言語である HTML の最新規格のことですが、単に「ウェブページ」の世界に留まらない魅力にあふれる規格として注目を集めています。
これまでPCの世界では、OS（オペレーションシステム）の選択から始まり、その OS 上で動作するアプリケーションを導入するというスキームでした。
しかしながら、スマートフォンやタブレット型PCなどの様々な情報端末が普及するにつれ、各々の環境で動作するアプリケーションを用意する必要に迫られるわけですが、
もし種々の環境で同一動作を保証する<strong>クロスプラットフォーム</strong>を実現されるならば、こんな便利なことはありません。
HTML5 の真価は「ウェブページ」にとどまらず、「ネイティブアプリケーション」のクロスプラットフォームとしての可能性を有している点にあるのです。

</p>
<p>
gnuplot もその時代の流れに乗るべく動き出したようです。
gnuplot はもともと、EPS, JPG, GIF, PNG といった静的な画象を出力することができますが、
gnuplot Ver. 4.4 から HTML5 で導入された新要素である「canvas 要素」で描画するための Javascript を出力することができるようになりました。
これにより、gnuplot を起動することなしに、ウェブブラウザだけで gnuplot のグラフを動的かつインタラクティブに扱うことがでます。
</p>


<h2>gnuplot の canvas 要素への出力結果</h2>
<p>
下の図は GIF や JPG などの静的画象ではなく、canvas 要素に動的に描画した図です。
gniplot を使っている方はわかると思いますが、見た目は gnuplot そのものです。
canvas 要素ないで、マウスの左ボタンでドラックすることで、拡大することができます。
</p>
<div style="text-align:center">
<iframe src="http://www.natural-science.or.jp/WebGL/gnuplot_canvas.html" style="width:630px; height:450px; border: 0px; overflow:hidden;" scrolling="no"></iframe>
</div>
<p>
①や②を押すことで、描画済みのグラフの表示・非表示を切り替えることができます。
</p>

<h3>しかしながら・・・</h3>
<p>
gnuplot を使ったことがある方はわかると思いますが、
これは<span style="font-weight:600; color:red">非常に使いにくい</span>です。
通常の gnuplot の３次元描画結果では、マウスで視点をグリグリと動かせることができますのに対して、上記のサンプルは「拡大」しかできません。
「グリグリ」が実装されていない以上、図を張るのと大差がありません。
canvas 要素は３次元描画することも可能なので、ぜひとも「グリグリ」を実装してもらいたいですね。
</p>

<h3>gnuplot テンプレート</h3>
<p>
上のサンプルは、本家の<a href="http://gnuplot.sourceforge.net/demo_canvas_4.6/hidden2.html" target="_blank">gnuplot demo script: hidden2.dem</a>の一つです。
任意の名前のファイルを作成して下記のコードをコピー＆ペーストして、gnuplot で「load」することで作成することができます。
</p>
<pre>
set terminal canvas  solid butt size 600,400 fsize 10 lw 1 fontscale 1 name "hidden2_1" jsdir "."
set output 'hidden2.1.js'
set style fill   solid 0.50 border
unset key
set isosamples 25, 25
set hidden3d front offset 1 trianglepattern 3 undefined 1 altdiagonal bentover
set xyplane at 0
#set title "Mixing pm3d surfaces with hidden-line plots" 
set cbrange [ -1.00000 : 1.00000 ] noreverse nowriteback
set palette rgbformulae 31, -11, 32
f(x,y) = sin(-sqrt((x+5)**2+(y-7)**2)*0.5)
GPFUN_f = "f(x,y) = sin(-sqrt((x+5)**2+(y-7)**2)*0.5)"
splot f(x,y) with pm3d, x*x-y*y with lines lt 1 lc rgb "#000000",       f(x,y) with lines lt -2 notitle
</pre>
<br />

<h2>競合技術：google WebGL ３次元グラフビューア（名前は勝手につけました）</h2>
<p>
2012年3月に google が WebGL を利用したアプリケーションが注目を集めています。
google の検索窓に「<a href="https://www.google.co.jp/search?rlz=1C1MKJF_jaJP447JP447&aq=f&sourceid=chrome&ie=UTF-8&q=z%3Dx%5E2%2By%5E2" target="_blank">z=x^2+y^2</a>」などと入力すると、3次元グラフを描画することができ、マウスグラックを利用して視点自在に移動することができます。
下図はその3次元グラフのキャプチャです。
</p>
<p style="text-align:center">
<a href="https://www.google.co.jp/search?rlz=1C1MKJF_jaJP447JP447&aq=f&sourceid=chrome&ie=UTF-8&q=z%3Dx%5E2%2By%5E2" target="_blank">
<img src="http://www.natural-science.or.jp/images/20120412-1.gif" alt="" />
</a>
</p>
<p>
WebGL とは、canvas 要素を利用したAPIの一つで、GPU を利用したレンダリングをウェブブラウザで実行するためのライブラリです（詳細は「<a href="http://www.natural-science.or.jp/article/20120220155529.php">HTML5による物理シミュレーション環境の構築 ～WebGLライブラリThree.js 入門（１／３）～</a>」をご覧ください）。
google WebGL ３次元グラフビューアは今のところ、google の検索窓に打ち込んたコードを検索結果に描画するだけなので、任意のページに取り込むことはできませんが、
今後の発展次第では gnuplot を超えることも考えられますね。
</p>


<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="20120424.gif" src="http://www.natural-science.or.jp/images/20120424.gif" width="554" height="275" class="mt-image-none" style="" /></span>
-->
]]>
        
    </content>
</entry>

<entry>
    <title>クォータニオンによる視点の移動 （WebGL（Three.js））</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120416225426.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13070</id>

    <published>2012-04-16T13:54:26Z</published>
    <updated>2012-04-16T13:56:05Z</updated>

    <summary> ３次元空間中の物体を任意の軸に対して、任意の角度回転させることを考えます。 こ...</summary>
    <author>
        <name>遠藤 理平</name>
        <uri>http://www.natural-science.or.jp/members/endo_rihei.php</uri>
    </author>
    
        <category term="WebGL" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="仮想物理実験室" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="threejs" label="Three.js" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="webgl" label="WebGL" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="クォータニオン" label="クォータニオン" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="マウスイベント" label="マウスイベント" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<p>
３次元空間中の物体を任意の軸に対して、任意の角度回転させることを考えます。
これは、コンピュータグラフィックなどの世界で、マウス操作などの入力装置を利用して３次元の物体の向きを変更させたいときに必須となります。
一般的に「回転」といえば「<em>オイラー角</em>」を思い浮かべるわけですが、任意の軸に対する回転は不得意であることが知られています。
それは、任意の軸に対する回転に対応する３つのオイラー角が直感的には定式化できないためです。
また、場合によってはジンバルロックと呼ばれるオイラー角を利用時に特定の条件で発生する特有の問題もあります。
そこで、コンピュータグラフィックなどで、任意の軸に対する回転を演算する際に、「<strong>クォータニオン（四元数）</strong>」と呼ばれる複素数の拡張版のような代数が利用されます。
本稿では、3次元グラフィック技術である WebGL（Three.js）にて視点をマウスで自由自在に移動することを目的に、
クォータニオンを Javascript で演算することを行います。
</p>
<br />

<h2>任意の軸に対する回転</h2>
<p>
次の図のような、座標<?php WriteEquation("\mathbf{R}") ?>にある物体を、回転軸ベクトル<?php WriteEquation("\mathbf{v}") ?>に対して角度<?php WriteEquation("\theta") ?>回転させた後の座標を<?php WriteEquation("\mathbf{R'}") ?>となる場合を考えます。
</p>
<p style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120412-2.gif" alt="" />
</p>
<p>
この回転は、回転軸ベクトル（３自由度）と回転角（１自由度）の４つのパラメータで指定することができます。
クォータニオンを利用すると、<?php WriteEquation("\mathbf{R'}") ?>は<?php WriteEquation("\mathbf{R}") ?>に対して２回の演算で計算することができます。
具体的な演算方法は「<a href="http://www015.upp.so-net.ne.jp/notgeld/quaternion.html" target="_blank">７０秒で分る、使える、四元数・４元数・クォータニオン・ Quaternionで回転 （中田亨氏）</a>」をご覧ください。ウェブページのタイトル通り確かに70秒で計算できました。
</p>

<br />
<h2>Javascriptによるクォータニオンを利用した回転の演算</h2>
<p>
クォータニオンはコンピュータグラフィックで非常によく利用されるため、クォータニオン演算のためのライブラリも存在します。
今回は、WebGL を使用する時に必要となる行列計算を、簡単に演算することのできる「<a href="http://code.google.com/p/glmatrix/" target="_blank">glMatrix.js</a>」を利用します。この中でクォータニオンの演算も定義されています。
</p>

<h3>glMatrix.jsでクォータニオンの演算</h3>
<p>
glMatrix.js でクォータニオンは
</p>
<pre class="brush: js;">
var P = new quat4.create([x,y,z,w]);
</pre>
<p>
で定義することができます。x,y,z は、クォータニオンの i,j,k の係数を表し、w がクォータニオンの実数部を表します。
2つのクォータニオンの積は
</p>
<pre class="brush: js;">
var P = new quat4.create([x1,y1,z1,w1]);
var Q = new quat4.create([x2,y2,z2,w2]);
var R = quat4.multiply(P,Q, quat4.create());
</pre>
<p>
で計算することできます。
</p>

<h3>クォータニオンを利用した回転の計算</h3>
<p>
座標ベクトル v = [vx, vy, vz] を
任意の回転軸 u = [ux, uy, uz]に対して、角度 theta 回転させた後の座標ベクトルを計算する関数を定義します。
</p>
<pre class="brush: js;">
function QuaternionRotation(theta, u, v){ //(回転角, 回転軸, 座標ベクトル)
  var P = new quat4.create([v[0],v[1],v[2],0]);
  var Q = new quat4.create([-u[0]*Math.sin(theta/2), -u[1]*Math.sin(theta/2), -u[2]*Math.sin(theta/2), Math.cos(theta/2)]);
  var R = new quat4.create([u[0]*Math.sin(theta/2), u[1]*Math.sin(theta/2), u[2]*Math.sin(theta/2), Math.cos(theta/2)]);
  var S0 = quat4.multiply(P,Q, quat4.create());
  var S =  quat4.multiply(R,S0,quat4.create());  
  var V = [S[0],S[1],S[2]];
  return V;
}
</pre>
<p>
この関数を利用することで、簡単に回転後の座標を計算することができます。
</p>
<br />

<h2>視点のマウスによる移動</h2>
<p>
2012年3月に google が WebGL を利用したアプリケーションが注目を集めています。
google の検索窓に「<a href="https://www.google.co.jp/search?rlz=1C1MKJF_jaJP447JP447&aq=f&sourceid=chrome&ie=UTF-8&q=z%3Dx%5E2%2By%5E2" target="_blank">z=x^2+y^2</a>」などと入力すると、3次元グラフを描画することができ、マウスグラックを利用して視点自在に移動することができます。
下図はその3次元グラフのキャプチャです。
</p>
<p style="text-align:center">
<a href="https://www.google.co.jp/search?rlz=1C1MKJF_jaJP447JP447&aq=f&sourceid=chrome&ie=UTF-8&q=z%3Dx%5E2%2By%5E2" target="_blank">
<img src="http://www.natural-science.or.jp/images/20120412-1.gif" alt="" />
</a>
</p>
<p>
視点の移動は、マウスクリック時のマウスポインタの座標を基準として、
視点の位置ベクトルと視点の上の向きを表すベクトルが、マウスの移動量 dx, dy に応じて変更することで実現することができます。
本稿では、上記のクォータニオンを利用して、2次元平面の canvas 上をマウスドラックすることで視点の移動させることを考えます。
</p>

<h3>視点移動の模式図</h3>
<p>
canvas 上を横方向（移動量 dx）と縦方向（移動量 dy）にマウスドラックさせることで視点を回転させることを考えます。
ただし、視点は原点（0,0,0）を向いているとします。
一般に視点の自由度は、<span style="font-weight:600">視点の位置ベクトル（3自由度）</span>と<span style="font-weight:600">視点の上の向きを表すベクトル（3自由度）</span>の計6自由度ですが、視点は原点（0,0,0）を向いていると条件を課すと、視点の上の向きを表すベクトルは位置ベクトルと垂直となり、実質的には１自由度となりますが、
演算の都合上ベクトルで表しておきます。
</p>
<p>
次に、マウスの移動量 dx, dy と具体的な視点の移動量との関係を、視点の位置ベクトルと上向きベクトルから一意に決定する軸による回転として得られると考えます。
視点の位置ベクトル（<?php WriteEquation("\mathbf{R}") ?>）と上向きベクトル（<?php WriteEquation("\mathbf{a}") ?>）に対する回転軸の模式図は次図のとおりです。
</p>
<p style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120412-3.gif" alt="" />
</p>
<p>
dx に対しては<?php WriteEquation("\mathbf{u}") ?>（緑）軸回転、dy に対しては<?php WriteEquation("\mathbf{w}") ?>（青）軸回転に対応させます。
図でも示しているとおり、<?php WriteEquation("R") ?>と<?php WriteEquation("a") ?>から上記の２軸は、
<?php WriteEquation("\mathbf{u}=\mathbf{a}") ?>、<?php WriteEquation("\mathbf{w}=\mathbf{R}\times\mathbf{u}") ?>
と簡単に計算することができます。ここまでくればあとは前節で触れたクォータニオンを利用して軸回転後の座標を計算することで、回転後の視点の位置ベクトルがわかります。
本稿では次のステップで計算します。<br />
<br />
１．クリック時の視点の位置ベクトル<?php WriteEquation("R") ?>、視点の上向きベクトル<?php WriteEquation("\mathbf{a}") ?>を取得する。<br />
２．<?php WriteEquation("R") ?>と<?php WriteEquation("\mathbf{a}") ?>から、２つの回転軸ベクトル<?php WriteEquation("\mathbf{u}") ?>,<?php WriteEquation("\mathbf{w}") ?>を計算する。<br />
３．マウス移動量 dx, dy から回転角度<?php WriteEquation("\theta_u") ?>、<?php WriteEquation("\theta_w") ?>を計算する。<br />
４．クォータニオンを利用して、<?php WriteEquation("\mathbf{u}") ?>, <?php WriteEquation("\mathbf{w}") ?>軸周りに<?php WriteEquation("\theta_u") ?>、<?php WriteEquation("\theta_w") ?>回転後の位置ベクトルを計算する。<br />
５．クォータニオンを利用して、視点の上方向ベクトルを計算する。<br />
<br />
次は、本稿で作成した視点の移動のサンプルです。
</p>

<br />
<h2>クオータニオンを用いた視点の移動テスト</h2>
<p>
HTML5 canvas 要素の WebGL（Three.jsライブラリ）を用いて、表題のテストを行います。
<span style="color:red; font-weight:600">WebGLを利用可能な環境</span>で下のフレーム内の図をドラックしてみてください。
視点を移動することができます。
</p>

<div style="text-align:center">
<iframe src="http://www.natural-science.or.jp/WebGL/quaternion_test.html" style="width:450px; height:500px; border: 0px; overflow:hidden;" scrolling="no"></iframe>
</div>
<p>
※上記のサンプルプログラムは、HTML5 のcanvas 要素を利用した WebGL を簡単に利用するためのライブラリである Three.js を利用しています。<br />

</p>

<h4>１．クリック時の視点の位置ベクトル<?php WriteEquation("R") ?>、視点の上向きベクトル<?php WriteEquation("\mathbf{a}") ?>を取得する。</h4>
<pre class="brush: js;">
R = new vec3.create([camera.position.x,camera.position.y,camera.position.z]); // 視点の位置ベクトルの取得
a = new vec3.create([camera.up.x, camera.up.y, camera.up.z]);                 // 視点の上向きベクトルの取得
</pre>
<p>
ただし、vec3 は glMatrix.js で定義されている３次元ベクトルです。
<?php WriteEquation("\mathbf{u}") ?>と<?php WriteEquation("\mathbf{w}") ?>が得られました。
</p>

<h4>２．<?php WriteEquation("R") ?>と<?php WriteEquation("\mathbf{a}") ?>から、２つの回転軸ベクトル<?php WriteEquation("\mathbf{u}") ?>,<?php WriteEquation("\mathbf{w}") ?>を計算する。</h4>
<pre class="brush: js;">
u = vec3.set(a, vec3.create());       // a のコピー
u = vec3.normalize(u, vec3.create()); // u の規格化
w = vec3.cross(R, u ,vec3.create());  // R × u の演算
w = vec3.normalize(w, vec3.create()); // w の規格化
</pre>
<p>
glMatrix.js には vec3 で定義された３次元ベクトルの演算が定義されています。<br />
上記は「vec3.set：コピー」「vec3.normalize：規格化」「vec3.cross：外積」を意味します。
この他にも、必要な演算が定義されています。
</p>

<h4>３．マウス移動量 dx, dy から回転角度<?php WriteEquation("\theta_u") ?>、<?php WriteEquation("\theta_w") ?>を計算する。</h4>
<pre class="brush: js;">
theta_u =  dx / 100;
theta_w = -dz / 100;
</pre>
<p>
これは適当に決めます。もし、マウスの移動量に対して速く回転させたければ、100 → 50 とし、逆に遅くしたければ 100 → 200 としてください。
</p>
<h4>４．クォータニオンを利用して、<?php WriteEquation("\mathbf{u}") ?>, <?php WriteEquation("\mathbf{w}") ?>軸周りに<?php WriteEquation("\theta_u") ?>、<?php WriteEquation("\theta_w") ?>回転後の位置ベクトルを計算する。<br />
</h4>
<p>
視点の位置ベクトルを、回転軸ベクトル<?php WriteEquation("\mathbf{u}") ?>で<?php WriteEquation("\theta_u") ?>回転後、
さらに<?php WriteEquation("\mathbf{w}") ?>で回転させます。
</p>
<pre class="brush: js;">
S = QuaternionRotation(theta_u, u, [camera.position.x, camera.position.y, camera.position.z]);
S = QuaternionRotation(theta_w, w, [S[0],S[1],S[2]]);
</pre>

<h4>５．クォータニオンを利用して、視点の上方向ベクトルを計算する。</h4>
<p>
４までで視点の移動は完了していますが、このままでは「google 3Dグラフ」のような操作性は実現できません。
上の模式図を見ればわかりますが、回転軸<?php WriteEquation("\mathbf{w}") ?>で視点を回転させると、視点の上ベクトルも回転することがわかります。つまり、
</p>
<pre class="brush: js;">
S = QuaternionRotation(theta_w, w, [camera.up.x,camera.up.y,camera.up.z]);
camera.up.set(S[0],S[1],S[2]);
</pre>
<p>
で視点の上ベクトルを計算することができます。
本稿では、クオータニオンを用いて視点の回転を計算しましたが、物体そのもの姿勢制御でもクオータニオンはオイラー角に比べて簡単に実装することができます。また、以上の計算は、WebGLだけでなくどのようなプログラムにも適用することができます。
今回はこんな程度で終わりにします。
</p>


<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="20120416-1.gif" src="http://www.natural-science.or.jp/images/20120416-1.gif" width="383" height="490" class="mt-image-none" style="" /></span>
-->
]]>
        
    </content>
</entry>

<entry>
    <title>N重振り子のアルゴリズムとシミュレータ</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120410185300.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13056</id>

    <published>2012-04-10T09:53:00Z</published>
    <updated>2012-04-10T12:40:56Z</updated>

    <summary> これまで，以下の振子の運動シミュレーションを行ってきました． ・ラグランジュ運...</summary>
    <author>
        <name>藤原 亮</name>
        <uri>http://www.natural-science.or.jp/</uri>
    </author>
    
        <category term="仮想物理実験室" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="計算物理学" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="html5" label="HTML5" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="threejs" label="Three.js" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="webgl" label="WebGL" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="アルゴリズム" label="アルゴリズム" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="シミュレータ" label="シミュレータ" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<p>
これまで，以下の振子の運動シミュレーションを行ってきました．<br />
・<a href="http://www.natural-science.or.jp/article/20101004215158.php">ラグランジュ運動方程式１：極座標を用いた単振子</a><br />
・<a href="http://www.natural-science.or.jp/article/20101005231427.php">ラグランジュ運動方程式２：極座標を用いた球面振子</a><br />
・<a href="http://www.natural-science.or.jp/article/20101007204340.php">ラグランジュ未定乗数法を用いた球面振子のシミュレーション</a><br />
・<a href="http://www.natural-science.or.jp/article/20101123180159.php">ラグランジュ未定乗数法を用いた２重振子のシミュレーション</a><br />
これまでのシミュレーションを見てきて，<span style="font-weight:600">おもりの数が増えたらどんな動きをするのだろうか？</span>
という疑問が湧いた人もいると思います．<br>
ここでは，<span style="font-weight:600">N重振り子の運動方程式を定式化</span>し，HTML5(canvas要素)＋WebGL(Three.jsライブラリ)を用いた，
<span style="font-weight:600">プラグインなしでお手軽に実行できるシミュレータ</span>で，その運動を再現します．
</p>

<h2>3次元空間中にある，質量のない剛体棒でつながれたN個の質点で構成された振り子の運動方程式を求めてみよう！</h2>
<p>
ここでは，シミュレーションを行うことを前提として，N重振り子の運動方程式を記述していく．
また，一般的に振り子の運動を記述するときは，剛体棒の角度<?php WriteEquation("\theta_i", 14) ?>などを使うが，
この方法は座標の数が減り解析がしやすくなる反面，
<span style="font-weight:600">質点が剛体棒から受ける拘束力</span>などといった情報がカットされているのだ．
したがって今回は，<span style="font-weight:600">質点のデカルト座標系における位置</span>と<span style="font-weight:600">質点が剛体棒から受ける拘束力</span>
で振り子の運動を記述してみようと思う．
</p>
<p>
運動方程式を求める前に，振り子を構成する要素に名前を付ける．
振り子が固定されている点を<?php WriteEquation("\mathbf{r}_0", 14) ?>，
固定点から数えて<?php WriteEquation("i", 14) ?>番目の質点の位置を<?php WriteEquation("\mathbf{r}_i", 14) ?>，
その質点の質量を<?php WriteEquation("m_i", 14) ?>とする．
また，振り子の質点の数をN，重力加速度を<?php WriteEquation("\mathbf{g}=(0 , 0 , -g)^\tran", 14) ?>とする．
<?php WriteEquation("i", 14) ?>番目の質点には，重力<?php WriteEquation("m_i \mathbf{g}", 14) ?>と，
前の質点との間に働く張力<?php WriteEquation("- \alpha_{i} (\mathbf{r}_{i} - \mathbf{r}_{i-1})", 14) ?>，
後の質点との間に働く張力<?php WriteEquation("\alpha_{i+1} (\mathbf{r}_{i+1} - \mathbf{r}_{i})", 14) ?>が作用する．
</p>
<p style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120409-1.gif" alt="" />
</p>

<br />
<h2>運動方程式と，その解き方の方針</h2>
<p>
これを運動方程式に書き表すと式(1)のとおりとなる．
</p>
<div class="waku">
<div style="float:right">(1)</div>
<img src="http://www.natural-science.or.jp/images/20120409-2.gif" alt="" />
</div>
<p>
<span style="font-weight:600">上式における，位置<?php WriteEquation("\{\mathbf{r}_i\}", 14) ?>，速度<?php WriteEquation("\{\dot{\mathbf{r}}_i\}", 14) ?>，張力に含まれる係数<?php WriteEquation("\{\alpha_i\}", 14) ?>という
7N個の変数を求めれば，振り子を再現できるのだ！！</span>
さて，求めたい変数は7N個あるのだが，式(1)は3N本しかない．
どうするのか？
</p>
<p>
まず，「一階化」というテクニックや「拘束条件」を使って式の本数を7N本とし，未知変数と式の数を一致させる．
この操作をすると，位置<?php WriteEquation("\{\mathbf{r}_i\}", 14) ?>，速度<?php WriteEquation("\{\dot{\mathbf{r}}_i\}", 14) ?>をRunge-Kutta法などの差分スキームを使って求めることができる．
ただ，<?php WriteEquation("\{ \alpha_i \}", 14) ?>が決まらなければ，位置<?php WriteEquation("\{\mathbf{r}_i\}", 14) ?>，速度<?php WriteEquation("\{\dot{\mathbf{r}}_i\}", 14) ?>は決めることができないのだ．
ということで，<span style="font-weight:600"><?php WriteEquation("\{ \alpha_i \}", 14) ?>をいかに決定するか</span>ということが，<span style="font-weight:600">ここでのヤマ場となる</span>．
結論からいうと，<?php WriteEquation("\{ \alpha_i \}", 14) ?>に関する連立方程式を立式するのだが，
いろいろな<span style="font-weight:600">ベクトル演算</span>のテクニックを存分に活用していくので，頑張ってついてきてくれ！！
</p>
<br />

<h2>一階化</h2>
<p>
まずは「一階化」を行う．
式(1)中にある加速度<?php WriteEquation("\{\ddot{\mathbf{r}}_i\}", 14) ?>は求めたい変数ではないので，これを消去したい．
ということで式(1)を，<?php WriteEquation("\{\mathbf{r}_i\}", 14) ?>と<?php WriteEquation("\{ \mathbf{v}_i \} = \{ \dot{\mathbf{r}}_i \}", 14) ?>の一階微分だけで表現する．
これが「一階化」なのだ！
</p>
<div class="waku">
<div style="float:right">(2)</div>
<img src="http://www.natural-science.or.jp/images/20120409-3.gif" alt="" />
</div>
<br />

<h2>境界条件</h2>
<p>
しかし，一階化しても式(2)は6N本しかないので，まだ全ての変数を決定することはできない．
そこで拘束条件を考えてみる．
各質点のあいだには<span style="font-weight:600">質点間の距離を一定に保つ</span>拘束条件がある．
この条件式は式(3)となる．
</p>
<div class="waku">
<div style="float:right">(3)</div>
<img src="http://www.natural-science.or.jp/images/20120409-4.gif" alt="" />
</div>
<br />

<h2>張力に含まれる係数<?php WriteEquation("\{\alpha_i\}", 14) ?>を求める</h2>
<p>
さて，<span style="font-weight:600">これが今回のヤマ場だ！！</span>
運動方程式(1)と拘束条件式(3)から，
位置<?php WriteEquation("\{\mathbf{r}_i\}", 14) ?>と速度<?php WriteEquation("\{ \mathbf{v}_i \} = \{ \dot{\mathbf{r}}_i \}", 14) ?>で表現された，
張力に含まれる係数<?php WriteEquation("\{ \alpha_i \}", 14) ?>に関する連立方程式を立式する．
この<?php WriteEquation("\{ \alpha_i \}", 14) ?>さえ求められれば式(2)をRunge-Kutta法などの差分スキームで存分にブン回せるのだ！
</p>
<p>
まずは下ごしらえとして，式(3)を時刻<?php WriteEquation("t", 14) ?>で微分する
</p>
<!--\footnote{
ベクトルの時間微分はどうやるんだ？と思った人もいるかもしれないので，ここで解説する．
まあ，簡単な話で，<span style="font-weight:600">成分ごとに分解してそれぞれ微分すればいい</span>だけなのだ．
たとえば，ある時間変化するベクトル<?php WriteEquation("\mathbf{r}(t) = (x(t)\;y(t)\;z(t))^{\tran}", 14) ?>における，<?php WriteEquation("\mathbf{r}(t)^2 = \mathbf{r}(t) \cdot \mathbf{r}(t)", 14) ?>の時間微分は
\begin{align*}
\frac{\deff}{\deff t} \mathbf{r}(t)^2 &=
%
\frac{\deff}{\deff t} \left[ (x(t)\;y(t)\;z(t))
\left(
\begin{array}{c}
x(t) \\
y(t) \\
z(t)
\end{array}
\right)
\right]
%
= \frac{\deff}{\deff t} (x(t)^2+y(t)^2+z(t)^2) \\
%
&= 2 x(t) \frac{\deff x(t)}{\deff t} + 2 y(t) \frac{\deff y(t)}{\deff t} + 2 z(t) \frac{\deff z(t)}{\deff t}
%
= 2 \mathbf{r}(t) \frac{\deff \mathbf{r}(t)}{\deff t}.
\end{align*}
この式変形の最初と最後だけ取ってくると，"<?php WriteEquation("\frac{\deff}{\deff t} \mathbf{r}(t)^2 = 2 \mathbf{r}(t) \frac{\deff \mathbf{r}(t)}{\deff t}", 14) ?>"となって
「なあんだ，スカラーと同じじゃん」と思うのである．
（同じじゃないのもあるので注意！！）
ここには出ないけど，空間微分「ナブラ」<?php WriteEquation("\nabla", 14) ?>とかが出てきても，恐れずにまずは成分ごとに計算してみよう！
}．-->
<div class="waku">
<div style="float:right">(4)</div>
<img src="http://www.natural-science.or.jp/images/20120409-5.gif" alt="" />
</div>
<p>
式(4)の両辺を2で割り，さらにもう1回<?php WriteEquation("t", 14) ?>で微分する．
</p>
<div class="waku">
<div style="float:right">(5)</div>
<img src="http://www.natural-science.or.jp/images/20120409-6.gif" alt="" />
</div>
<p>
<span style="font-weight:600">相対位置<?php WriteEquation("\{ ({\mathbf{r}}_{i} - {\mathbf{r}}_{i-1}) \}", 14) ?>の二階微分<?php WriteEquation("\{ (\ddot{\mathbf{r}}_{i} - \ddot{\mathbf{r}}_{i-1}) \}", 14) ?>が出てきた！</span>
運動方程式(1)からも，うまく<?php WriteEquation("\{ (\ddot{\mathbf{r}}_{i} - \ddot{\mathbf{r}}_{i-1}) \}", 14) ?>を出して消去すれば，<?php WriteEquation("\{\alpha_i\}", 14) ?>を求められそうだぞ！
ということで，式(1)の両辺を質量<?php WriteEquation("\{ m_i \}", 14) ?>で割ってみる．
</p>
<div class="waku">
<div style="float:right">(6)</div>
<img src="http://www.natural-science.or.jp/images/20120409-7.gif" alt="" />
</div>
<p>
さてここで<?php WriteEquation("\{ (\ddot{\mathbf{r}}_{i} - \ddot{\mathbf{r}}_{i-1}) \}", 14) ?>を出すために，<?php WriteEquation("i", 14) ?>番目の式から<?php WriteEquation("(i-1)", 14) ?>番目の式を辺々引く．
</p>
<div class="waku">
<div style="float:right">(7)</div>
<img src="http://www.natural-science.or.jp/images/20120409-8.gif" alt="" />
</div>
<p>
ここで<span style="font-weight:600"><?php WriteEquation("\ddot{\mathbf{r}_0}", 14) ?>はどうするんだ？</span>と思った人がいるかもしれない．
<?php WriteEquation("{\mathbf{r}_0}", 14) ?>は固定点なので力がつり合っており<?php WriteEquation("\ddot{\mathbf{r}_0}=\mathbf{0}", 14) ?>になっている，としておこう．
ここで式(7)の両辺と<?php WriteEquation("\{ ({\mathbf{r}}_{i} - {\mathbf{r}}_{i-1}) \}", 14) ?>の内積をとる．
</p>
<div class="waku">
<div style="float:right">(8)</div>
<img src="http://www.natural-science.or.jp/images/20120409-9.gif" alt="" />
</div>
<p>
式(5)から導かれる関係式<?php WriteEquation("(\ddot{\mathbf{r}}_{i} - \ddot{\mathbf{r}}_{i-1}) \cdot (\mathbf{r}_{i} - \mathbf{r}_{i-1}) = - (\dot{\mathbf{r}}_{i} - \dot{\mathbf{r}}_{i-1})^2", 14) ?>を使って，
式(8)の左辺にある相対位置の二階微分<?php WriteEquation("\{ (\ddot{\mathbf{r}}_{i} - \ddot{\mathbf{r}}_{i-1}) \}", 14) ?>を消そう．
<span style="font-weight:600">これでやっと加速度を消去できたな！}
ついでに，後々のために右辺と左辺を入れ替えたり係数を掛ける順番を少し入れ替えておく．
</p>
<div class="waku">
<div style="float:right">(9)</div>
<img src="http://www.natural-science.or.jp/images/20120409-10.gif" alt="" />
</div>
<p>
<span style="font-weight:600">さて，これは<?php WriteEquation("\{ \alpha_i \}", 14) ?>についての連立方程式になりそうだな...</span>
とりあえず式(9)を行列化してみよう．
式(9)を下記のとおりに置き換える．
</p>
<div class="waku">
<div style="float:right">(10)</div>
<img src="http://www.natural-science.or.jp/images/20120409-11.gif" alt="" />
</div>
<p>
ただしここで，
</p>
<div class="waku">
<div style="float:right">(11)</div>
<img src="http://www.natural-science.or.jp/images/20120409-12.gif" alt="" />
</div>
<p>
なのだが，<?php WriteEquation("\mathbf{R}", 14) ?>は
</p>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120409-13.gif" alt="" />
</div>
<p>
となる．
あとは，Gauss-Jordanの消去法などを用いて<?php WriteEquation("\mathbf{\alpha}", 14) ?>を求めれば完了だ！
<span style="font-weight:600">やっと<?php WriteEquation("\{ \alpha_i \}", 14) ?>を求められたな！！おつかれっす！！</span>
</p>


<h2>N重振り子シミュレータ</h2>
<p>
本シミュレータは、HTML5(canvas要素)＋WebGL(Three.jsライブラリ)を用いて、プラグインなし実行することができます。
ただし、クライアントサイドのブラウザとグラフィックカードが、HTML5とWebGLに対応している必要があります。
</p>

<p style="text-align:center">
↓デモ画像（<a href="http://www.natural-science.or.jp/WebGL/MPJS.html" target="_blank" style="font-weight:600; font-size:x-small;">「点電荷による電気力線シミュレータ」はこちら</a><br /><br />
<a href="http://www.natural-science.or.jp/WebGL/MPJS.html" target="_blank"><img src="http://www.natural-science.or.jp/images/20120409.gif" alt="" />
</a>
</p>


<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="20120409.gif" src="http://www.natural-science.or.jp/images/20120409.gif" width="600" height="420" class="mt-image-none" style="" /></span>
-->
]]>
        
    </content>
</entry>

<entry>
    <title>Javascript マルチスレッド処理技術 WebWorkerのサンプル</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120410002114.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13057</id>

    <published>2012-04-09T15:21:14Z</published>
    <updated>2012-04-09T15:29:12Z</updated>

    <summary> WebWorker とは、HTML5 API の１つで、Javascript ...</summary>
    <author>
        <name>遠藤 理平</name>
        <uri>http://www.natural-science.or.jp/members/endo_rihei.php</uri>
    </author>
    
        <category term="TIPS 集" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="html5" label="HTML5" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="webworker" label="Webworker" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<p>
WebWorker とは、HTML5 API の１つで、Javascript を並列計算するために標準で用意されている規格です。
通常 Javascript は CPU の１つのスレッドで演算を行うため、もし時間のかかる演算の場合にはその演算が終わるまで次の命令を受け付けません。
一方、WebWorker を利用すると、予め処理を定義しておいた「Worker」を任意のタイミングで呼び出すことで、重い演算のマルチスレッド処理が可能となります。
つまり、昨今のマルチコア搭載マシンで、 Javascript を利用した演算を効率的に行うことができるわけです。
</p>

<h2>WebWorker の使い方</h2>
<p>
マルチスレッド処理と聞くと難しく感じますが、WebWorkerを実装するのは非常に簡単です。
ライブラリを別途読み込む必要すらありません。
次の４つを行います。<br />
<br />
１．Worker クラスのオブジェクトを宣言<br />
２．Worker に変数を送る<br />
３．Worker で行う処理を定義<br />
４．Worker から処理結果を受けとる<br />
<br />
４つとも簡単なので、
次に具体的なプログラムソースを示します。
</p>
<br />
<h3>１．Worker クラスのオブジェクトを宣言</h3>
<pre class="brush: js;">
var worker = new Worker("Worker で実行する処理を記述するファイル名");
</pre>
<p>
これだけです。本サンプルでは、Worker で実行する処理を記述する外部ファイル名を「worker_test.js」とします。
もちろん、オブジェクト名「worker」は任意です。
</p>
<br />
<h3>２．Worker に変数を送る</h3>
<pre class="brush: js;">
worker.postMessage( 変数名 ); //Worker に 変数を渡す
</pre>
<p>
これだけです。	
「worker」は１で宣言した Worker クラスのオブジェクト名で、「postMessage」は Worker クラスオブジェクトのメソッドです。
「postMessage」に引数を設定することで、外部で実行する処理にパラメータを送ることができます。
引数には普通の変数だけでなく、配列やオブジェクト（連想配列）を与えることもできます。
オブジェクトを引数として与えた例は次のとおりです。
</p>
<pre class="brush: js;">
var AA = {n:1, l:2, m:3}; //Worker に渡すオブジェクトを宣言
worker.postMessage(AA);	  //Worker に オブジェクトを渡す
</pre>
<br />
<h3>３．Worker で行う処理を定義</h3>
<p>
１で指定したファイルに、２で与えたパラメータを利用して Worker で実行する処理を記述します。
</p>
<h4>worker_test.js</h4>
<pre class="brush: js;">
onmessage = function(event) {
    var AA = event.data;  
    //ここに処理を記述する
    var results = AA;
    postMessage(results);
}
</pre>
<p>
「event.data」には、２の「postMessage」の引数で設定した変数が格納されています。
さらに、「postMessage」関数を用いて処理の結果を呼び出したオブジェクトに返します。
上の例では、動作確認を目的としているので、受けた変数を何も処理をせずにそのまま返しています。
</p>
<br />
<h3>４．Worker から処理結果を受けとる</h3>
<p>
３の「postMessage」関数の引数で指定した変数を元のプログラムで受け取ります。
変数が返されると、Worker クラスオブジェクトのメソッド「onmessage」が呼び出されます。
</p>
<pre class="brush: js;">
worker.onmessage = function(event) {
	var BB = event.data;
}
</pre>
<p>
「event.data」には、３の「postMessage」の引数で設定した変数が格納されています。
受けた処理後のデータをあとは煮るなり焼くなりするだけです。
</p>
<br />
<h2>WebWorker のサンプルプログラム</h2>
<p>
下のボタンを押すと、データを Worker	に送った後に処理を行い、
さらに Worker から受け取ったデータを出力しています。
</p>


<iframe src="worker_test.html" style="width:450px; height:200px; border: 0px; overflow:hidden;" scrolling="no"></iframe>


<br />

<h3>サンプルプログラムのソース</h3>
<p>
上記サンプルプログラムは、「メイン」と「worker_test.js」の２つのソースから成り立ちます。	
</p>
<h4>メインのソース</h4>
<pre class="brush: js;">
var worker = new Worker("worker_test.js");
worker.onmessage = function(event) {//ワーカーから受け取り
	var BB = event.data;
	document.getElementById("output").innerHTML = "n = " + BB.n + "<br>l = " + BB.l + "<br>m = " + BB.m;
}
function pushButton (){  //ボタンをクリックした際の処理
	var AA = {n:1, l:2, m:3};
	worker.postMessage(AA);		 // ワーカに数値を渡す
};
</pre>
<h4>worker_test.js</h4>
<pre class="brush: js;">
onmessage = function(event) {
    var AA = event.data; // event.data
    //ここに処理を記述する
    var results = AA;
    postMessage(results);
}
</pre>
<br />

<h2>参考ページ</h2>
<p>
・<a href="http://akiyoshi220.blogspot.jp/2010/06/html5web-workers.html" target="_blank">HTML5のWeb Workersを使ってみた（コイケアキヨシ blog）</a><br />
・Webworker の例：<a href="http://www.natural-science.or.jp/WebGL/HydrogenWaveFunction_ver1.0.html">HTML5による物理シミュレーション～水素原子の波動関数ビューア～</a>
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>HTML5による物理シミュレーション環境の構築水素原子の波動関数ビューア</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120406225432.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13055</id>

    <published>2012-04-06T13:54:32Z</published>
    <updated>2012-04-06T14:23:31Z</updated>

    <summary> HTML5の新要素 canvas 要素に WebGL（Three.js）＋Ja...</summary>
    <author>
        <name>遠藤 理平</name>
        <uri>http://www.natural-science.or.jp/members/endo_rihei.php</uri>
    </author>
    
        <category term="仮想物理実験室" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="計算物理学" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="html5" label="HTML5" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="threejs" label="Three.js" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="webgl" label="WebGL" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="werworker" label="WerWorker" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="シュレディンガー方程式" label="シュレディンガー方程式" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="ビューア" label="ビューア" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="波動関数" label="波動関数" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="解析解" label="解析解" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<p>
HTML5の新要素 canvas 要素に WebGL（Three.js）＋Javascript を利用して構築する物理シミュレータの第３弾として、「<a href="http://www.natural-science.or.jp/WebGL/HydrogenWaveFunction_ver1.0.html" target="_blank">水素原子の波動関数ビューア</a>」を公開します。
<em>水素原子</em>は、陽子１つと電子１つで構成される最も単純な構造の原子です。
電子はクーロン相互作用の引力により、電子よりも2000倍重たい陽子の周りに雲のように分布します（電子雲）。
電子状態は、主量子数<?php WriteEquation("n") ?>, 方位量子数<?php WriteEquation("l") ?>, 磁気量子数<?php WriteEquation("m") ?>３つのパラメータで指定され、それぞれ特徴的な形状を成します。
本稿では HTML5 を水素原子の電子状態を表す波動関数の３次元空間分布を可視化するためのビューアとして利用します。
</p>

<p style="text-align:center">
<span style="font-weight:600; font-size:x-small; color:red">以下の図はデモ画面です</span> → <a href="http://www.natural-science.or.jp/WebGL/HydrogenWaveFunction_ver1.0.html" target="_blank" style="font-weight:600; font-size:x-small;">実行ページこちら</a><br /><br />
<a href="http://www.natural-science.or.jp/WebGL/HydrogenWaveFunction_ver1.0.html" target="_blank"><img src="http://www.natural-science.or.jp/images/20120406-1.gif" alt="" /></a>
</p>
<br />

<h2>計算アルゴリズム</h2>
<p>
水素原子の電子状態は、電子のように非常に小さな粒子が従う<em>シュレーディンガー方程式</em>を解くことで理解することができます。
電子状態を表す波動関数に対するシュレーディンガー方程式は、その他の原子の場合と異なり、<strong>解析的</strong>に解くことができます。
解析解は、主量子数<?php WriteEquation("n") ?>, 方位量子数<?php WriteEquation("l") ?>, 磁気量子数<?php WriteEquation("m") ?>の３つのパラメータを用いて、
</p>
<div class="waku">
<div style="float:right">(1)</div>
<img src="http://www.natural-science.or.jp/images/20120329-1.gif" alt="" />
</div>
<p>
と表されます。
<?php WriteEquation("R") ?>と<?php WriteEquation("Y") ?>は、元のシュレーディンガー方程式を変数分離した際に得られる動径方向と方位角方向の解で
</p>
<div class="waku">
<div style="float:right">(2)</div>
<img src="http://www.natural-science.or.jp/images/20120329-2.gif" alt="" />
</div>
<p>
と
</p>
<div class="waku">
<div style="float:right">(3)</div>
<img src="http://www.natural-science.or.jp/images/20120329-6.gif" alt="" />
</div>
<p>
となります。式(2),(3)にある <?php WriteEquation("L") ?>はラゲール多項式, <?php WriteEquation("P") ?>はルジャンドル陪関数を表し、
</p>
<div class="waku">
<div style="float:right">(4)</div>
<img src="http://www.natural-science.or.jp/images/20111227-1.gif" alt="" />
</div>
<br />
<div class="waku">
<div style="float:right">(5)</div>
<img src="http://www.natural-science.or.jp/images/20120329-5.gif" alt="" />
</div>
<p>
で定義されます。ラゲール多項式は階乗を計算できれば簡単に計算することができますが、
ルジャンドル陪関数は、複数回の微分を演算する必要があるため、簡単に計算することできません。
しかしながら、漸化式を用いることで比較的簡単に計算することができます。<br />
<span style="font-size:x-small">※ルジャンドル陪関数については「<a href="http://www.natural-science.or.jp/article/20111227231948.php">ルジャンドル陪関数の漸化式と規格化</a>」を参考にして下さい。</span>
</p>
<p>
式中の<?php WriteEquation("\alpha r") ?>は長さの表す無次元量です。
本ビューアは、<?php WriteEquation("\alpha") ?>を単位として、１辺の長さ<?php WriteEquation("L=80") ?>の立方体を描画しています。
ただし、<?php WriteEquation("\alpha") ?>は
</p>
<div class="waku">
<div style="float:right">(6)</div>
<img src="http://www.natural-science.or.jp/images/20120329-3.gif" alt="" />
</div>
<p>
で定義され、<?php WriteEquation("a_0") ?>はボーア半径と呼ばれ
</p>
<div class="waku">
<div style="float:right">(7)</div>
<img src="http://www.natural-science.or.jp/images/20120329-4.gif" alt="" />
</div>
<p>
と定義されます。
</p>

<h2>スクリーンショット</h2>
<p style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120406-2.gif" alt="" style="width:300px" />
<img src="http://www.natural-science.or.jp/images/20120406-3.gif" alt="" style="width:300px" />
<img src="http://www.natural-science.or.jp/images/20120406-4.gif" alt="" style="width:300px" />
<img src="http://www.natural-science.or.jp/images/20120406-5.gif" alt="" style="width:300px" />
</p>
<br />

<h2>プログラムソース</h2>
<h3>Javascript</h3>
<p>
本ビューアは「WebWorker」と呼ばれる Javascript にて並列化計算を行うための技術を利用しています。
WebWorker も WeBGL と同様に、HTML5 における Javascript の標準化技術です。
</p>

<h4>本体</h4>
<pre class="brush: js;">
  var L = 80;       //系のサイズ
  var n_max = 4;    //主量子数の最大値
  var p_max = 40000;//点の数
  var p_size = 0.5; //点のサイズ
  var times, timesL;

  var scatterPlots = new Array(n_max+1);
  var workers = new Array(n_max+1);
  var $id = function(id) { return document.getElementById(id); }

  function init(){
    //各状態のオブジェクトとワーカーの多重配列を宣言
    for (var n = 1; n &lt;= n_max; n++) {
      scatterPlots[n] = new Array(n);
      workers[n] = new Array(n);
      for (var l = 0; l &lt; n; l++) {  
        scatterPlots[n][l] = new Array(l+1);
        workers[n][l] = new Array(l+1);
        for(m=0; m&lt;=l; m++)  scatterPlots[n][l][m] = new Array(3);
      }
    }
    //ワーカーの設定
    for (var n = 1; n &lt;= n_max; n++){
      for (var l = 0; l &lt; n; l++){
        for (var m = 0; m &lt;= l; m++){
          workers[n][l][m] = new Worker(&quot;worker_wave.js&quot;);
          for(var i=0; i&lt;=2; i++) scatterPlots[n][l][m][i] = new THREE.Object3D();
          workers[n][l][m].onmessage = function(event) {//ワーカーから受け取り
            var Ps = event.data;
            var n = Ps.n; var l =Ps.l; var m =Ps.m;
            var Xs = Ps.x;
            var Ys = Ps.y;
            var Zs = Ps.z;
            var mat = new THREE.ParticleBasicMaterial({vertexColors:true, size: p_size});
            var pointGeos = new Array(3);
            for(var i=0; i&lt;=2; i++) pointGeos[i] = new THREE.Geometry();
            if(m==0){
              for (var i=0; i&lt; Zs.length; i++) {
                pointGeos[0].vertices.push(new THREE.Vertex( new THREE.Vector3(Zs[i].x, Zs[i].y, Zs[i].z) ));
                if(Zs[i].a &gt;0 ) pointGeos[0].colors.push(new THREE.Color(0xff0000));
                else  pointGeos[0].colors.push(new THREE.Color(0x0000ff));
              }
            }else{
              for (var i=0; i&lt; Xs.length; i++) {  
                pointGeos[1].vertices.push(new THREE.Vertex( new THREE.Vector3(Xs[i].x, Xs[i].y, Xs[i].z) ));
                if(Xs[i].a &gt;0 ) pointGeos[1].colors.push(new THREE.Color(0xff0000));
                else  pointGeos[1].colors.push(new THREE.Color(0x0000ff));
                pointGeos[2].vertices.push(new THREE.Vertex( new THREE.Vector3(Ys[i].x, Ys[i].y, Ys[i].z) ));
                if(Ys[i].a &gt;0 ) pointGeos[2].colors.push(new THREE.Color(0xff0000));
                else  pointGeos[2].colors.push(new THREE.Color(0x0000ff));
              }
            }

            if(m==0){
              scatterPlots[n][l][m][0].add(new THREE.ParticleSystem(pointGeos[0], mat));
               $id(&quot;s&quot; + n + l + m ).innerHTML = &quot;準備完了！&quot; ;
              $id(&quot;n&quot; + n + l + m ).style.display = 'inline';
             }else{
              scatterPlots[n][l][m][1].add(new THREE.ParticleSystem(pointGeos[1], mat));
               $id(&quot;s&quot; + n + l + m + &quot;x&quot;).innerHTML = &quot;準備完了！&quot; ;
              $id(&quot;n&quot; + n + l + m + &quot;x&quot;).style.display = 'inline';
              scatterPlots[n][l][m][2].add(new THREE.ParticleSystem(pointGeos[2], mat));
               $id(&quot;s&quot; + n + l + m + &quot;y&quot;).innerHTML = &quot;準備完了！&quot; ;
              $id(&quot;n&quot; + n + l + m + &quot;y&quot;).style.display = 'inline';
             }
             
          }
          if(m==0){
            $id(&quot;n&quot; + n + l + m ).checked = false;
            $id(&quot;n&quot; + n + l + m ).style.display = 'none';
          }else{
            $id(&quot;n&quot; + n + l + m + &quot;x&quot;).checked = false;
            $id(&quot;n&quot; + n + l + m + &quot;x&quot;).style.display = 'none';
            $id(&quot;n&quot; + n + l + m + &quot;y&quot;).checked = false;
            $id(&quot;n&quot; + n + l + m + &quot;y&quot;).style.display = 'none';
          }
        }
      }
    }
  }

  var width, height;
  var renderer;
  function initThree() {
    width = document.getElementById('canvas-frame').clientWidth;
    height = document.getElementById('canvas-frame').clientHeight;  
    try {renderer = new THREE.WebGLRenderer({antialias: true});} catch (e) {}  
    if(!renderer) document.getElementById(&quot;errer&quot;).innerHTML = '&lt;p style=&quot;text-align:center;font-size:small; color:red&quot;&gt;お使いの環境ではWebGLはご利用いただけません。&lt;br /&gt;WebGLに対応していない方のためにGIFファイルを以下に用意しました。&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.natural-science.or.jp/images/tutorial6.gif&quot; alt=&quot;WEBGLデモ&quot; /&gt;&lt;/p&gt;';
    renderer.setSize(width, height);
    document.getElementById('canvas-frame').appendChild(renderer.domElement);
    renderer.setClearColorHex(0x000000, 1.0);
    $id(&quot;pn&quot;).value = p_max;
    $id(&quot;ps&quot;).value = p_size;      
  }
  
  var camera;
  var cameraL = 150;
  var cameraTheta = Math.PI*(1/2-0.01);
  var cameraPhi   = Math.PI*(3/2-0.01);  
  function initCamera() {  
    camera = new THREE.PerspectiveCamera( 45 , width / height , 1 , 10000 );
    camera.up.x = 0;
    camera.up.y = 0;
    camera.up.z = 1;
    camera.position.set(cameraL*Math.sin(cameraTheta)*Math.cos(cameraPhi),
              cameraL*Math.sin(cameraTheta)*Math.sin(cameraPhi),
              cameraL*Math.cos(cameraTheta));       
  }
  var scene;
  function initScene() {    
    scene = new THREE.Scene();
    scene.fog = new THREE.FogExp2( 0xFFFFFF, 0.0015 );    
  }
  var light, light2;
  function initLight() {
    light = new THREE.DirectionalLight(0xFFFFFF, 1.0, 0);
    light.position.set( 100, 100, 100 );
    scene.add(light);

    light2 = new THREE.AmbientLight(0x777777);
    scene.add(light2);
  }


  
  var scatterPlot;
  var axis;
  function initObject(){
    axis = new THREE.Object3D();
    scene.add(axis);
    scatterPlot = scatterPlots[1][0][0];
  
    function v(x,y,z){ return new THREE.Vertex(new THREE.Vector3(x,y,z)); }
    var lineGeo = new THREE.Geometry();
    lineGeo.vertices.push(
      v(-L/2, 0, 0), v(L/2, 0, 0),
      v(0, -L/2, 0), v(0, L/2, 0),
      v(0, 0, -L/2), v(0, 0, L/2),
    
      v(-L/2, L/2, -L/2), v(L/2, L/2, -L/2),
      v(-L/2, -L/2, -L/2), v(L/2, -L/2, -L/2),
      v(-L/2, L/2, L/2), v(L/2, L/2, L/2),
      v(-L/2, -L/2, L/2), v(L/2, -L/2, L/2),
    
      v(-L/2, 0, L/2), v(L/2, 0, L/2),
      v(-L/2, 0, -L/2), v(L/2, 0, -L/2),
      v(-L/2, L/2, 0), v(L/2, L/2, 0),
      v(-L/2, -L/2, 0), v(L/2, -L/2, 0),
    
      v(L/2, -L/2, -L/2), v(L/2, L/2, -L/2),
      v(-L/2, -L/2, -L/2), v(-L/2, L/2, -L/2),
      v(L/2, -L/2, L/2), v(L/2, L/2, L/2),
      v(-L/2, -L/2, L/2), v(-L/2, L/2, L/2),
    
      v(0, -L/2, L/2), v(0, L/2, L/2),
      v(0, -L/2, -L/2), v(0, L/2, -L/2),
      v(L/2, -L/2, 0), v(L/2, L/2, 0),
      v(-L/2, -L/2, 0), v(-L/2, L/2, 0),
    
      v(L/2, L/2, -L/2), v(L/2, L/2, L/2),
      v(L/2, -L/2, -L/2), v(L/2, -L/2, L/2),
      v(-L/2, L/2, -L/2), v(-L/2, L/2, L/2),
      v(-L/2, -L/2, -L/2), v(-L/2, -L/2, L/2),
    
      v(-L/2, 0, -L/2), v(-L/2, 0, L/2),
      v(L/2, 0, -L/2), v(L/2, 0, L/2),
      v(0, L/2, -L/2), v(0, L/2, L/2),
      v(0, -L/2, -L/2), v(0, -L/2, L/2)
    );
    var lineMat = new THREE.LineBasicMaterial({color: 0x444444, lineWidth: 1});
    var line = new THREE.Line(lineGeo, lineMat);
    line.type = THREE.Lines;
    axis.add(line);
    
    var titleX = createText2D('-X', 'gray');
    titleX.position.x = -(L/2+5);
    titleX.rotation.x = Math.PI/2; 
    axis.add(titleX);
    
    var titleX = createText2D('X', 'gray');
    titleX.position.x = (L/2+5);
    titleX.rotation.x = Math.PI/2;
    axis.add(titleX);
    
    var titleX = createText2D('-Y', 'gray');
    titleX.position.y = -(L/2+5);
    titleX.rotation.x = Math.PI/2;
    axis.add(titleX);
    
    var titleX = createText2D('Y', 'gray');
    titleX.position.y = (L/2+5);
    titleX.rotation.x = Math.PI/2;
    axis.add(titleX);
    
    var titleX = createText2D('-Z', 'gray');
    titleX.position.z = -(L/2+5);
    titleX.rotation.x = Math.PI/2;
    axis.add(titleX);
    
    var titleX = createText2D('Z', 'gray');
    titleX.position.z = (L/2+5);
    titleX.rotation.x = Math.PI/2;
    axis.add(titleX);
    
    start(1, 0, 0);//n=1だけデフォルトで計算スタート
    $id(&quot;n100&quot;).checked = true;    
    /*
    var AA = {n:1, l:0, m:0, p_max:p_max, L: L};
      workers[1][0][0].postMessage(AA);     // ワーカに数値を渡す
    $id(&quot;b100&quot;).innerHTML = &quot;再計算&quot;;  ;    
    $id(&quot;s100&quot;).innerHTML = &quot;計算中...&quot; ;
    */    
  }
  function start(n, l, m) {//計算開始ボタンを押した時に呼び出される関数
    for(var i=0; i&lt;=2; i++) {
      scene.remove( scatterPlots[n][l][m][i]);
      scatterPlots[n][l][m][i] = new THREE.Object3D();
    }
    p_max = parseInt($id(&quot;pn&quot;).value);
    p_size = parseFloat($id(&quot;ps&quot;).value);  
    $id(&quot;b&quot; + n + l + m ).innerHTML = &quot;再計算&quot;;  
    if(m==0){
      $id(&quot;s&quot; + n + l + m).innerHTML = &quot;計算中...&quot; ;
    }else{
      $id(&quot;s&quot; + n + l + m + &quot;x&quot;).innerHTML = &quot;計算中...&quot; ;
      $id(&quot;s&quot; + n + l + m + &quot;y&quot;).innerHTML = &quot;計算中...&quot; ;
    }  
    var AA = {n:n, l:l, m:m, p_max:p_max, L: L};
    workers[n][l][m].postMessage(AA);     // ワーカに数値を渡す
  }

  function initEvent(){//イベントの登録
    window.addEventListener(&quot;mousedown&quot;, onMousedown, false);
    window.addEventListener(&quot;mouseup&quot;, onMouseup, false);
    window.addEventListener(&quot;mousemove&quot;,  onMousemove, false);
    window.addEventListener(&quot;mousewheel&quot;, onMousewheel, false);
    window.addEventListener('DOMMouseScroll', onMousewheel, false); //Firefox用（マウスホイール）
    window.addEventListener(&quot;dragover&quot;, onCancel, false);
    window.addEventListener(&quot;dragenter&quot;, onCancel, false);
    window.addEventListener(&quot;drop&quot;, onDropFile, false);
    
    for (var n = 1; n &lt;= n_max; n++)
      for (var l = 0; l &lt; n; l++)
        for (var m = 0; m &lt;= l; m++)
        //$id(&quot;b&quot; + n + l + m).addEventListener(&quot;click&quot;, start(n,l,m), false); //これでは、start(n,l,m)が実行されてしまうのでダメ
        //$id(&quot;b&quot; + n + l + m).addEventListener(&quot;click&quot;, function(event) { start(n,l,m); }, false); //これでは、イベントの登録がfor文の後になるため、意図通り引き数を与えることができないダメ
        $id(&quot;b&quot; + n + l + m).addEventListener(&quot;click&quot;, (function (n_, l_, m_) { return function() { start(n_, l_, m_); } })(n, l, m) , false);
    //参考ページ
    //http://d.hatena.ne.jp/Syunpei/20070605/1181035316
    //http://d.hatena.ne.jp/uriyuri/20081014/1223974862
  }

  function loop() {
    for (var n = 1; n &lt;= n_max; n++)
      for (var l = 0; l &lt; n; l++)
        for (var m = 0; m &lt;= l; m++){
          if(m==0){
            if($id(&quot;n&quot; + n + l + m).checked) scene.add(scatterPlots[n][l][m][0]);
            else scene.remove( scatterPlots[n][l][m][0]);            
          }else{
            if($id(&quot;n&quot; + n + l + m + &quot;x&quot;).checked) scene.add(scatterPlots[n][l][m][1]);
            else scene.remove( scatterPlots[n][l][m][1]);
            if($id(&quot;n&quot; + n + l + m + &quot;y&quot;).checked) scene.add(scatterPlots[n][l][m][2]);
            else scene.remove( scatterPlots[n][l][m][2]);                    
          }
          
        }

    renderer.clear();
    camera.lookAt( {x:0, y:0, z:0 } );    
    renderer.render(scene, camera);
    window.requestAnimationFrame(loop);
  }
  function threeStart() {
    initEvent();
    initThree();
    initCamera();
    initScene();    
    initLight();  
    initObject();
    loop();
  }
  function createTextCanvas(text, color, font, size) {
    size = size || 24;
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    var fontStr = (size + 'px ') + (font || 'Arial');
    ctx.font = fontStr;
    var w = ctx.measureText(text).width;
    var h = Math.ceil(size);
    canvas.width = w;
    canvas.height = h;
    ctx.font = fontStr;
    ctx.fillStyle = color || 'black';
    ctx.fillText(text, 0, Math.ceil(size*0.8));
    return canvas;
  }
  
  function createText2D(text, color, font, size, segW, segH) {
    var canvas = createTextCanvas(text, color, font, size);
    var plane = new THREE.PlaneGeometry(canvas.width, canvas.height, segW, segH);
    var tex = new THREE.Texture(canvas);
    tex.needsUpdate = true;
    var planeMat = new THREE.MeshBasicMaterial({
      map: tex, color: 0xffffff, transparent: true
    });
    var mesh = new THREE.Mesh(plane, planeMat);
    mesh.scale.set(0.15, 0.15, 0.15);
    mesh.doubleSided = true;
    return mesh;
  }
  function QuaternionRotation(theta, u, v){ //(回転角, 回転軸, 任意のベクトル)
    var P = new quat4.create([v[0],v[1],v[2],0]);
    var Q = new quat4.create([-u[0]*Math.sin(theta/2), -u[1]*Math.sin(theta/2), -u[2]*Math.sin(theta/2), Math.cos(theta/2)]);
    var R = new quat4.create([u[0]*Math.sin(theta/2), u[1]*Math.sin(theta/2), u[2]*Math.sin(theta/2), Math.cos(theta/2)]);
    var S0 = quat4.multiply(P,Q, quat4.create());
    var S =  quat4.multiply(R,S0,quat4.create());  
    return S;
  }


////マウスイベント////////////////////////////////////////////////////
  var down = false;
  var v, u, w, theta;
  function onMousedown (ev){  //マウスダウン時イベント
    if (ev.target == renderer.domElement) { 
      down = true;
      sx = ev.clientX; sz = ev.clientY;
      v = new vec3.create([camera.position.x,camera.position.y,camera.position.z]);  //任意の点
      u = new vec3.create([-v[0]*v[2],-v[1]*v[2], (v[0]*v[0]+v[1]*v[1])]);
      u = vec3.normalize(u, vec3.create());      
      w = new vec3.create([v[1],-v[0],0]);
      w = vec3.normalize(w, vec3.create());
      
    }
  };
  function onMouseup (){       //マウスアップ時イベント
    down = false; 
  };
  function onMousemove (ev) {  //マウスムーブ時イベント
    if (down) {
      if (ev.target == renderer.domElement) {
        var dx = -(ev.clientX - sx);
        var dz = -(ev.clientY - sz);

        theta =  dx/ 100;
        var S = QuaternionRotation(theta, u, [camera.position.x,camera.position.y,camera.position.z]);        
        theta =  -dz/ 100;
        S =  QuaternionRotation(theta, w, [S[0],S[1],S[2]]);        
        camera.position.set(S[0],S[1],S[2]);  
        sx -= dx;
        sz -= dz;  
      }
    }
  }
  function onMousewheel(ev){//マウスホイール時イベント
    var x = camera.position.x;
    var y = camera.position.y;
    var z = camera.position.z;
    cameraL = Math.sqrt(Math.pow(x,2)+Math.pow(y,2)+Math.pow(z,2));
    cameraTheta = Math.acos(z/cameraL);
    if( y &gt;= 0 ) cameraPhi = Math.acos(x/(cameraL*Math.sin(cameraTheta)));
    else cameraPhi = 2.0*Math.PI - Math.acos(x/(cameraL*Math.sin(cameraTheta)));

    var delta;//回転量
    if (ev.wheelDelta) { 
      delta = ev.wheelDelta; //Chrome用
    } else if (ev.detail) {
      delta = -ev.detail*20;      //Firefox用
    }
    cameraL += delta * 0.2;
    if(cameraL &lt; 0) cameraL = 0.1;
    camera.position.set(cameraL*Math.sin(cameraTheta)*Math.cos(cameraPhi),
              cameraL*Math.sin(cameraTheta)*Math.sin(cameraPhi),
              cameraL*Math.cos(cameraTheta));
  }
  var onDropFile = function(ev){         // ファイルドロップ時イベント
    ev.preventDefault();
    var file = ev.dataTransfer.files[0]; // File オブジェクトを取得
    readFile(file);                     // ファイル読み込み
  };
  var onCancel = function(ev){            // デフォル処理をキャンセル
    if(ev.preventDefault) { ev.preventDefault(); }
    return false;
  };
  function f_write(){
    var  str = &quot;&quot;;

    for (var i = 0; i &lt; N_EC; i++) {
      if(!ECs[i].flag) continue;
      for (var j = 0; j &lt; n_line; j++) {
        var geometry = new THREE.Geometry();
        for (var k = 0; k &lt; n_step; k++) {
          if(Lines[i][j][k] != undefined &amp;&amp; Lines[i][j][k] != undefined &amp;&amp; Lines[i][j][k] != undefined)
            str  +=  Lines[i][j][k].x  + &quot; &quot; + Lines[i][j][k].y  + &quot; &quot; + Lines[i][j][k].z  + &quot;\n&quot;;
          else break;
        }
        str  += &quot;\n&quot;;
      }
    }
    var blobBuilder;
    if (&quot;MozBlobBuilder&quot; in window) {
      blobBuilder = new MozBlobBuilder();
    } else if (&quot;WebKitBlobBuilder&quot; in window) {
      blobBuilder = new WebKitBlobBuilder();
    }
    blobBuilder.append(str);
    //var disp = document.getElementById(&quot;download&quot;);
    if (window.URL) {
      window.open(window.URL.createObjectURL(blobBuilder.getBlob()) , &quot;New Window&quot;, &quot;&quot;);
    } else if (window.webkitURL) {
      window.open(window.webkitURL.createObjectURL(blobBuilder.getBlob()), &quot;New Window&quot;, &quot;&quot;);          
    }
    //disp.innerHTML = 'ファイルがダウンロードされました （t='+ t +'）';
  }  
///////////////////////////////////////////////////////////////////////
window.onload = function(){
  init();
  threeStart();
}
</pre>

<br />
<h4>WebWorker（worker_wave.js）</h4>
<pre class="brush: js;">
// WebWorker
onmessage = function(event) {
    var AA = event.data;
  var results = wavefunction(AA);
    // 生成元に結果を返す
    results.n = AA.n; //主量子数
    results.l = AA.l; //方位量子数
    results.m = AA.m; //磁気量子数 m = 0 ～ l
    postMessage(results);
}
function wavefunction(AA){
  var n = AA.n; //主量子数
    var l = AA.l; //方位量子数
    var m = AA.m; //磁気量子数 m = 0 ～ l
  var L = AA.L; //計算する領域のサイズ
  var p_max = AA.p_max; //描画する点の数
  var results = {};
  var points = new Array(); 
  points[0] = new Array();
  if(m&gt;0){
    points[1] = new Array();
    points[2] = new Array();
  }
  if(n==1){
    times  = 5;
    timesL = L/3;
  }
  else if(n==2){
    times  = 20;
    timesL = L/2;    
  }
  else if (n==3){
    times  = 50;
    timesL = L/1.5;        
  }
  else if (n==4){
    times =70;
    timesL = L;      
  }
  //var mat = new THREE.ParticleBasicMaterial({vertexColors:true, size: p_size});
  var pointCount = p_max*100;
  //var pointGeo = new THREE.Geometry();
  var p=0;
  for (var i=0; i&lt;pointCount; i++) {
    var x = timesL/2* (Math.random() - Math.random());
    var y = timesL/2* (Math.random() - Math.random());
    var z = timesL/2* (Math.random() - Math.random());
    
    var r = Math.sqrt(Math.pow(x,2)+Math.pow(y,2)+Math.pow(z,2));
    var theta = Math.acos(z/r);
    var phi;
    if(y&gt;=0) phi = Math.acos(x/(r*Math.sin(theta)));
    else phi = 2.0*Math.PI - Math.acos(x/(r*Math.sin(theta)));
    if(r==0){
      theta = 0;
      phi = 0;
    }
    var R = 2.0/Math.pow(n,2) * Math.sqrt(Factorial(n-l-1)/Factorial(n+l)) * Math.exp(-r/n) * Math.pow( 2.0*r/n,l) *Laguerre(2*l+1, n-l-1, 2.0*r/n)  ;
    var Y = Math.pow(-1.0, m) * Math.sqrt(l+1.0/2.0) * Factorial(l-m)/Factorial(l+m) * Legendre(m,l,Math.cos(theta));
    var Psi, Psi_x, Psi_y;

    Psi = R * Y;
    if(Math.abs(Psi) * times  &lt;Math.random()) continue;  
    if(m==0) {
      if(Psi&gt;0) points[0].push({x:x,y:y,z:z,a:1});
      else points[0].push({x:x,y:y,z:z,a:-1});
    }else{
      var Yx = Y * Math.cos(m*phi);
      var Yy = Y * Math.sin(m*phi);
      Psi_x = R * Yx;
      Psi_y = R * Yy;
      if(Psi_x&gt;0) points[1].push({x:x,y:y,z:z,a:1});
      else points[1].push({x:x,y:y,z:z,a:-1});
      if(Psi_y&gt;0) points[2].push({x:x,y:y,z:z,a:1});
      else points[2].push({x:x,y:y,z:z,a:-1});      
    } 
    p++;
    if(p &gt; p_max) break;
  }
  if(m==0) {  
    results.z = points[0];
  }else{
    results.x = points[1];  
    results.y = points[2];
  }
  return results;
}
  function Factorial(n, n1) //
  {
  　　var m = n1 || 1; 
    if( n&lt;=0 ) return (1.0);
    var F = 1.0;
    for(var i=n; i&gt;=2; i-=m ){
      F *= i;    
    }
    return (F);
  }
  function Legendre (m, l, x ) {//ルジャンドル陪関数
    var mm = Math.abs(m);
    if( mm&gt;l )  return (0);
    var r0, r1, r2;
      r0 = 0.0;
      r1 = Math.pow(1.0-x*x, mm/2.0) * Factorial(2*mm-1,2);
      if( mm==l &amp;& m&gt;=0) return (r1);
      if( mm==l &amp;& m&lt;0)  return (r1 * Math.pow(-1.0,mm) * Factorial(l-mm)/Factorial(l+mm)) ;
      for(var ll = mm+1; ll&lt;=l; ll++ ){
        r2 = ((2.0*ll-1.0)*x*r1 - (ll+mm-1.0)*r0)/(ll-mm);
        r0 = r1;
        r1 = r2;
      }
    if(m&gt;=0) return (r2);
    else return (r2 * Math.pow(-1.0,mm) * Factorial(l-mm)/Factorial(l+mm)) ;
  }
  function Laguerre(k, n, x){
    var sum=0;
    for(var m=0; m&lt;=n; m++){
      sum += Math.pow(-x,m)*Factorial(n+k)/Factorial(n-m)/Factorial(k+m)/Factorial(m);
    }
    return sum;
  }
</pre>

<br />

<h3>C言語</h3>
<p>
図を描画用にデータ出力用のプログラムです。

</p>
<pre class="brush: cpp">
/*
水素原子の波動関数（厳密解）
(2012.03.29 公開)
*/
#include &lt;math.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;
#include &lt;fstream&gt;
#include &lt;sstream&gt;
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;cstdio&gt;
#include &lt;iomanip&gt;
#include &lt;stdio.h&gt;
#include &lt;complex&gt;
#if defined(_OPENMP)
  #include &lt;omp.h&gt;
#endif
#if defined(_MSC_VER)
  #include &lt;direct.h&gt;   // Windowsフォルダ作成用
#elif defined(__GNUC__)
  #include &lt;sys/stat.h&gt; //  UNIX系ディレクトリ作成用
#endif
using namespace std;

double PI = acos(-1.0);
double Factorial(int n);
double Factorial(int n, int m);
const int n_max = 4;
const int kizami = 200;
const double L = 80.0;
double Laguerre( int k, int n, double x);           //ラゲール陪関数
double Legendre( int m, int l, double x);           //ルジャンドル陪関数

string folder = &quot;Hydrogen&quot;;//作成するフォルダ名


int main(){
  #if defined(_MSC_VER)
    _mkdir(folder.c_str());   // Windowsフォルダ作成
  #elif defined(__GNUC__)
    mkdir(folder.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); // UNIX系のディレクトリ作成
  #endif
  #if defined(_OPENMP)
    omp_set_num_threads(8);
    cout &lt;&lt; &quot;OpenMPを利用します（最大スレッド数：&quot;&lt;&lt; omp_get_max_threads() &lt;&lt; &quot;）&quot; &lt;&lt;  endl;
  #endif
  double r_min = 0.0;
  double r_max =  40.0;
  const int Z = 1;

  /*// 動径分布関数
  for(int n=1; n&lt;=n_max; n++)
  {
    for(int l=0; l&lt;n; l++)
    {
      for(int m=-l; m&lt;=l; m++)
      {
        char str[200];
        string str1;
        ofstream fout_s;
        sprintf(str, &quot;/R%d_%d_%d.data&quot;, n, l, m); str1 = folder + str; //動径方向
        fout_s.open(str1.c_str());
        for(int i=0; i&lt;=kizami*100; i++)
        {
          double x = r_min + (r_max-r_min)/double(kizami*100)*double(i);
          double R = 2.0/pow(double(n),2) * sqrt(Factorial(n-l-1)/Factorial(n+l)) * exp(-x/double(n)) * pow( 2.0*x/double(n),l) *Laguerre(2*l+1, n-l-1, 2.0*x/double(n))  ;
          fout_s &lt;&lt; x &lt;&lt; &quot; &quot; &lt;&lt; R &lt;&lt; endl;
        }
        fout_s.close();
      }
    }
  }
*/
  for(int n=1; n&lt;=n_max; n++)
  {
    for(int l=0; l&lt;n; l++)
    {
      for(int m=0; m&lt;=l; m++)
      {
        char str[200];
        string str1;
        ofstream fout_s;
        sprintf(str, &quot;/Psi%d_%d_%d.data&quot;, n, l, m); str1 = folder + str; //
        fout_s.open(str1.c_str());
        for(int ix=0; ix&lt;=kizami; ix++ )
        {
          for(int iy=0; iy&lt;=kizami; iy++ )
          {
            double x = - L/2.0 + L * double(ix)/double(kizami);
            double y = - L/2.0 + L * double(iy)/double(kizami);
            double z =0;
            double r = sqrt(pow(x,2)+pow(y,2)+pow(z,2));
            double theta = acos(z/r);
            double phi;
            if(y&gt;=0) phi = acos(x/r);
            else phi = 2.0*PI - acos(x/r);
            if(r==0){
              theta = 0;
              phi = 0;
            }
            double R = 2.0/pow(double(n),2) * sqrt(Factorial(n-l-1)/Factorial(n+l)) * exp(-r/double(n)) * pow( 2.0*r/double(n),l) *Laguerre(2*l+1, n-l-1, 2.0*r/double(n))  ;
            double Y = pow(-1.0, m) * sqrt(double(l)+1.0/2.0) * Factorial(l-m)/Factorial(l+m) * Legendre(m,l,cos(theta));
            if(m==0) {
              fout_s &lt;&lt; x &lt;&lt; &quot; &quot; &lt;&lt; y &lt;&lt; &quot; &quot;  &lt;&lt; R * Y &lt;&lt; endl;
            }else{
              double Yx = Y * cos(double(m)*phi);
              double Yy = Y * sin(double(m)*phi);
              fout_s &lt;&lt; x &lt;&lt; &quot; &quot; &lt;&lt; y &lt;&lt; &quot; &quot;  &lt;&lt; R * Yx &lt;&lt; &quot; &quot; &lt;&lt; R * Yy &lt;&lt; endl ;
            }
          }
          fout_s &lt;&lt; &quot;&quot; &lt;&lt; endl;
        }
        fout_s.close();
      }
    }
  }
}
double Laguerre( int k, int n, double x)
{
  double sum=0;
  for(int m=0; m&lt;=n; m++){
    sum += pow(-x,m)*Factorial(n+k)/Factorial(n-m)/Factorial(k+m)/Factorial(m);
  }
  return sum;
}
double Legendre( int m, int l, double x)
{
  int mm = abs(m);
  if( mm&gt;l )  return 0;
  double r0, r1, r2;
    r0 = 0.0;
    r1 = pow(1.0-x*x, double(mm)/2.0) * Factorial(2*mm-1, 2);
    if( mm==l &amp;& m&gt;=0) return r1;
    if( mm==l &amp;& m&lt;0)  return r1 * pow(-1.0,mm) * Factorial(l-mm)/Factorial(l+mm) ;
    for(int ll = mm+1; ll&lt;=l; ll++ ){
      r2 = ((2.0*ll-1.0)*x*r1 - (ll+mm-1.0)*r0)/(ll-mm);
      r0 = r1;
      r1 = r2;
    }
  if(m&gt;=0) return r2;
  else return r2 * pow(-1.0,mm) * Factorial(l-mm)/Factorial(l+mm) ;
}
double Factorial(int n)
{
  if( n&lt;=0 ) return 1.0;
  double F = 1.0;
  for(int i=n; i&gt;=2; i--){
    F *= double(i);    
  }
  return F;
}
double Factorial(int n, int m)
{
  if( n&lt;=0 ) return 1.0;
  double F = 1.0;
  for(int i=n; i&gt;=2; i=i-m){
    F *= double(i);    
  }
  return F;
}
</pre>

<br />
<h3>gnuplotテンプレート</h3>
<p>
上のプログラムで出力したデータを用いて、gif描画用のgnuplotテンプレートです。
</p>
<pre>
set pm3d                           ## 3次元カラー表示
set pm3d map                       ## カラーマップ表示
set pm3d interpolate 5, 5          ## 補間
set ticslevel 10

set nokey
set tics font 'Times,14'
set size square

########################################################
## gif ファイル出力の場合 ##############################
########################################################
set terminal gif optimize size 600, 480
cb = 1                  ##&lt;---------カラーバーの指定
set cbrange[-cb:cb]
set palette defined ( -cb &quot;blue&quot; , 0 &quot;black&quot;, cb &quot;red&quot;)
L=5.2
set xr[-L:L]            ##&lt;---------描画x軸の範囲
set yr[-L:L]            ##&lt;---------描画y軸の範囲

set output 'Psi1_0_0.gif'
splot &quot;Psi1_0_0.data&quot; u 1:2:3 with pm3d

L=10                    
set xr[-L:L]            ##&lt;---------描画x軸の範囲
set yr[-L:L]            ##&lt;---------描画y軸の範囲
cb = 0.2                ##&lt;---------カラーバーの指定
set cbrange[-cb:cb]
set palette defined ( -cb &quot;blue&quot; , 0 &quot;black&quot;, cb &quot;red&quot;)

set output 'Psi2_0_0.gif'
splot &quot;Psi2_0_0.data&quot; u 1:2:3 with pm3d

cb = 0.1                ##&lt;---------カラーバーの指定
set cbrange[-cb:cb]
set palette defined ( -cb &quot;blue&quot; , 0 &quot;black&quot;, cb &quot;red&quot;)

set output 'Psi2_1_0.gif'
splot &quot;Psi2_1_0.data&quot; u 1:2:3 with pm3d

set output 'Psi2_1_x.gif'
splot &quot;Psi2_1_1.data&quot; u 1:2:3 with pm3d

set output 'Psi2_1_y.gif'
splot &quot;Psi2_1_1.data&quot; u 1:2:4 with pm3d

cb = 0.03               ##&lt;---------カラーバーの指定
set cbrange[-cb:cb]
set palette defined ( -cb &quot;blue&quot; , 0 &quot;black&quot;, cb &quot;red&quot;)
L=20
set xr[-L:L]            ##&lt;---------描画x軸の範囲
set yr[-L:L]            ##&lt;---------描画y軸の範囲

set output 'Psi3_0_0.gif'
splot &quot;Psi3_0_0.data&quot; u 1:2:3 with pm3d

set output 'Psi3_1_0.gif'
splot &quot;Psi3_1_0.data&quot; u 1:2:3 with pm3d

set output 'Psi3_1_x.gif'
splot &quot;Psi3_1_1.data&quot; u 1:2:3 with pm3d

set output 'Psi3_1_y.gif'
splot &quot;Psi3_1_1.data&quot; u 1:2:4 with pm3d


set output 'Psi3_2_0.gif'
splot &quot;Psi3_2_0.data&quot; u 1:2:3 with pm3d

cb = 0.01               ##&lt;---------カラーバーの指定
set cbrange[-cb:cb]
set palette defined ( -cb &quot;blue&quot; , 0 &quot;black&quot;, cb &quot;red&quot;)

set output 'Psi3_2_x.gif'
splot &quot;Psi3_2_1.data&quot; u 1:2:3 with pm3d

set output 'Psi3_2_y.gif'
splot &quot;Psi3_2_1.data&quot; u 1:2:4 with pm3d

set output 'Psi3_2_2x.gif'
splot &quot;Psi3_2_2.data&quot; u 1:2:3 with pm3d

set output 'Psi3_2_2y.gif'
splot &quot;Psi3_2_2.data&quot; u 1:2:4 with pm3d


L=30
set xr[-L:L]            ##&lt;---------描画x軸の範囲
set yr[-L:L]            ##&lt;---------描画y軸の範囲

cb = 0.02               ##&lt;---------カラーバーの指定
set cbrange[-cb:cb]
set palette defined ( -cb &quot;blue&quot; , 0 &quot;black&quot;, cb &quot;red&quot;)

set output 'Psi4_0_0.gif'
splot &quot;Psi4_0_0.data&quot; u 1:2:3 with pm3d

set output 'Psi4_1_0.gif'
splot &quot;Psi4_1_0.data&quot; u 1:2:3 with pm3d

set output 'Psi4_1_x.gif'
splot &quot;Psi4_1_1.data&quot; u 1:2:3 with pm3d

set output 'Psi4_1_y.gif'
splot &quot;Psi4_1_1.data&quot; u 1:2:4 with pm3d

set output 'Psi4_2_0.gif'
splot &quot;Psi4_2_0.data&quot; u 1:2:3 with pm3d

cb = 0.005
set cbrange[-cb:cb]
set palette defined ( -cb &quot;blue&quot; , 0 &quot;black&quot;, cb &quot;red&quot;)

set output 'Psi4_2_x.gif'
splot &quot;Psi4_2_1.data&quot; u 1:2:3 with pm3d

set output 'Psi4_2_y.gif'
splot &quot;Psi4_2_1.data&quot; u 1:2:4 with pm3d

set output 'Psi4_2_2x.gif'
splot &quot;Psi4_2_2.data&quot; u 1:2:3 with pm3d

set output 'Psi4_2_2y.gif'
splot &quot;Psi4_2_2.data&quot; u 1:2:4 with pm3d


L=40
set xr[-L:L]            ##&lt;---------描画x軸の範囲
set yr[-L:L]            ##&lt;---------描画y軸の範囲

set output 'Psi4_3_0.gif'
splot &quot;Psi4_3_0.data&quot; u 1:2:3 with pm3d

set output 'Psi4_3_x.gif'
splot &quot;Psi4_3_1.data&quot; u 1:2:3 with pm3d

set output 'Psi4_3_y.gif'
splot &quot;Psi4_3_1.data&quot; u 1:2:4 with pm3d


cb = 0.001
set cbrange[-cb:cb]
set palette defined ( -cb &quot;blue&quot; , 0 &quot;black&quot;, cb &quot;red&quot;)


set output 'Psi4_3_2x.gif'
splot &quot;Psi4_3_2.data&quot; u 1:2:3 with pm3d

set output 'Psi4_3_2y.gif'
splot &quot;Psi4_3_2.data&quot; u 1:2:4 with pm3d

set output 'Psi4_3_3x.gif'
splot &quot;Psi4_3_3.data&quot; u 1:2:3 with pm3d

set output 'Psi4_3_3y.gif'
splot &quot;Psi4_3_3.data&quot; u 1:2:4 with pm3d
</pre>

<p>
・<a href="http://www.natural-science.or.jp/sources/20120329.cpp" target="_blank">C++言語</a><br />
・<a href="http://www.natural-science.or.jp/sources/20120329.plt" target="_blank">gnuplotテンプレート</a><br />
・<a href="http://www.natural-science.or.jp/sources/20120329.ai" target="_blank">イラストレータ</a><br />
</p>
<br />

<h2>計算結果</h2>
<p>
上のgnuplot テンプレートで出力した gif データです。
<?php WriteEquation("z=0") ?>の平面での波動関数の振幅に比例する確率分布による点描画です。

</p>
<h3>主量子数：<?php WriteEquation("n=1") ?>（K殻）</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120328-n1.gif" alt="" />
</p>

<h3>主量子数：<?php WriteEquation("n=2") ?>（L殻）</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120328-n2.gif" alt="" />
</p>

<h3>主量子数：<?php WriteEquation("n=3") ?>（M殻）</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120328-n3.gif" alt="" />
</p>
<h3>主量子数：<?php WriteEquation("n=4") ?>（N殻）</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120328-n4.gif" alt="" />
</p>


<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="20120406-1.gif" src="http://www.natural-science.or.jp/images/20120406-1.gif" width="600" height="438" class="mt-image-none" style="" /></span>
-->
<!--
s
p_z, p_x, p_y
d_{3z^2-r^2}, d_{zx}, d_{yz}, d_{x^2-y^2}, d_{yz}
f_{z(5z^2-3r^2)}, f_{x(5z^2-r^2)},  f_{y(5z^2-r^2)},  f_{z(x^2-y^2)},  f_{xyz},  f_{x(x^2-3y^2)}, f_{y(3x^2-y^2)}
-->]]>
        
    </content>
</entry>

<entry>
    <title>トランジスタを用いたモータ駆動</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120405194530.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13054</id>

    <published>2012-04-05T10:45:30Z</published>
    <updated>2012-04-05T10:49:42Z</updated>

    <summary> トランジスタを用いた応用例を紹介する。 今回はトランジスタ(エミッタ接地、コレ...</summary>
    <author>
        <name>八重樫 和之</name>
        
    </author>
    
        <category term="センサーの開発" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="実験装置開発" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="エミッタ接地" label="エミッタ接地" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="トランジスタ" label="トランジスタ" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="モータ駆動" label="モータ駆動" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="電気回路" label="電気回路" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[
<p>
トランジスタを用いた応用例を紹介する。
今回はトランジスタ(エミッタ接地、コレクタ負荷)によるモータ駆動の回路を作成した。
さらに、入力端子にフォトインタラプタを用いることでライントレースロボットの基礎回路も作成してみた。
</p>

<h2>LEDを用いたエミッタ接地回路の動作チェック
</h2>
<p>
まず、トランジスタを用いたエミッタ接地回路の動作チェックをを行った。
下図のように、入力信号がonになるとLEDが点灯する回路を製作した。
</p>
<p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="yaegashi_20120405-1.gif" src="http://www.natural-science.or.jp/images/yaegashi_20120405-1.gif" width="535" height="264" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span>
</p>

<h2>トランジスタを用いたモータ駆動
</h2>
<p>
先ほどの回路のLEDをモータに置き換えた。
入力信号がonになると、モータが回転することを確認できた。
なお、トランジスタのコレクタ電流の最大規格によってはモータを駆動できないことがある。
今回は2SC1815というトランジスタを用いたが、このトランジスタでモータを駆動できない場合、コレクタ電流の最大規格が大きいトランジスタを用いる必要がある。
</p>

<p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="yaegashi_20120405-2.gif" src="http://www.natural-science.or.jp/images/yaegashi_20120405-2.gif" width="538" height="269" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span>
</p>

<h2>フォトインタラプタを用いたライントレースロボットの基礎回路
</h2>
<p>
先ほどの回路のうち、入力信号にフォトインタラプタを接続した。
フォトインタラプタとは、対向する発光部と受光部を持ち、発光部からの光を物体が遮るのを受光部で検出することによって、物体の有無や位置を判定するセンサである。
下図のように、フォトインタラプタに白紙を当てるとモータが回転するが、黒紙を当てるとモータが回転しないことが確認できた。
この回路を組み合わせることで、ライントレースロボットの回路へ応用することができる。
</p>
<p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="yaegashi_2012-04-05-3.gif" src="http://www.natural-science.or.jp/images/yaegashi_2012-04-05-3.gif" width="472" height="566" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span>
</p>
]]>
        
    </content>
</entry>

<entry>
    <title>エミッタ接地増幅回路の製作</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120404174915.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13052</id>

    <published>2012-04-04T08:49:15Z</published>
    <updated>2012-04-04T08:52:40Z</updated>

    <summary> トランジスタによる増幅回路の製作と動作チェックを行った。 今回は、トランジスタ...</summary>
    <author>
        <name>八重樫 和之</name>
        
    </author>
    
    <category term="トランジスタ" label="トランジスタ" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="電気回路" label="電気回路" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[
<p>
トランジスタによる増幅回路の製作と動作チェックを行った。
今回は、トランジスタのベース端子が入力、コレクタ端子が出力、エミッタ端子がグラウンドという、
エミッタ接地増幅回路を制作した。
コレクタ端子につながった抵抗とエミッタ端子につながった抵抗の比によって、入力電圧を何倍に増幅して出力するかが決まる。
今回の回路では、入力電圧を5倍に増幅した。
</p>

<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="yaegashi_20120404.gif" src="http://www.natural-science.or.jp/images/yaegashi_20120404.gif" width="533" height="750" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span>
</p>
<h2>参考文献</h2>
トランジスタ回路の設計[単行本](鈴木雅臣 著)]]>
        
    </content>
</entry>

<entry>
    <title>数値計算法概論常微分方程式の解法</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120323225814.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13050</id>

    <published>2012-03-23T13:58:14Z</published>
    <updated>2012-03-23T22:55:26Z</updated>

    <summary> 本稿は、コンピュータを用いた常微分方程式の数値計算に関するアルゴリズムの個人的...</summary>
    <author>
        <name>遠藤 理平</name>
        <uri>http://www.natural-science.or.jp/members/endo_rihei.php</uri>
    </author>
    
        <category term="計算物理学" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="アルゴリズム" label="アルゴリズム" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="常微分方程式" label="常微分方程式" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="数値計算" label="数値計算" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[
<p style="border:1px solid gray; padding:5px 10px">
本稿は、コンピュータを用いた常微分方程式の数値計算に関するアルゴリズムの個人的メモです。
数値計算に関する参考文献は図書やWEBなどで比較的簡単に入手可能で、それぞれ目的に合わせてまとめられていますが、
そもそもどんな手法が存在するのかを俯瞰するために網羅的に並べて、詳しく知りたい時のために引用文献を明記しました。
勉強する上で特に有用だったのが、専門家の方々がwww上で公開しているPDFファイルです。この場にて勝手に御礼申し上げます。<br />
※本稿の内容は、私の誤解やミスを含んでいない可能性は<span style="font-weight:600">絶無</span>です。
もしよろしければ、<a href="mailto:info@natural-science.or.jp">ご連絡</a>下さい。修正、コメントなどを追記いたします。
<!--ITの発展に伴い、暗黙知 → 形式知 → 集合知、そして知のコモディティ化が急速に進んでいることの恩恵を-->
</p>


<p>
常微分方程式の標準的な形式は
</p>
<div class="waku">
<div style="float:right">(1)</div>
<img src="http://www.natural-science.or.jp/images/20120319-55.gif" alt="" />
</div>
<p>
と表される。式(1)は１階の常微分方程式であるが、多階の常微分方程式の場合であっても階数に応じた変数を導入することで、１階の微分方程式の連立方程式に帰着される。つまり、式(1)を計算するための数値計算の手法（アルゴリズム）を確立することができれば、多階の常微分方程式も計算可能となるだけではなく、多変数による常微分方程式、偏微分方程式への応用も可能となる。
</p>
<p>
常微分方程式に限らずコンピュータで計算を行う場合、有限桁の精度で数値的に計算を行うことに起因する様々な問題が存在する<a href="#c17">[17]</a>。
その詳細は割愛するが、計算アルゴリズムは問題を克服しながら、これまで多くの方々によって開発されてきた。
計算アルゴリズムに必要な要件は「精度よく」「安全に」そして「簡単に」という点にあり、それぞれに利点と欠点が指摘されている。
本稿では、次に挙げる分類をもとに、常微分方程式を計算するアルゴリズムを概観することにします。
</p>

<h2>分類</h2>
<p>
常微分方程式を数値的に解くための計算アルゴリズムの一般的な分類を概観する。
その前に表記についてです。<?php WriteEquation("t=t_n") ?>と<?php WriteEquation("t=tn+h") ?>における<?php WriteEquation("x") ?>の値を
</p>
<div class="waku">
<div style="float:right">(2)</div>
<img src="http://www.natural-science.or.jp/images/20120319-56.gif" alt="" />
</div>
<p>
と表す。<?php WriteEquation("h") ?>は<?php WriteEquation("t") ?>の差分量とする。
</p>

<h3>段階数（step）</h3>
<p>
<?php WriteEquation("x_{n+1}") ?>を計算するアルゴリズムを
</p>
<div class="waku">
<div style="float:right">(3)</div>
<img src="http://www.natural-science.or.jp/images/20120319-58.gif" alt="" />
</div>
<p>
と表した場合、<?php WriteEquation("m") ?>を<em>段階数（step）</em>と呼ぶ。<br />
<?php WriteEquation("m=1") ?>（１段階式）の場合、<?php WriteEquation("x_{n+1}") ?>を決めるために必要な過去のデータは<?php WriteEquation("x_{n}") ?>だけとなるため、<?php WriteEquation("x_{0}") ?>を初期条件から与えることで任意の時刻の値を計算することができる（セルスタート可能と呼ぶ）（ルンゲクッタ型など）。<br />
一方、<?php WriteEquation("m \geq 2") ?>（多段階式）では、<?php WriteEquation("x_{1}") ?>を決めるために<?php WriteEquation("x_{0}") ?>だけでなく、より過去の情報<?php WriteEquation("x_{-1}, \, x_{-2} \, \cdots \, x_{-m+1} ") ?>が必要となるため、このアルゴリズム単独だけでは計算をスタートできない（セルスタート不可能）（アダムス型など）。
多段階式の計算アルゴリズムは、各ステップにおける関数の値を利用して補間（ラグランジュ・ニュートン補間）を行う。
</p>
<h3>段数（stage）</h3>
<p>
<?php WriteEquation("x_{n+1}") ?>を決定する際に<?php WriteEquation("f") ?>を評価する回数。計算量の目安となる。<br />
段数１：アダムス型の多段階式に多い。<br />
多段数：ルンゲ・クッタ型の１段階式に多い。<br />
</p>
<h3>次数（order）</h3>
<p>
コンピュータを用いた数値計算は、微分を差分で表現することから生じる誤差を含むことになる。
<?php WriteEquation("t_{n+1} = t_n + h") ?>とおき、計算アルゴリズム（差分式）による表式と
厳密解のテーラー展開から得られる表式
</p>
<div class="waku">
<div style="float:right">(4)</div>
<img src="http://www.natural-science.or.jp/images/20120319-57.gif" alt="" />
</div>
<p>
と比較して、低次から完全に一致する項数を<em>次数（order）</em>と呼ぶ。
次数が大きいほど厳密解と近いことを意味するため計算精度を表す指数となる。
</p>

<h3>陽的／陰的（explicit／implicit）</h3>
<p>
<?php WriteEquation("x_{n+1}") ?>を計算するアルゴリズムが
</p>
<div class="waku">
<div style="float:right">(5)</div>
<img src="http://www.natural-science.or.jp/images/20120319-59.gif" alt="" />
</div>
<p>
と表される場合、<em>陽的アルゴリズム</em>と呼ばれ、
</p>
<div class="waku">
<div style="float:right">(6)</div>
<img src="http://www.natural-science.or.jp/images/20120319-60.gif" alt="" />
</div>
<p>
と表される場合は<em>陰的アルゴリズム</em>と呼ばれる。
</p>

<p>
陽的アルゴリズムは、<?php WriteEquation("x_{n+1}") ?>を得るために必要な情報が、これまでに計算した<?php WriteEquation("x_i \ (i\leq n)") ?>だけである。順々に代入するだけで時間発展を計算することができる（直接代入法）。
一方、陰的アルゴリズムでは、<?php WriteEquation("x_{n+1}") ?>を計算するために、<?php WriteEquation("x_{n+1}") ?>が必要となり、単純に代入するだけでは<?php WriteEquation("x_{n+1}") ?>を計算することができない。別途、ニュートン法などを用いて非線形方程式を解く必要がある。
<br />
陽的→プログラミングしやすい<br />
陰的→硬い方程式でも安定的<br />
</p>

<h3>シンプレクティック性？</h3>
<p>
位相空間の幾何学的な構造を不変に保つ変換を<em>シンプレクティック変換</em>と呼ばれる。
ハミルトニアン力学系に適用した場合、エネルギーや角運動量などの物理量が保存することに対応し、正準変換はすべてシンプレクティック変換であることが知られている。

シンプレクティック変換に基づいたアルゴリズムを用いて保存系における物理量の計算を場合、保存されるべき保存量が、一定の範囲内で保存されることが保証される。
一方、シンプレクティック変換に基づかない計算アルゴリズムの場合には、<span style="font-weight:600">保存されるべき保存量が単調増加する</span>。
シンプレクティック変換に基づいた計算アルゴリズムを<em>シンプレクティック性</em>を満たすと呼ばれる。
つまり、保存系の物理量を計算する場合には特にシンプレクティック性を満たすアルゴリズムが非常に重要な役割を果たすことになる。<br />
<br />
シンプレクティック性○ → ベルレの方法、陰的ルンゲ・クッタ法　など<br />
シンプレクティック性× → 陽的ルンゲ・クッタ法、予測子・修正子法など<br />
<br />
欠点 → ステップごとに時間刻みを変えると保存量の保存が崩れる<a href="#c12">[12]</a>。
</p>

<h3>対称型？</h3>
<p>
m段階式の計算アルゴリズム
</p>
<div class="waku">
<div style="float:right">(7)</div>
<img src="http://www.natural-science.or.jp/images/20120319-61.gif" alt="" />
</div>
<p>
において、
</p>
<div class="waku">
<div style="float:right">(8)</div>
<img src="http://www.natural-science.or.jp/images/20120319-62.gif" alt="" />
</div>
<p>
が成り立つ場合<em>対称型</em>アルゴリズムであると呼ばれる。
つまり、対称型アルゴリズムでは時間反転対称性が満たされている（ただし丸め誤差により厳密には成り立たない）。
対称型の利点はシンプレクティック性と同様、保存量が一定の範囲内で保存される<a href="#c12">[12]</a>。
また、シンプレクティック性とは異なり、ステップごとに時間刻みを変えても保存量の保存が崩れないようにすることもできる<a href="#c12">[12]</a>。また、任意の物理量の誤差が最悪でも時間に比例しかしないことも示されている<a href="#c12">[12]</a>。
そのため、シンプレクティック変換に基づいたアルゴリズムよりもある意味でよい<a href="#c12">[12]</a>。

<br />
対称型○ → 安定性が非対称型に比べ飛躍的によい<a href="#c12">[12]</a>。
</p>

<h3>エルミート型</h3>
<p>
ラグランジュ・ニュートン補間で多段階式の計算アルゴリズムに対して、高階の導関数を利用して補間（エルミート補間）することで導出されるアルゴリズム<a href="#c13">[13]</a>。
導関数が簡単に導出することが出来る場合、多段階式解法やルンゲ・クッタ法に比べて、誤差項の係数がずっと小さいことが知られている<a href="#c13">[13]</a>。
</p>

<h3>安定性</h3>
<p>
コンピュータを用いた数値計算は精度が有限桁であるために、解析的には収束解存在していたとしても、数値的不安定性のために発散する可能性がある。
数値的不安定性は、<em>線形安定性解析</em>を利用することで定量化することができる。
線形安定性解析とは、写像力学における固定点の安定性を調べる手法の一つで、ある固定点近傍における振る舞いを支配するヤコビ行列の固有値と固有ベクトルを調べることである。振る舞いに主要な寄与を示すのは最大固有値の固有ベクトルで、最大固有値と固有ベクトルは写像に伴う拡大率と拡大軸のベクトルを表している。
厳密解近傍において、計算アルゴリズムによって計算した軌道の振る舞いを調べることによって数値的不安定性を解析することができる。
具体的には、任意の非線形方程式を原点周りで線形化した方程式である、テスト方程式と呼ばれる方程式
</p>
<div class="waku">
<div style="float:right">(9)</div>
<img src="http://www.natural-science.or.jp/images/20120319-63.gif" alt="" />
</div>
<p>
を用いて原点近傍の振る舞いを解析解と比較する。解析解は
</p>
<div class="waku">
<div style="float:right">(10)</div>
<img src="http://www.natural-science.or.jp/images/20120319-64.gif" alt="" />
</div>
<p>
となるので、
</p>
<div class="waku">
<div style="float:right">(11)</div>
<img src="http://www.natural-science.or.jp/images/20120319-67.gif" alt="" />
</div>
<p>
となる。一方、計算アルゴリズムをテスト方程式に適用して、<?php WriteEquation("x_{n+1}") ?>と<?php WriteEquation("x_{n}") ?>の比を導出すると
</p>
<div class="waku">
<div style="float:right">(12)</div>
<img src="http://www.natural-science.or.jp/images/20120319-66.gif" alt="" />
</div>
<p>
と表すことができる。ただし、<?php WriteEquation("R") ?>は<?php WriteEquation("z") ?>の多項式となる。
この比は各ステップごとの拡大率を表すことになる。
つまり、<?php WriteEquation("{\rm Re}{[\lambda]}<0") ?>の条件のもと、<?php WriteEquation("|R(z)| < 1 ") ?>を満たす<?php WriteEquation("z") ?>の領域が<em>安定性領域</em>と呼ばれ、安定的に計算するための時間刻み<?php WriteEquation("h") ?>の大きさを決める指針となる。
当然、計算アルゴリズムによって安定性領域は異なり、安定性領域が広いほど<?php WriteEquation("h") ?>を大きくとることが可能となり計算効率を格段に上げることが可能となる。つまり、アルゴリズムの良し悪しを判定する一つの指標を与えることになる。
</p>
<h4>A-安定</h4>
<p>
安定性領域が<?php WriteEquation("{\rm Re}{[z]}<0") ?>を満たす計算アルゴリズムは<em>A-安定</em>と呼ばれる。
A-安定のアルゴリズムの場合、<span style="font-weight:600">硬い方程式</span>に対しても安定的であることが示されている<a href="#c13">[13]</a>。
陰的ルンゲクッタ法の一部であるガウス・ルジャンドル法はすべての次数でA-安定であることが示されている<a href="#c13">[13]</a>。
</p>



<h2>ルンゲ・クッタの公式</h2>
<p>
常微分方程式を解く計算手法のもっとも一般的な手法。
<?php WriteEquation("f") ?>の値だけで高次近似を実現。
陽的、陰的どちらもあるが、一般的には陽的なものを指し、陽的４段４次の「古典的ルンゲ・クッタ公式」が最も有名。
系統的な導出により次数は無限に上げることができる。<br />
</p>

<h3>陽的ルンゲ・クッタ法</h3>
<p>
陽的ルンゲ・クッタ法とは<?php WriteEquation("x_{n+1}") ?>を決定するのに、<?php WriteEquation("t_n") ?>と<?php WriteEquation("x_n") ?>の近傍の複数地点における<?php WriteEquation("f") ?>を計算することで、高次を精度を実現する１段階多段式アルゴリズム。
具体的には
</p>
<div class="waku">
<div style="float:right">(13)</div>
<img src="http://www.natural-science.or.jp/images/20120319-1.gif" alt="" />
</div>
<p>
と表すことができ、
</p>
<div class="waku">
<div style="float:right">(14)</div>
<img src="http://www.natural-science.or.jp/images/20120319-2.gif" alt="" />
</div>
<p>
と形式的に表すことができる。
式(14)の係数<?php WriteEquation("\[a_i, \, b_i, \, c_i\}") ?>は求める精度と段数から決まる。
<?php WriteEquation("\[a_i, \, b_i, \, c_i\}") ?>与えられれば、<?php WriteEquation("x_n") ?>を用いて、<?php WriteEquation("k_1") ?>から<?php WriteEquation("k_p") ?>まで順に代入するだけで計算することができ、最終的に<?php WriteEquation("x_{n+1}") ?>が得られる。
係数<?php WriteEquation("\[a_i, \, b_i, \, c_i\}") ?>はアルゴリズムごとに異なり次のような表にまとめられる。
</p>
<div class="waku">
<div style="float:right">(15)</div>
<img src="http://www.natural-science.or.jp/images/20120319-3.gif" alt="" />
</div>

<h3>利点</h3>
<p>
・<span style="font-weight:600; color:red">アルゴリズムの実装が簡単</span><br />
・時間刻みの変更が容易。<br />
・セルスタート可能<a href="#c15">[15]</a><br />
・係数が有理数であるので丸め誤差が少ない（６段５位まで）<a href="#c12">[12]</a><br />
・４次の安定性領域が低次よりも広い<br />
</p>
<h3>欠点</h3>
<p>
・対称性×<br />
・シンプレクティック性×<a href="#c10">[10]</a><br />
　→たとえ安定領域であっても保存すべき量が単調増加する<br />
・陽的ルンゲ・クッタはＡ-安定ではない<a href="#c10">[13]</a><a href="#c20">[20]</a><br />
</p>

<table>
<tr>
<th>名称</th>
<th>テーブル</th>
<th>アルゴリズム</th>
</tr>
<tr>
<td>
オイラー法<br />
１段１次
</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-5.gif" alt="" />
</td>
<td>
<img src="http://www.natural-science.or.jp/images/20120319-4.gif" alt="" />
</td>
</tr>
<tr>
<td>
改良オイラー法<br />２段２次</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-7.gif" alt="" />
</td>
<td>
<img src="http://www.natural-science.or.jp/images/20120319-6.gif" alt="" />
</td>
</tr>
<tr>
<td>
修正オイラー法（ホイン法）<br />２段２次</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-9.gif" alt="" />
</td>

<td>
<img src="http://www.natural-science.or.jp/images/20120319-8.gif" alt="" />
</td>
</tr>

<tr>
<td>ホインの３次公式<br />３段３次</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-11.gif" alt="" />
</td>

<td>
<img src="http://www.natural-science.or.jp/images/20120319-10.gif" alt="" />
</td>
</tr>

<tr>
<td>クッタの３次公式<br />３段３次</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-13.gif" alt="" />
</td>
<td>
<img src="http://www.natural-science.or.jp/images/20120319-12.gif" alt="" />
</td>
</tr>

<tr>
<td>古典的ルンゲ・クッタ公式<br />４段４次
</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-15.gif" alt="" />
</td>
<td>
<img src="http://www.natural-science.or.jp/images/20120319-14.gif" alt="" />
</td>
</tr>
<tr>
<td>クッタ3/8公式<br />４段４次</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-17.gif" alt="" />
</td>
<td>
<img src="http://www.natural-science.or.jp/images/20120319-16.gif" alt="" />
</td>
</tr>
<tr>
<td>ルンゲ・クッタ・ギル公式</td>
<td colspan="2">メモリが少なくて済む<a href="#c3">[3]</a>
</td>
</tr>
</table>
<p>
・時間刻みを埋め込み型で調整 → ルンゲ・クッタ・フェルベルグ公式<a href="#c12">[12]</a>。<br />
・系統的導出と安定性が掲載<a href="#c3">[3]</a>。４次の丁寧な導出<a href="#c6">[6]</a>。
・精度５次以上の掲載<a href="#c7">[7]</a>（Mathematicaを利用）。<br />
・精度５次以上で安定領域がかなり狭くなる。<br />
・古典的ルンゲ・クッタ公式は４段の公式であるため、分子動力学のように力の計算が体部分を占める系では非常に非効率となるだけではなく、
シンプレクティック性を満たさないため応用には適さない<a href="#c10">[10]</a>。利用する場合は、少なくても刻み幅の適合化を行うべき<a href="#c10">[10]</a><br />
・５段５次、６段６次と同等の公式も提案されている<a href="#c8">[8]</a><br />
</p>

<h3>陰的ルンゲ・クッタ</h3>
<p>
陰的ルンゲ・クッタ法とは、陽的ルンゲ・クッタ法と同様に<?php WriteEquation("x_{n+1}") ?>を決定するのに、<?php WriteEquation("t_n") ?>と<?php WriteEquation("x_n") ?>の近傍の複数地点における<?php WriteEquation("f") ?>を計算することで、高次を精度を実現する１段階多段式アルゴリズムである。
<?php WriteEquation("k_1") ?>から<?php WriteEquation("k_p") ?>まで順に代入するだけで計算することができた陽的ルンゲ・クッタ法と異なり、
<?php WriteEquation("k_i") ?>を決めるのに<?php WriteEquation("k_i") ?>を利用するというアルゴリズムになっている。
具体的には
</p>
<div class="waku">
<div style="float:right">(16)</div>
<img src="http://www.natural-science.or.jp/images/20120319-20.gif" alt="" />
</div>
<p>
と形式的に表すことができる。そして一般的には<?php WriteEquation("k_i") ?>は式(16)で与えられる非線形方程式を解くことで得られる。
式(16)の係数<?php WriteEquation("\{a_i, \, b_i, \, c_i\}") ?>も、陽的の場合と同様に下の表のようにまとめられる。
</p>
<div class="waku">
<div style="float:right">(17)</div>
<img src="http://www.natural-science.or.jp/images/20120319-21.gif" alt="" />
</div>
<p>
「次数≦段数」である陽的な場合と異なり、陰的公式は「次数≧段数」を実現することができる。２段３次の既知の公式も多数知られている<a href="#c21">[21]</a>。
本稿では、陰的ルンゲ・クッタ法の中でも
式(16)の係数<?php WriteEquation("\{a_i, \, b_i, \}") ?>が
</p>
<div class="waku">
<div style="float:right">(18)</div>
<img src="http://www.natural-science.or.jp/images/20120319-22.gif" alt="" />
</div>
<p>
の条件を満たす特別な場合に絞る。式(18)は、少ない分点数で高精度の数値積分を行うガウス・ルジャンドル法と同様の概念を利用することで導出した条件で、式(18)を満たす陰的ルンゲ・クッタ法は<em>ガウス・ルジャンドル法</em>と呼ばれる。
式(18)は、陰的ルンゲ・クッタ法のうちシンプレクティック性と満たす計算アルゴリズムであることが示されている<a href="#c20">[20]</a>。
</p>

<h4>ガウス・ルジャンドル法の利点と欠点</h4>
<p>
【利点】<br />
・すべて１段階 → セルスタート可能<br />
・p段で2p次の精度を達成<a href="#c12">[12]</a><a href="#c20">[20]</a> → 計算量を減らせる<br />
・シンプレクティック性○<a href="#c13">[13]</a><a href="#c20">[20]</a><br />
・対称性○<a href="#c13">[13]</a><a href="#c20">[20]</a><br />
・安定性　→　A-安定<a href="#c13">[13]</a><a href="#c20">[20]</a><br />
・局所誤差　→　極小<a href="#c13">[13]</a>
<br />
【欠点】<br />
・<?php WriteEquation("k_i") ?>を計算する際に非線形方程式を解く必要がある<a href="#c13">[13]</a><a href="#c20">[20]</a><br />。
・埋め込み型公式が使えない。
</p>

<table>
<tr>
<th>名称</th>
<th>テーブル</th>
</tr>
<tr>
<td>
ガウス・ルジャンドル法<br />
１段２次
</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-23.gif" alt="" />
</td>
</tr>
<tr>
<td>
ガウス・ルジャンドル法<br />
２段４次
</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-24.gif" alt="" />
</td>
</tr>
<tr>
<td>
ガウス・ルジャンドル法<br />
３段６次
</td>
<td style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120319-25.gif" alt="" />
</td>
</tr>
</table>
<p>
「A-安定＋高精度＋シンプレクティック性」を兼ね備えるため、多くの場合で最良<a href="#c13">[13]</a>。
</p>


<h2>線形多段階法</h2>
<p>
<?php WriteEquation("x_{n+1}") ?>を得るために、<?php WriteEquation("x_n") ?>しか利用しないルンゲ・クッタ法と異なり、
<?php WriteEquation("x_{n},\, x_{n-1}, \, x_{n-2}\, \cdots") ?>とより過去の情報を利用して解く方法は多段階法と呼ばれる。
</p>
<h3>共通の利点と欠点</h3>
<h4>利点</h4>
<p>
・何次の精度でも比較的簡単に導くことができる<br />
・１ステップあたりの関数評価が１回で済む（１段）→　計算量が少なくてすむ<br />
・局所誤差が比較的小さい。<br />
</p>

<h4>欠点</h4>
<p>
・シンプレクティック性×<br />
・対称性×<br />
・安定性　→　A安定でない<br />
・次数を上げると安定領域が急激に狭くなる　→　予測子・修正子法である程度緩和可能<a href="#c3">[3]</a>。<br />
・セルスタート不可能　→　次数のあったルンゲ・クッタ法などを利用する必要がある<br />
・多段階式からくる真の解には現れない計算モードを必ず含む<a href="#c3">[3]</a>。<br />
</p>

<h3>中点則（２段階２次）</h3>
<p>
多段階法の最も単純な陽的公式。
</p>
<div class="waku">
<div style="float:right">(19)</div>
<img src="http://www.natural-science.or.jp/images/20120319-26.gif" alt="" />
</div>

<h3>アダムズ・バッシュフォース公式</h3>
<p>
・陽的公式<br />
詳細が<a href="#c3">[3]</a>に記述されている。
ラグランジュ補間で多項式で近似し積分を計算する。２次から４次の公式を上から記述する。
５次６次の公式は<a href="#c9">[9]</a>に記述されている。
</p>
<div class="waku">
<div style="float:right">(20)</div>
<img src="http://www.natural-science.or.jp/images/20120319-27.gif" alt="" />
</div>

<h3>アダムズ・ムルトン公式</h3>
<p>
・２次が台形公式<a href="#c12">[12]</a>。
・陰的公式<br />
・計算スタート時に情報が足らない。<br />
２次から４次の公式を上から記述する。
５次６次の公式は<a href="#c9">[9]</a>に記述されている。
</p>
<div class="waku">
<div style="float:right">(20)</div>
<img src="http://www.natural-science.or.jp/images/20120319-28.gif" alt="" />
</div>

<h3>予測子・修正子法</h3>
<p>


予測子：アダムズ・バッシュフォース公式（陽的）<br />
修正子：アダムズ・ムルトン公式（陰的）<br />
を利用したものをアダムズ法と呼ばれる<a href="#c3">[3]</a>。
<a href="#c15">[15]</a>に係数の表。
４次のアダムズ法は次の通り。
</p>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-29.gif" alt="" />
</div>
<h4>利点</h4>
<p>
・時間刻み間隔を簡単に変えられる<a href="#c12">[12]</a>。<br />
・誤差の評価が簡単<a href="#c12">[12]</a>。<br />
・自動的な精度制御も可能<a href="#c15">[15]</a>。<br />
・ルンゲ・クッタ法よりも高速<a href="#c12">[12]</a>。<br />
・収束するまで計算する必要はない。→１回で十分な精度<a href="#c12">[12]</a>。<br />
</p>
<h4>欠点</h4>
<p>
・安定領域が大きくない<a href="#c15">[15]</a>。<br />
・メモリが多く必要<a href="#c15">[15]</a>。<br />
・初期値の設定に難点　→　分子動力学シミュレーションの場合問題にならない<a href="#c15">[15]</a>。<br />
・ポテンシャルの不連続性に弱い<a href="#c15">[15]</a>。<br />
・力の不連続性に弱い<a href="#c15">[15]</a>。<br />
・力学と適合しない<br />
・ハミルトン系に適用する場合は、最適化の余地がある<a href="#c12">[12]</a><br />
</p>


<!--<h2>エルミート型公式</h2>
<p>
エルミート型公式は、線形多段階法のアダムス型公式の一つの一般化である[]。
</p>

<h3>ギヤーの公式</h3>
<p>
・１段<br />
・予測子・修正子法の改良版<a href="#c9">[9]</a><br />
<br />
欠点
・シンプレクティックでない<a href="#c10">[10]</a>
</p>

-->
<h2>シンプレクティック解法</h2>
<p>
先述の「分類：シンプレクティック性」でも触れたが、シンプレクティック解法とは、シンプレクティック変換に基づいたアルゴリズムである。
保存系における物理量の計算を場合、保存されるべき保存量が、一定の範囲内で保存されることが保証される。
これは保存系の物理シミュレーションで、長時間の計算を行う際に非常に有用となる。
ハミルトニアンの位置<?php WriteEquation("q") ?>と運動量<?php WriteEquation("q") ?>の依存性が分離できる場合、<span style="font-weight:600">陽的シンプレクティック解法</span>を導出することができる。一方、ハミルトニアンの位置<?php WriteEquation("q") ?>と運動量<?php WriteEquation("q") ?>の依存性が分離できない一般のハミルトニアンに対しては、先述した<strong>「ガウス・ルジャンドル法」が陰的シンプレクティック解法</strong>となる。
本節では、陽的シンプレクティック解法に話を絞る。
ハミルトニアンが
</p>
<div class="waku">
<div style="float:right">(21)</div>
<img src="http://www.natural-science.or.jp/images/20120319-30.gif" alt="" />
</div>
<p>
と分離される場合、正準方程式は
</p>
<div class="waku">
<div style="float:right">(22)</div>
<img src="http://www.natural-science.or.jp/images/20120319-31.gif" alt="" />
</div>
<p>
で与えられる。式(22)の<?php WriteEquation("F(q) ,\, G(p)") ?>は、計算アルゴリズムの見通しを良くするために導入した関数である。
時刻<?php WriteEquation("t=t_n") ?>の<?php WriteEquation("q_n") ?>と<?php WriteEquation("p_n") ?>を
</p>
<div class="waku">
<div style="float:right">(23)</div>
<img src="http://www.natural-science.or.jp/images/20120319-35.gif" alt="" />
</div>
<p>
と行列で表した場合に、正準方程式を利用して<?php WriteEquation("x_{n}") ?>から<?php WriteEquation("x_{n+1}") ?>に変換する変換則が
<span style="font-weight:600">シンプレクティック変換</span>と呼ばれ、
</p>
<div class="waku">
<div style="float:right">(24)</div>
<img src="http://www.natural-science.or.jp/images/20120319-32.gif" alt="" />
</div>
<p>
と表します。<?php WriteEquation("{\cal S}") ?>はシンプレクティック変換を表し、添字の<?php WriteEquation("h") ?>は時間刻み幅を表します。
<?php WriteEquation("{\cal S}") ?>は複数回の変換で
</p>
<div class="waku">
<div style="float:right">(25)</div>
<img src="http://www.natural-science.or.jp/images/20120319-33.gif" alt="" />
</div>
<p>
と「積」で表されます。一つ一つの<?php WriteEquation("{\cal S}_i") ?>は<?php WriteEquation("i") ?>番目のシンプレクティック変換を表す。さらに１つのシンプレクティック変換は、正準方程式に対応する２つの変換に分けられる。
</p>
<div class="waku">
<div style="float:right">(26)</div>
<img src="http://www.natural-science.or.jp/images/20120319-34.gif" alt="" />
</div>
<p>
ただし、<?php WriteEquation("{\cal S}_P^{\hat{b}_i}") ?>と<?php WriteEquation("{\cal S}_Q^{b_i}") ?>は
</p>
<div class="waku">
<div style="float:right">(27)</div>
<img src="http://www.natural-science.or.jp/images/20120319-36.gif" alt="" />
</div>
<p>
で定義される。式(26)の<?php WriteEquation("\hat{b}_i") ?>と<?php WriteEquation("\hat{b}_i") ?>が、変換に伴う位置と運動量の変化量を表し、<?php WriteEquation("\{ \hat{b}_i, \, \hat{b}_i \}") ?>の組み合わせでシンプレクティック変換に基づいた様々なアルゴリズムを構成することができる。具体的な導出例（ベルレ法との対応、４次６次の表式）<a href="#c15">[15]</a>。
</p>

<h4>特徴</h4>
<p>
<br />
・簡単。安定。保存量が保存<a href="#c15">[15]</a>。<br />
・誤差の判定法が簡単。１ステップあたりの平均誤差（<?php WriteEquation("\Delta=1/N\sum_i |E_{i+1}-E_{i}|") ?>）を計算<a href="#c16">[16]</a>。
・誤差が最悪でも時間に比例<a href="#c12">[12]</a>。<br />
・物理的保存量が保存される<a href="#c12">[12]</a>。<br />
・欠点→時間間隔を変えると上の性質が一般的に壊れる。<br />
・陽的：作用素文化に基づいた公式が広く使われる<a href="#c12">[12]</a>。→　リープフロッグのタイムステップを変えて組み合わせて高次を実現<br />
・リープフロッグは時間対称型なので、組み合わせも全て対称型となる。７段６位、１５段８次も導かれている<br />
・陽的：再帰的方法でいくらでも高次の公式を導出できるが、６次で１５段、８次で２７段と効率が悪い<a href="#c12">[12]</a><br />
・欠点→局所誤差が悪い（ルンゲ・クッタ悪い）<a href="#c12">[12]</a><br />
</p>

<h3>シンプレクティック　オイラー法（１段１次）</h3>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-37.gif" alt="" />
</div>
<table>
<tr>
<th>表</th>
<th>アルゴリズム</th>
</tr>
<tr>
<td><img src="http://www.natural-science.or.jp/images/20120319-38.gif" alt="" /></td>
<td><img src="http://www.natural-science.or.jp/images/20120319-39.gif" alt="" /></td>
</tr>
</table>

<h3>ベルレの方法（２段２次）</h3>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-41.gif" alt="" />
</div>
<table>
<tr>
<th>表</th>
<th>アルゴリズム</th>
</tr>
<tr>
<td><img src="http://www.natural-science.or.jp/images/20120319-40.gif" alt="" /></td>
<td><img src="http://www.natural-science.or.jp/images/20120319-42.gif" alt="" /></td>
</tr>
</table>
<p>
ベルレの方法は、単純明快で実装が簡単でかつシンプレクティック性<a href="#c10">[10]</a>かつ時間対称型<a href="#c12">[12]</a>を満たすため、非常に有用なアルゴリズムである。ベルレの方法と等価な方法については後述する。<br />
</p>
<p>
さらなる陽的シンプレクティック解法も示されている。
系統的に取り扱うために、式(26)に基づいたシンプレクティック変換を
</p>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-44.gif" alt="" />
</div>
<p>
と表す。
ただし、
</p>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-45.gif" alt="" />
</div>
<p>
である。
</p>
<h3>ルースの公式（３段３次）</h3>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-43.gif" alt="" />
</div>

<h3>サンス・セルナの公式（6段4次）</h3>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-46.gif" alt="" />
</div>


<h2>ベルレの方法</h2>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-47.gif" alt="" />
</div>
<p>
ベルレの法則は先述の通り、シンプレクティック解法の中で位置づけられるアルゴリズムであるが、
その簡便さから目的に合わせて柔軟に変更することができることから、様々なアルゴリズムが利用される。
</p>

<h3>位置ベルレの差分式</h3>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-48.gif" alt="" />
</div>

<h3>リープフロッグ差分式</h3>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-49.gif" alt="" />
</div>
<p>
・デメリット→エネルギー保存の値の誤差が、ベルレよりも１位悪い（<a href="#c10">[10]</a>）。<br />
</p>
<h3>速度ベルレ差分式</h3>
<div class="waku">
<img src="http://www.natural-science.or.jp/images/20120319-50.gif" alt="" />
</div>
<p>
・２階微分方程式を解く際に有用<a href="#c10">[10]</a><br />
・誤差：<?php WriteEquation("h^3") ?><br />
・シンプレクティック性<a href="#c10">[10]</a>かつ時間対称型<a href="#c12">[12]</a><br />
・デメリット→時間間隔を変えられない<a href="#c4">[10]</a><br />
</p>


<h2>その他のアルゴリズム</h2>
<h3>ヌメロフの公式</h3>
<p>
ヌメロフの公式は、常微分方程式が
</p>
<div class="waku">
<div style="float:right">(28)</div>
<img src="http://www.natural-science.or.jp/images/20120319-51.gif" alt="" />
</div>
<p>
の形をしているときに、非常に効率的かつ高精度（１段階＋１階＋５次）なアルゴリズムとなる<a href="#c10">[10]</a>。
元の<?php WriteEquation("x") ?>を
</p>
<div class="waku">
<div style="float:right">(29)</div>
<img src="http://www.natural-science.or.jp/images/20120319-52.gif" alt="" />
</div>
<p>
と変形することで
</p>
<div class="waku">
<div style="float:right">(30)</div>
<img src="http://www.natural-science.or.jp/images/20120319-53.gif" alt="" />
</div>
<p>
という簡単な漸化式となる。
逆変換
</p>
<div class="waku">
<div style="float:right">(30)</div>
<img src="http://www.natural-science.or.jp/images/20120319-54.gif" alt="" />
</div>
<p>
を行うことで、任意の時刻の<?php WriteEquation("x(t)") ?>を得ることができる。
</p>





<!--
<h2>陽的：Ruth４次<a href="#c12">[12]</a></h2>
<p>

</p>

<h2>陰的：陰的ガウス法<a href="#c12">[12]</a></h2>
<p>
いろんな意味（陽的で問題だった局所誤差も小さい）で最適<a href="#c12">[12]</a>。

</p>

<h2>物理系メモ</h2>
<p>
・重力多体系の場合、粒子の配置によて時間刻みを変える必要がある。→ 粒子ごとに時間刻みを変える必要あり<a href="#c12">[12]</a>。
　（分子動力学では必要なし）
</p>
<p>
<a href="#c15">[15]</a>で調和振動子を具体例として、ベルレ、予測子・修正子の実例が記述されている。
</p>

-->



<!--

<h2>方程式の解</h2>

<table>
<tr>
<th>名称</th>
<th>精度</th>
<th>利点</th>
<th>欠点</th>
<th>備考</th>
</tr>
<tr>
<td>２分法</td>
<td>１次収束（<?php WriteEquation("\epsilon^1") ?>）</td>
<td>安全確実に収束</td>
<td>収束が遅い</td>
<td></td>
</tr>
<tr>
<td>ニュートン法</td>
<td>２次収束（<?php WriteEquation("\epsilon^2") ?>）</td>
<td>収束が二分法よりも早い</td>
<td>初期値によっては収束しない</td>
<td>２分法と組み合わせて利用することで欠点を回避</td>
</tr>
<tr>
<td>デュラン・ケルナー法</td>
<td>３次収束（<?php WriteEquation("\epsilon^3") ?>）</td>
<td></td>
<td></td>
<td></td>
</tr>
</table>


<h2>数値積分法</h2>
<h2>ニュートン・コーツの公式</h2>
<table>
<tr>
<th>名称</th>
<th>精度</th>
<th>利点</th>
<th>欠点</th>
<th>備考</th>
</tr>
<tr>
<td>矩形法</td>
<td>
上限公式：誤差（<?php WriteEquation("1/N") ?>）に比例
下限公式：誤差（<?php WriteEquation("1/N") ?>）に比例
中点公式：誤差（<?php WriteEquation("1/N^2") ?>）に比例
</td>
<td></td>
<td></td>
<td>長方形で近似。誤差計算<a href="#c4">[4]</a>。</td>
</tr>
<tr>
<td>台形公式</td>
<td>誤差（<?php WriteEquation("1/N^2") ?>）に比例（矩形法中点公式の1/2）</td>
<td>簡単。積分範囲が<?php WriteEquation("[-\infty, \infty]") ?>で高精度</td>
<td></td>
<td>１次関数で近似。漸化式<a href="#c2">[2]</a>、誤差計算<a href="#c2">[4]</a>。</td>
</tr>
<tr>
<td>シンプソン法</td>
<td>誤差（<?php WriteEquation("1/N^4") ?>）に比例</td>
<td>簡単。積分範囲が<?php WriteEquation("[-\infty, \infty]") ?>で高精度</td>
<td></td>
<td>２次関数で近似。漸化式<a href="#c2">[2]</a>、誤差計算<a href="#c2">[4]</a>。</td>
</tr>
<tr>
<td>ブールの公式</td>
<td>誤差（<?php WriteEquation("1/N^6") ?>）に比例</td>
<td></td>
<td></td>
<td>４次関数で近似。</td>
</tr>

</table>

<h2>ガウス型積分公式</h2>
<p>
少ない点数で積分値を決める事ができる
ガウス・ルジャンドルの公式
</p>


<p>
分割数を<?php WriteEquation("N=2^n") ?>とし、<?php WriteEquation("n") ?>を順次増やしていく際の漸化式を導出することで効率的に計算する。
また漸化式は目的の桁数が変化しなくなった時に計算を終了する<a href="#c2">[2]</a>。
</p>

<h2>Double Exponential 法</h2>
<p>
端点に特異性のある積分や半無限区間の積分に強い。
反復型の自動プログラムも作成しやすい。
</p>
<table>
<tr>
<th>名称</th>
<th>精度</th>
<th>利点</th>
<th>欠点</th>
<th>備考</th>
</tr>
<tr>
<td>Double Exponential 法</td>
<td>誤差（<?php WriteEquation("e^{-N}") ?>）に比例</td>
<td></td>
<td></td>
<td></td>
</tr>
</table>

<p>
二重指数関数の詳細は<a href="#c5">[5]</a>に掲載
</p>
-->

<h2>まとめ</h2>
<p>
いろいろな文献を調べていて「<span style="font-weight:600">シンプレクティック性、対称性、A-安定</span>」の重要性を理解することができた。「<span style="font-weight:600; color:red">ガウス・ルジャンドル法</span>」は上記の条件をすべて満たすため、研究を行う上で非常に強力であると考えられる。ただし、<span style="font-weight:600;">陰的解法</span>であるため、非線形連立方程式をニュートン法をなどで解く必要がある。
一方、陽的ルンゲ・クッタ法は上記条件をひとつも満たさないため、導入するメリット実装の容易さ以外には無いように思える。
ただし、<?php WriteEquation("f(x)") ?>の変動が大きな領域が存在する場合には、細心の注意が必要となる（最低でも刻み幅の自動調整が必須）。
本稿で取り上げた以外にもまだたくさんある。<span style="font-weight:600;">ブリルシュ・ストア法</span>は、リチャードソン補外を用いて目的の精度を達成するまで反復するという手法である。それゆえ、次数という概念は存在しない。<a href="#c17">[17]</a>の著者はこの手法が最良であると言っているほどである。しかしながら、あまり文献などで触れられていないため利用されていないようである。
数値計算の世界のディープさを少し実感することができた。
また、ITの発展に伴い、暗黙知 → 形式知 → 集合知、そして知のコモディティ化が急速に進んでいることの恩恵を受けていることも、参考文献が簡単に手に入ることで実感することができた。
自分も微力ながら、知のコモディティ化に貢献したいと思っている。
</p>



<h2>参考文献</h2>
<p>
以下の参考文献リストの並び順は、本文での出現順あるいは重要度順ではなく、全くの順不同である。強いていうならば筆者が参考にした順である。
本文中で言及されていないものも含むため注意を要す。
</p>

<ul>
<li id="c1">[1] <a href="http://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%88%E3%83%B3%E3%83%BB%E3%82%B3%E3%83%BC%E3%83%84%E3%81%AE%E5%85%AC%E5%BC%8F" target="_blank">ニュートン・コーツの公式 - Wikipedia [WEB]</a></li>
<li id="c2">[2] <a href="http://ocw.kyoto-u.ac.jp/01-faculty-of-integrated-human-studies-jp/introduction-to-simulation/lecturenote" target="_blank">シミュレーション概論（講義ノート）[PDF]</a>（早川尚男 著）</li>
<li id="c3">[3] <a href="http://www.amazon.co.jp/gp/product/4130613057/ref=as_li_ss_tl?ie=UTF8&tag=yoggi-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4130613057" target="_blank">スペクトル法による数値計算入門 [単行本]</a>（石岡圭一 著）</li>
<li id="c4">[4] <a href="http://www.amazon.co.jp/gp/product/4254126670/ref=as_li_ss_tl?ie=UTF8&tag=yoggi-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4254126670" target="_blank">統計的データ解析のための数値計算法入門 [単行本]</a>（岩崎学 著）</li>
<li id="c5">[5] <a href="http://www.kurims.kyoto-u.ac.jp/~kyodo/kokyuroku/contents/pdf/1040-20.pdf" target="_blank">二重指数関数型変換のすすめ [PDF]</a>（森正武 著）</li>
<li id="c6">[6] <a href="http://ocw.kyoto-u.ac.jp/01-faculty-of-integrated-human-studies-jp/introduction-to-simulation/pdf/rk.pdf" target="_blank">Runge-Kutta 法についてのノート [PDF]</a>（早川尚男 著）</li>
<li id="c7">[7] <a href="http://www.330k.info/essay/Explicit-Runge-Kutta-Butcher-Tableau" target="_blank">陽的Runge-Kutta法のButcher tableau [WEB]</a>（330k.info 著）</li>
<li id="c8">[8] <a href="http://ci.nii.ac.jp/naid/110002724003" target="_blank">Runge-Kutta5段5次型と6段6次型の実用公式 [PDF]</a>（情報処理学会論文誌、小野令美, 戸田英雄 共著）</li>
<li id="c9">[9] <a href="http://www.amazon.co.jp/gp/product/4785315342/ref=as_li_ss_tl?ie=UTF8&tag=yoggi-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4785315342">分子シミュレーション―古典系から量子系手法まで [単行本]</a>（上田顕 著）</li>
<li id="c10">[10] <a href="http://www.amazon.co.jp/gp/product/4431710582/ref=as_li_ss_tl?ie=UTF8&tag=yoggi-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4431710582" target="_blank">計算物理学 [単行本]</a>（J．M．ティッセン 著、松田和典, 道廣嘉隆, 谷村吉隆, 高須昌子, 吉江友照（訳））</li>

<li id="c11">[11] <a href="http://next1.cc.it-hiroshima.ac.jp/" target="_blank">数学教育学習支援研究室 [WEB]</a></li>
<li id="c12">[12] <a href="http://www.cfca.nao.ac.jp/hpc/muv/text/makino_07.pdf" target="_blank">数値計算法の基礎 [PDF]</a>（牧野淳一郎 著）</li>
<li id="c13">[13] <a href="http://jun.artcompsci.org/kougi/system_suuri4_1999/overall.html" target="_blank">システム数理 [WEB, PDF]</a>（牧野淳一郎 著）</li>
<li id="c14">[14] <a href="http://www.amazon.co.jp/gp/product/4254130864/ref=as_li_ss_tl?ie=UTF8&tag=yoggi-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4254130864" target="_blank">計算物理学 基礎編 [単行本]</a>（Rubin H. Landau, Manuel Jose Paez Mejia (共著)、小柳 義夫, 春日隆, 狩野覚, 善甫康成 (訳））</li>
<li id="c15">[15] <a href="http://www.phys.keio.ac.jp/guidance/labs/riron/pdf/nosenote1.pdf" target="_blank">計算物理学特論 分子動力学シミュレーション、数値積分法 [PDF]</a>（能勢修一 著）</li>
<li id="c16">[16] <a href="http://www.phys.keio.ac.jp/guidance/labs/riron/pdf/nosenote3.pdf" target="_blank">分子動力学法入門 [PDF]</a>（能勢修一 著）</li>
<li id="c17">[17] <a href="http://www.amazon.co.jp/gp/product/4874085601/ref=as_li_ss_tl?ie=UTF8&tag=yoggi-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4874085601" target="_blank">ニューメリカルレシピ・イン・シー 日本語版―C言語による数値計算のレシピ [単行本]</a>（William H. Press, William T. Vetterling, Saul A. Teukolsky, Brian P. Flannery (共著)、 丹慶勝市, 佐藤俊郎, 奥村晴彦, 小林誠（訳）</li>

<li id="c18">[18] <a href="http://www.phys.keio.ac.jp/guidance/labs/riron/pdf/nosenote3.pdf" target="_blank">分子動力学法入門 [PDF]</a>（能勢修一 著）</li>
<li id="c19">[19] 
<a href="http://www.saiensu.co.jp/index.php?page=book_details&ISBN=ISBN4910054700916&YEAR=2001" target="_blank">「計算物理入門」～ 分子シミュレーションを中心に ～ [単行本]</a>（上田顕 著）</li>
<li id="c20">[20] 計算数理特論 [PDF]（三井斌友 著）<a href="http://www2.math.human.nagoya-u.ac.jp/~mitsui/syllabi/gs-is/cmp_math_title_pg.pdf" target="_blank">Title</a> <a href="http://www2.math.human.nagoya-u.ac.jp/~mitsui/syllabi/gs-is/cmp_math_chapt0.pdf" target="_blank">chapter0</a> <a href="http://www2.math.human.nagoya-u.ac.jp/~mitsui/syllabi/gs-is/cmp_math_chapt1.pdf" target="_blank">chapter1</a> <a href="http://www2.math.human.nagoya-u.ac.jp/~mitsui/syllabi/gs-is/cmp_math_chapt2.pdf" target="_blank">chapter2</a> <a href="http://www2.math.human.nagoya-u.ac.jp/~mitsui/syllabi/gs-is/cmp_math_chapt3.pdf" target="_blank">chapter3</a>
<!--http://www2.math.human.nagoya-u.ac.jp/~mitsui/syllabi/gs-is/--></li>
<li id="c21">[21] <a href="http://ci.nii.ac.jp/naid/110002721777" target="_blank">2段数陰的Runge-Kutta法について [PDF]</a>（情報処理学会論文誌、田中正次, 山下忠志, 山下茂 共著）</li>
<li id="c22">[22] <a href="http://en.wikipedia.org/wiki/List_of_Runge%E2%80%93Kutta_methods" target="_blank">List of Runge?Kutta methods [WEB]</a>（Wikipedia）</li>
<li id="c23">[23] <a href="http://na-inet.jp/nasoft/index.html" target="_blank">Numerical Computation as Software [PDF]</a>（幸谷智紀 著）</li>
<li id="c24">[24] <a href="http://www-cms.phys.s.u-tokyo.ac.jp/~naoki/CIPINTRO/" target="_blank">計算物理のためのC/C++言語入門 [WEB]</a>（渡辺尚貴 著）</li>
<li id="c25">[25] <a href="http://na-inet.jp/na/gsl.html" target="_blank">GNU Scientific Library Guide in Japanese [WEB]</a>（幸谷智紀 著）</li>
<li id="c26">[26] <a href="http://www.cbrc.jp/~tominaga/translations/gsl/" target="_blank">GSL reference manual Japanese translation [PDF]</a>（富永大介 著）</li>
<li id="c27">[27] <a href="http://pi2.cc.u-tokyo.ac.jp/~tnagai/index-j.html" target="_blank">ガウス・ルジャンドル法の係数（４倍精度）[WEB]</a>（永井貴博 氏）</li>

</ul>
<!--http://www.math.nagoya-u.ac.jp/~naito/lecture/
-->
<img src="http://www.assoc-amazon.jp/e/ir?t=yoggi-22&l=as2&o=9&a=4130613057" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<img src="http://www.assoc-amazon.jp/e/ir?t=yoggi-22&l=as2&o=9&a=4254126670" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<img src="http://www.assoc-amazon.jp/e/ir?t=yoggi-22&l=as2&o=9&a=4785315342" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<img src="http://www.assoc-amazon.jp/e/ir?t=yoggi-22&l=as2&o=9&a=4431710582" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<img src="http://www.assoc-amazon.jp/e/ir?t=yoggi-22&l=as2&o=9&a=4254130864" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
<img src="http://www.assoc-amazon.jp/e/ir?t=yoggi-22&l=as2&o=9&a=4874085601" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
]]>
        
    </content>
</entry>

<entry>
    <title>週末科学実験講座音ってそもそもなんだろう？～電子ピアノをつくろう～報告書</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120319151337.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13047</id>

    <published>2012-03-19T06:13:37Z</published>
    <updated>2012-03-19T06:20:00Z</updated>

    <summary> 本講座は１月１４日から３月３日の間、毎週土曜日の１３時から１５時まで、Five...</summary>
    <author>
        <name>渡辺 慶太郎</name>
        <uri>http://www.natural-science.or.jp/</uri>
    </author>
    
        <category term="入門編" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="報告" label="報告" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="週末科学講座" label="週末科学講座" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="音" label="音" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<p style="border:solid 1px gray; padding:10px 10px">
本講座は１月１４日から３月３日の間、毎週土曜日の１３時から１５時まで、FiveBridge（仙台市青葉区北目町４－７ HSGビル３F）において、全５名の参加者で行った。なお、授業に参加できなかった生徒には、翌週に２時間の補講を行った。
</p>

<h2>講座の目的</h2>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-1.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
本講座は、各部品や回路のはたらきを理解した上で、
音階をもつ電子ピアノの製作と調律を通じ、音階と波形の関係を目と耳で理解することを目的として行った。
</p>
<br class="c" />

<h2>本講座の具体的方法</h2>
<p>
上記の目的を達成するために、講座を次の４つのステップで実施した。
</p>

<h3>ステップ１：<br />
工具の使い方や作業環境の整理整頓など、ものづくりにあたっての心得を学ぶ（１回目）</h3>
<p>
・はんだごての高温部や鋭利な工具等、怪我の原因となる要素を認識する。<br />
・手元の作業スペースを常に確保し、危険を排除しつつはんだづけに集中できる環境をつくる。<br />
・電子工作の基本技術であるはんだづけの練習を行う。<br />
・配線を行うための、工具（ニッパー、ラジオペンチ）の使い方を学ぶ。<br />
</p>

<h3>ステップ２：<br />
電子ピアノの構成部品のはたらきを知り、電子ピアノの動作原理を理解する（２～４回目）</h3>
<p>
・２回目：抵抗が電流を制限するはたらきを、数種類の抵抗とLEDを用いた回路により目で理解する。<br />
・３回目：ICがもつ、電流のON/OFFを切り替えるはたらきを目で理解するために、LEDの点滅回路をつくる。さらに、抵抗を入れ替えることで、その点滅速度（周波数）が変化することを理解する。<br />
・４回目：スピーカーがもつ、電流のON/OFFを音に変えるはたらきを耳で実感するために、ブザー回路をつくる。3回目までに得られた知識をもとに、ブザーの音の高さを変化させられることを理解する。<br />
・５回目（前半）：半固定抵抗の抵抗値を調整できるというはたらきを、LED点灯回路により目で理解する。<br />
</p>

<h3>ステップ３：<br />
音階をもつ電子ピアノを製作する（５,６回目）</h3>
<p>
・1～4回目までに得られた知識や技術を応用し、電子ピアノ製作を行う。
</p>
<h3>ステップ４：<br />
音階と波形の関係を目と耳で理解する（７,８回目）</h3>
<p>
・７回目：耳による調律を行い、人間の聴覚だけに頼った調律の精度を実感する。<br />
・８回目：オシロスコープを用いて調律を行い、波形と周波数（音の高さ）の関係を理解する。また、人間の聴覚に頼った調律と機械を利用した調律の精度を比較する。
</p>




<br />
<h2>本講座で使用した電子ピアノのしくみ</h2>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-2.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
　本講座のために設計した電子ピアノの動作原理は、ICに抵抗とコンデンサをつないだ発振回路から発生させた電気信号を、スピーカーにより音に変換する、というものである。<br />
　電子ピアノの音の高さは、抵抗値とコンデンサの容量により決めることができる。
</p>

<br />
<h2>本講座の実施内容</h2>
<h3>１回目</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-3.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
　はんだづけの練習と工具の扱い方、そして電子工作をする上での作業環境について実践的に学んだ。また、その学習内容を確認するために、LEDライトを製作した。<br />
　受講者は初め工具の扱い方に苦戦していたが、最後にはLEDライトを全員完成させることができた。
</p>
<br class="c" />

<h3>２回目</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-4.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
　抵抗の電流を制限するはたらきを、複数の種類の抵抗を用いた回路で学んだ。また、スイッチのはたらきを学んだ。<br />
　抵抗のはたらきを理解するための回路は全員が完成させることができた。スイッチのはたらきを理解する回路は時間内では１名完成させることができなかったが、予備の回路を用いることで理解してもらうことができた。<br />
</p>
<br class="c" />

<h3>３回目</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-5.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
　ICのはたらきを学んだ。回路には受講者によって違う種類の抵抗を用い、お互いの回路を見比べることで、抵抗値が大きくなるとLEDの点滅速度が遅くなるという関係を目で見ることで実感した。<br />
　回路は時間内では２名完成することができなかったが、他の受講生の回路を用いてはたらきを理解することができた。
</p>
<br class="c" />

<h3>４回目</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-6.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
　スピーカーのはたらきを学ぶためにブザー回路を製作した。そのため、３回目のLED点滅回路のLEDをスピーカーに交換するとスピーカーから音が生じる。<br />
<br />
　音の高さはICにつなぐ抵抗の値できまる。そこで、耳で聴いたスピーカーの音から抵抗値を予想するゲームを行い、抵抗値が大きくなるとブザーの音が低くなることを耳で実感した。ゲームの正解率は人により異なっていたが、抵抗値と音の高さの関係については全員が理解することができた。
</p>
<br class="c" />

<h3>５回目</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-7.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
　半固定抵抗のはたらきを学ぶ回路を製作し、配布した回路図および配線図をもとに電子ピアノの製作を行った。 受講者はこれまでに得た知識や技術を活かし、電子ピアノの製作を順調に行っていた。
</p>
<br class="c" />

<h3>６回目</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-8.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
　前回に引き続き、配布した回路図および配線図をもとに電子ピアノの製作を行った。受講者のうち、欠席した１名を除いた全員が電子ピアノをスムーズに完成させることができた。
</p>
<br class="c" />

<h3>７回目</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-9.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
　電子ピアノの耳による調律を行った。受講者は、全員十分な時間をかけて調律に取り組み、人間の感覚に基づいた調律の難しさを実感してもらった。
</p>
<br class="c" />

<h3>８回目</h3>
<p>
<img src="http://www.natural-science.or.jp/images/20120319-10.jpg" alt="" style="float:right; margin:0px 0px 20px 20px" />
　オシロスコープに電子ピアノを接続して調律を行い、音階が高くなるとオシロスコープに現れる波の数が増えるということを目で見て実感した。<br />
　全回出席していた受講者は、全員がこのことを実感することができ、調律の結果納得のいく音を出すことができた。
また、欠席した回のあった受講者1名についても、この日までに電子ピアノ回路を完成させ、音階と波形の関係について理解してもらうことができた。
</p>
<br class="c" />


<h2>本講座のまとめ</h2>
<p>
　８回目に受講者全員が電子ピアノの調律を独力で成功させることができたことから、受講者全員が本講座の目的である音階と波形の関係の理解をすることができたといえる。<br />
　また、特に４回目の抵抗当てゲームや、７・８回目の授業においては、講師が指示をしなくても受講者が互いに声を掛け合いながら課題に取り組む姿が見られた。協力の重要性を自ら発見してくれたという予想以上の意義がある講座であった。
</p>

<h2>本講座の課題と今後に向けて</h2>
<p>
①３回目の回路の故障などのトラブルは、半田づけの技術習得が１回目に充分にできていなかったためだと考えられる。２回目以降にも半田づけの練習を取り入れるなどして、さらに技術の基礎を固めさせたい。<br />
<br />
②電子工作の経験者は課題をこなすスピードが速かったため、経験者向けの発展課題をより多く準備しておくと幅広い層の受講者を迎えることができるのではないかと思った。
</p>


<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="tanki8.jpg" src="http://www.natural-science.or.jp/images/tanki8.gif" width="168" height="159" class="mt-image-none" style="" /></span>
-->
]]>
        
    </content>
</entry>

<entry>
    <title>HTML5による物理シミュレーション環境の構築点電荷による電気力線シミュレータ</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120311222045.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13045</id>

    <published>2012-03-11T13:20:45Z</published>
    <updated>2012-03-12T01:10:53Z</updated>

    <summary> HTML5の新要素 canvas 要素に WebGL（Three.js）＋Ja...</summary>
    <author>
        <name>遠藤 理平</name>
        <uri>http://www.natural-science.or.jp/members/endo_rihei.php</uri>
    </author>
    
        <category term="WebGL" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="仮想物理実験室" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="c" label="C++" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="html5" label="HTML5" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="threejs" label="Three.js" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="点電荷" label="点電荷" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="物理シミュレーション" label="物理シミュレーション" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="電気力線" label="電気力線" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<p>
HTML5の新要素 canvas 要素に WebGL（Three.js）＋Javascript を利用して構築する物理シミュレータの第２弾として、「<a href="http://www.natural-science.or.jp/WebGL/ElectricalFluxLine_ver0.1.html" target="_blank">点電荷による電気力線の描画シミュレータ</a>」を公開します。
４つの点電荷の各「電荷と座標」を任意に指定することができます。その際の電気力線を描画します。下記の図はシミュレータのデモ画面です。
</p>
<p style="text-align:center">
<span style="font-weight:600; font-size:x-small; color:red">以下の図はデモ画面です</span> → <a href="http://www.natural-science.or.jp/WebGL/ElectricalFluxLine_ver0.1.html" target="_blank" style="font-weight:600; font-size:x-small;">実行ページこちら</a><br /><br />
<a href="http://www.natural-science.or.jp/WebGL/ElectricalFluxLine_ver0.1.html" target="_blank"><img src="http://www.natural-science.or.jp/images/20120311-4.gif" alt="" /></a>
</p>
<br />

<h2>計算アルゴリズム</h2>
<p>
そもそも電気力線とは、電気力を視覚的に表現するために導入された<span style="font-weight:600">仮想的な線</span>のことです。
電気力線の一般的な特徴は次のとおりです。<br />
<br />
（１）<span style="font-weight:600; color:red">正の電荷</span>から<span style="font-weight:600; color:blue">負の電荷</span>に向けて<strong>電場の向き</strong>を沿う。<br />
（２）途中で途切れたり交差したりせず、正の点電荷から無限遠へ、逆に負の電荷にむけて無限遠から電気力線が到達する。<br />
（３）電場が強いほど、電気力線の密度が高い。<br />
<br />
電気力線は電場の空間依存性から計算することができるわけですが、
電気力線を<?php WriteEquation("\mathbf{l}(s)") ?>、電場を<?php WriteEquation("\mathbf{E}(\mathbf{r})") ?>と表した場合、
</p>
<div class="waku">
<div style="float:right">(1)</div>
<img src="http://www.natural-science.or.jp/images/20120311-2.gif" alt="" />
</div>
<p>
の関係があります。<?php WriteEquation("s") ?>は１次元的な電気力線の位置を表す媒介変数となります。
式(1)からコンピュータで計算するためのアルゴリズムは、
</p>
<div class="waku">
<div style="float:right">(2)</div>
<img src="http://www.natural-science.or.jp/images/20120311-3.gif" alt="" />
</div>
<p>
となります。式(2)を図示したのが下図です。
</p>
<p style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120311-1.gif" alt="" />
</p>
<p>
式(1)→(2)の導出はオイラー法として知られる差分法となります。
空間上の任意の点<?php WriteEquation("\mathbf{l}(s)") ?>とその位置における電場が得られると、電気力線の次の位置を決めることができます。点電荷でつくられる電場は、各点電荷によるクーロンの法則の重ねあわせで厳密に計算することができます。
</p>
<div class="waku">
<div style="float:right">(3)</div>
<img src="http://www.natural-science.or.jp/images/20120311-5.gif" alt="" />
</div>
<p>
つまり、<span style="font-weight:600">厳密</span>に得られる電場の空間分布から式(2)を用いて、<span style="font-weight:600">近似的</span>に電気力線を計算することができるわけです。ただし、
本稿で作成した電気力線シミュレータは、厳密な意味で電気力線ではありません。
その理由は、<br />
<br />
（１）電荷の大きさと、電気力線の本数を関連付けしていない<br />
（２）正の点電荷からだけではなく、負の点電荷からも電気力線を延ばしている。<br />
（３）電場が「０」になる所で<span style="font-weight:600">交わる</span>ことがある。<br />
<br />
ためです。
上記（１）は単純に描画結果を単純化するためです。（２）は負の点電荷に無限遠から流入する電気力線を表現するためです。
もちろん負の点電荷の場合、式(2)の電場の符号は「-」になります。
（３）についてですが、点電荷が生み出す電場が打ち消しあい「０」となる点が存在します（例えば、正の点電荷が２つだけ並んでいる場合のちょうど中間地点など）。電気力線を描画する際の初期点によってはその電場「０」の地点に向かうものもあり、その点が電気力線の終点となります。その点に向かう線が複数存在した場合、終点となるその点で交わることになります。
つまり、電気力線の描画ルール「交わらない、途切れない」に違反することになります。
しかしながら、もともと電気力線は電場の流れを可視化するために導入された手法なので、
ルール違反があっても物理的には間違いはありません。
</p>

<br />
<h2>スクリーンショット</h2>
<p style="text-align:center">
<img src="http://www.natural-science.or.jp/images/20120310-1.gif" alt="" style="width:300px" />
<img src="http://www.natural-science.or.jp/images/20120310-2.gif" alt="" style="width:300px" />
<img src="http://www.natural-science.or.jp/images/20120310-3.gif" alt="" style="width:300px" />
<img src="http://www.natural-science.or.jp/images/20120310-4.gif" alt="" style="width:300px" />
</p>
<br />

<h2>Javascript プログラムソース</h2>
<pre class="brush: js;">
  var PI = Math.PI;
  var e = Math.E;
  var c = 2.99792458E+8;
  var mu0 = 4.0*PI*1.0E-7;
  var epsilon0 = 1.0/(4.0*PI*c*c)*1.0E+7;
  var e0 = 1.60217733 * 1.0E-19;
  
  var Lx=100, Ly=100, Lz=0;
  var dz = 1.0E-6; //空間刻み幅
  
  //////////////////////////////////////
  //点電荷の設定
  /////////////////////////////////////
  var ElectricCharge = function(charge, x, y, z){
    this.charge = charge;
    this.x = x;
    this.y = y;
    this.z = z;
    this.flag = true;
  }
  var N_EC = 4; //点電荷の個数
  var ECs = new Array();
  ECs[0] = new ElectricCharge (1.0*e0, -10*dz, -10*dz, 0 );
  ECs[1] = new ElectricCharge (-1.0*e0,  10*dz, -10*dz, 0 );
  ECs[2] = new ElectricCharge (-1.0*e0, -10*dz,  10*dz, 0 );
  ECs[3] = new ElectricCharge (1.0*e0,  10*dz, 10*dz, 0 );  
  var N_EF   = 20000; //電気力線のステップ数
  var N_Skip = 100;   //データ出力間引き数
  var N_D    = 100;   //電気力線計算時の単位長さあたりの刻み幅  
  var N_EF_V = 6;     //緯度方向の分割数
  var N_EF_H = 18;   //経度方向の分割数
  var n_step = N_EF/N_D; //電気力線１本値のデータ数
  var n_line = N_EF_V*N_EF_H;//１電荷あたりの電気力線の本数
  /////////////////////////////////////////////////////////////////////////////
  //計算結果を記録用３次元配列を定義
  var Lines;
  function initLine(){
    Lines = new Array(N_EC); 
    for (var i = 0; i &lt; N_EC; i++)
      Lines[i] = new Array(n_line);
    for (var i = 0; i &lt; N_EC; i++)
      for (var j = 0; j &lt; n_line; j++)
        Lines[i][j] = new Array();
  }
  var $id = function(id) { return document.getElementById(id); }
  function init(){
    initLine();
    for(var i=0; i&lt;N_EC; i++){
      $id(&quot;e&quot;+i+&quot;c&quot;).value = ECs[i].charge/e0;
      $id(&quot;e&quot;+i+&quot;x&quot;).value = ECs[i].x/dz;
      $id(&quot;e&quot;+i+&quot;y&quot;).value = ECs[i].y/dz;
      $id(&quot;e&quot;+i+&quot;z&quot;).value = ECs[i].z/dz;    
    }
  }
  function restart(){
    initLine();
    for(var i=0; i&lt;N_EC*n_line; i++){
      scene.remove( lines[i] );
    }
    for(var i=0; i&lt;N_EC; i++){
      scene.remove( balls[i] );
      ECs[i] = { charge: parseFloat($id(&quot;e&quot;+i+&quot;c&quot;).value)*e0, 
          x:parseFloat($id(&quot;e&quot;+i+&quot;x&quot;).value)*dz, 
          y:parseFloat($id(&quot;e&quot;+i+&quot;y&quot;).value)*dz, 
          z:parseFloat($id(&quot;e&quot;+i+&quot;z&quot;).value)*dz,
          flag: $id(&quot;e&quot;+i+&quot;i&quot;).checked }
    }
    initObject();
  }
  function culStart(){  
    ////////////////////////////////////////////////////////////////////////////
    for(var q=0; q&lt;N_EC; q++){//各点電荷
      if(!ECs[q].flag) continue;
      var ll=0;
      for(var n_theta=0; n_theta&lt;N_EF_V; n_theta++){
        var theta = PI/N_EF_V * n_theta;
        var n_EF_H = parseInt(N_EF_H * Math.abs(Math.sin(theta)));//経度方向の分割数を緯度によって変える
        if(n_EF_H%2==1) n_EF_H++;  //奇数→偶数
        if(n_EF_H == 0) n_EF_H =1; //0だとまずいので
        for(var n_phi=0; n_phi&lt;n_EF_H; n_phi++){
          ll++;      
          var phi = 2.0*PI/n_EF_H * n_phi ;
          var ELine_x, ELine_y, ELine_z;
          ELine_x = ECs[q].x + dz * Math.sin(theta) * Math.cos(phi);
          ELine_y = ECs[q].y + dz * Math.sin(theta) * Math.sin(phi);
          ELine_z = ECs[q].z + dz * Math.cos(theta);
          Lines[q][ll-1][0] = {x:ELine_x/dz, y:ELine_y/dz, z:ELine_z/dz};        
          OUT :
          for(var j=1; j&lt;=N_EF; j++){
            if(j%N_Skip==0) Lines[q][ll-1][j/N_Skip] = {x:ELine_x/dz, y:ELine_y/dz, z:ELine_z/dz};    
            var Ex =0, Ey = 0, Ez = 0, E_abs;
            for(var i=0; i&lt;N_EC; i++){
              if(!ECs[i].flag) continue;
              var R = Math.sqrt(Math.pow(ELine_x-ECs[i].x,2) + Math.pow(ELine_y-ECs[i].y,2) + Math.pow(ELine_z-ECs[i].z,2)); 
              Ex += ECs[i].charge/(4.0*PI*e0) * (ELine_x-ECs[i].x)/Math.pow(R,3);
              Ey += ECs[i].charge/(4.0*PI*e0) * (ELine_y-ECs[i].y)/Math.pow(R,3);
              Ez += ECs[i].charge/(4.0*PI*e0) * (ELine_z-ECs[i].z)/Math.pow(R,3);
            }
            E_abs = Math.sqrt(Math.pow(Ex,2)+Math.pow(Ey,2)+Math.pow(Ez,2));
            if(ECs[q].charge &gt; 0){
              ELine_x += Ex/E_abs *dz/N_D;
              ELine_y += Ey/E_abs *dz/N_D;
              ELine_z += Ez/E_abs *dz/N_D;
            }else{
              ELine_x -= Ex/E_abs *dz/100 ;
              ELine_y -= Ey/E_abs *dz/100 ;
              ELine_z -= Ez/E_abs *dz/100 ;
            }
            if(E_abs*e0&lt;1E-15) break;
            for(var i=0; i&lt;N_EC; i++) 
              if(Math.sqrt(Math.pow(ELine_x-ECs[i].x,2)+Math.pow(ELine_y-ECs[i].y,2)+Math.pow(ELine_z-ECs[i].z,2)) &lt; dz ) break OUT;//点電荷に到達したら終了
          }
        }
      }
    }
  }
  var width, height;
  var renderer;
  function initThree() {
    width = document.getElementById('canvas-frame').clientWidth;
    height = document.getElementById('canvas-frame').clientHeight;  
    try {renderer = new THREE.WebGLRenderer({antialias: true});} catch (e) {}  
    if(!renderer) document.getElementById(&quot;errer&quot;).innerHTML = '&lt;p style=&quot;text-align:center;font-size:small; color:red&quot;&gt;お使いの環境ではWebGLはご利用いただけません。&lt;br /&gt;WebGLに対応していない方のためにGIFファイルを以下に用意しました。&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;http://www.natural-science.or.jp/images/tutorial6.gif&quot; alt=&quot;WEBGLデモ&quot; /&gt;&lt;/p&gt;';
    renderer.setSize(width, height);
    document.getElementById('canvas-frame').appendChild(renderer.domElement);
    renderer.setClearColorHex(0x000000, 1.0);
  }
  
  var camera;
  function initCamera() {  
    camera = new THREE.PerspectiveCamera( 45 , width / height , 1 , 10000 );
    camera.up.x = 0;
    camera.up.y = 0;
    camera.up.z = 1;

  }
  var scene;
  function initScene() {    
    scene = new THREE.Scene();
  }
  var light, light2;
  function initLight() {
    light = new THREE.DirectionalLight(0xFFFFFF, 1.0, 0);
    light.position.set( 100, 100, 100 );
    scene.add(light);

    light2 = new THREE.AmbientLight(0x777777);
    scene.add(light2);
  }

  var lines = new Array();
  var balls = new Array();
  function initObject(){   
    culStart();  
    var ll=0;
    for (var i = 0; i &lt; N_EC; i++) {
      if(!ECs[i].flag) continue;
      for (var j = 0; j &lt; n_line; j++) {
        var geometry = new THREE.Geometry();
        for (var k = 0; k &lt; n_step; k++) {
          if(Lines[i][j][k] != undefined &amp;&amp; Lines[i][j][k] != undefined &amp;&amp; Lines[i][j][k] != undefined)
              geometry.vertices.push( new THREE.Vertex( new THREE.Vector3( Lines[i][j][k].x , Lines[i][j][k].y, Lines[i][j][k].z) ) );
          else break;
        }
        lines[ll] = new THREE.Line( geometry, new THREE.LineBasicMaterial( { color: &quot;0xFFFFFF&quot;, opacity:0.4} ) );
        scene.add( lines[ll] );//シーンに追加
        ll++;
      }
      //点電荷の描画
      var chargeColor;
      if(ECs[i].charge &lt; 0) chargeColor = &quot;0x0000FF&quot;;
      else chargeColor = &quot;0xFF0000&quot;;
      balls[i] = new THREE.Mesh(
        new THREE.SphereGeometry(ECs[i].charge/e0,20,20),
        new THREE.MeshLambertMaterial({color: chargeColor, ambient:chargeColor})
      );
      balls[i].position.set(ECs[i].x/dz, ECs[i].y/dz, ECs[i].z/dz);
      scene.add(balls[i]);
    }
  }

  function initEvent(){
    window.addEventListener(&quot;mousedown&quot;, onMousedown, false);
    window.addEventListener(&quot;mouseup&quot;, onMouseup, false);
    window.addEventListener(&quot;mousemove&quot;,  onMousemove, false);
    window.addEventListener(&quot;mousewheel&quot;, onMousewheel, false);
    window.addEventListener(&quot;dragover&quot;, onCancel, false);
    window.addEventListener(&quot;dragenter&quot;, onCancel, false);
    window.addEventListener(&quot;drop&quot;, onDropFile, false);
    $id(&quot;restartButton&quot;).addEventListener(&quot;click&quot;, restart, false);
    $id(&quot;outputButton&quot;).addEventListener(&quot;click&quot;, f_write, false);
  }

  function loop() {
    camera.position.set(cameraR*Math.sin(cameraTheta)*Math.cos(cameraPhi),
              cameraR*Math.sin(cameraTheta)*Math.sin(cameraPhi),
              cameraR*Math.cos(cameraTheta));
    renderer.clear();
    camera.lookAt( {x:0, y:0, z:0 } );    
    renderer.render(scene, camera);
    window.requestAnimationFrame(loop);
  }
  function threeStart() {
    initEvent();
    initThree();
    initCamera();
    initScene();    
    initLight();  
    initObject();
    loop();
  }

////マウスイベント////////////////////////////////////////////////////
  var down = false;
  var sy = 0, sz = 0;
  var cameraR = 100, cameraTheta =PI/4, cameraPhi =PI/2;
  function onMousedown (ev){  //マウスダウン時イベント
    if (ev.target == renderer.domElement) { 
      down = true;
      sy = ev.clientX; sz = ev.clientY;
    }
  };
  function onMouseup (){       //マウスアップ時イベント
    down = false; 
  };
  function onMousemove (ev) {  //マウスムーブ時イベント
    var speed = 0.01;
    if (down) {
      if (ev.target == renderer.domElement) { 
        var dy = -(ev.clientX - sy);
        var dz = -(ev.clientY - sz);
        cameraPhi += dy*speed;
        cameraTheta += dz*speed;
        sy -= dy;
        sz -= dz;
      }
    }
  }
  function onMousewheel(ev){//マウスホイール時イベント
    var speed = 0.1;    
    cameraR += ev.wheelDelta * speed ; 
  }
  var onDropFile = function(ev){         // ファイルドロップ時イベント
    ev.preventDefault();
    var file = ev.dataTransfer.files[0]; // File オブジェクトを取得
    readFile(file);                     // ファイル読み込み
  };
  var onCancel = function(ev){            // デフォル処理をキャンセル
    if(ev.preventDefault) { ev.preventDefault(); }
    return false;
  };
  function f_write(){
    var  str = &quot;&quot;;

    for (var i = 0; i &lt; N_EC; i++) {
      if(!ECs[i].flag) continue;
      for (var j = 0; j &lt; n_line; j++) {
        var geometry = new THREE.Geometry();
        for (var k = 0; k &lt; n_step; k++) {
          if(Lines[i][j][k] != undefined &amp;&amp; Lines[i][j][k] != undefined &amp;&amp; Lines[i][j][k] != undefined)
            str  +=  Lines[i][j][k].x  + &quot; &quot; + Lines[i][j][k].y  + &quot; &quot; + Lines[i][j][k].z  + &quot;\n&quot;;
          else break;
        }
        str  += &quot;\n&quot;;
      }
    }
    var blobBuilder;
    if (&quot;MozBlobBuilder&quot; in window) {
      blobBuilder = new MozBlobBuilder();
    } else if (&quot;WebKitBlobBuilder&quot; in window) {
      blobBuilder = new WebKitBlobBuilder();
    }
    blobBuilder.append(str);
    //var disp = document.getElementById(&quot;download&quot;);
    if (window.URL) {
      window.open(window.URL.createObjectURL(blobBuilder.getBlob()) , &quot;New Window&quot;, &quot;&quot;);
    } else if (window.webkitURL) {
      window.open(window.webkitURL.createObjectURL(blobBuilder.getBlob()), &quot;New Window&quot;, &quot;&quot;);          
    }
    //disp.innerHTML = 'ファイルがダウンロードされました （t='+ t +'）';
  }  
///////////////////////////////////////////////////////////////////////
window.onload = function(){
  init();
  threeStart();
}
</pre>
<br />
<h2>C言語プログラムソース</h2>
<p>
任意の点電荷分布に対する電気力線を計算するC言語のプログラムも合わせて公開しておきます。<br />
→<a href="http://www.natural-science.or.jp/sources/ElectricalFluxLine_ver0.1.cpp" target="_blank">ダウンロード（4kB）</a>
</p>








<h2>参考ページ</h2>
<p>
■ <a href="http://www.natural-science.or.jp/WebGL/DoublePendulum_ver1.0.html">HTML5による物理シミュレーション環境の構築 ～２重振子シミュレータ～</a><br />
■ <a href="http://www.natural-science.or.jp/article/20120220155529.php">HTML5による物理シミュレーション環境の構築 ～WebGLライブラリThree.js 入門（１／３）～</a><br />
■ <a href="http://www.natural-science.or.jp/article/20120225194735.php">HTML5による物理シミュレーション環境の構築 ～WebGLライブラリThree.js 入門（２／３）～</a><br />
■ <a href="http://www.natural-science.or.jp/article/20120302133233.php">HTML5による物理シミュレーション環境の構築 ～WebGLライブラリThree.js 入門（３／３）～</a><br />
</p>
<p>
ミスの指摘、質問やコメントなどがありましたら、お気軽に<a href="http://www.natural-science.or.jp/about/contact.php">こちら</a>まで、お願いいたします。
</p>
<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="20120311-4.gif" src="http://www.natural-science.or.jp/images/20120311-4.gif" width="500" height="362" class="mt-image-none" style="" /></span>
-->]]>
        
    </content>
</entry>

<entry>
    <title>Three.jsのバージョンアップの際の注意点（r47→r48）</title>
    <link rel="alternate" type="text/html" href="http://www.natural-science.or.jp/article/20120307161548.php" />
    <id>tag:www.natural-science.or.jp,2012://12.13042</id>

    <published>2012-03-07T07:15:48Z</published>
    <updated>2012-03-07T07:21:05Z</updated>

    <summary> Three.js とは現在開発が進んでいるHTML5のcanvas要素に描画す...</summary>
    <author>
        <name>遠藤 理平</name>
        <uri>http://www.natural-science.or.jp/members/endo_rihei.php</uri>
    </author>
    
        <category term="TIPS 集" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="threejs" label="Three.js" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="ja" xml:base="http://www.natural-science.or.jp/">
        <![CDATA[<p>
Three.js とは現在開発が進んでいるHTML5のcanvas要素に描画する際に便利なJavascript のライブラリです。
バージョンが上がる度に機能が追加されるので歓迎ですが、様々なパラメータのデフォルト値が変更されることがあるため注意も必要です。
３月４日に公開されたバージョン r48 では、材質の環境光に対する反射係数が変更されたため、環境光を利用しているときに見た目が変わる可能性があります。
</p>

<h4>r47（デフォルト値の変更前）</h4>
<pre>
ambient:0x050505
</pre>
<p style="text-align:center">
「<a href="http://www.natural-science.or.jp/WebGL/DoublePendulum_ver1.0.html" target="_blank">２重振子シミュレータ</a>」より<br />
<img src="http://www.natural-science.or.jp/images/20120307-2.gif" alt="" /><br />
</p>

<h4>r48（デフォルト値の変更後）</h4>
<pre>
ambient:0xffffff
</pre>
<p style="text-align:center">
「<a href="http://www.natural-science.or.jp/WebGL/DoublePendulum_ver1.0.html" target="_blank">２重振子シミュレータ</a>」より<br />
<img src="http://www.natural-science.or.jp/images/20120307-1.gif" alt="" /><br />
</p>
<p>
環境光（THREE.AmbientLight）を利用していて、材質に「ambient」を設定していない場合、描画は白っぽくなります。
バージョンアップに伴うパラメータのデフォルト値の変更はあまり無いようです。
詳しい変更点などは<a href="https://github.com/mrdoob/three.js/" target="_blank">本家ページ</a>をご覧下さい。
</p>

<!--
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="20120307-1.gif" src="http://www.natural-science.or.jp/images/20120307-1.gif" width="500" height="493" class="mt-image-none" style="" /></span>
-->]]>
        
    </content>
</entry>

</feed>

