<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sakef Blog</title>
	<atom:link href="http://sakef.jp/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://sakef.jp/blog</link>
	<description>Flash and Web Programming.</description>
	<lastBuildDate>Sun, 18 Sep 2011 10:11:07 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>YouTubeの動画をダウンロードするPHPスクリプト (2011/09)</title>
		<link>http://sakef.jp/blog/2011/09/youtube_dl_php3/</link>
		<comments>http://sakef.jp/blog/2011/09/youtube_dl_php3/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 10:11:07 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1400</guid>
		<description><![CDATA[YouTubeの動画のダウンロードスクリプトです(2011年9月時点)。 HTML内に複数サイズの動画のアドレスがあるので、全部取ってきて全部ダウンロードしてます。 久々にPHP書いた。]]></description>
			<content:encoded><![CDATA[<p>YouTubeの動画のダウンロードスクリプトです(2011年9月時点)。</p>
<p>HTML内に複数サイズの動画のアドレスがあるので、全部取ってきて全部ダウンロードしてます。</p>
<div class="paragraph2"></div>
<p>久々にPHP書いた。</p>
<p><span id="more-1400"></span></p>
<div class="paragraph"></div>
<pre class="brush: php; title: ; notranslate">
&lt;?php
// 動画のURL
$url = &quot;http://www.youtube.com/watch?v=NGQrE3fM8w8&quot;;

// 拡張子のリスト
$extension = array(&quot;5&quot; =&gt; &quot;.flv&quot;, &quot;18&quot; =&gt; &quot;.mp4&quot;, &quot;22&quot; =&gt; &quot;.mp4&quot;, &quot;34&quot; =&gt; &quot;.flv&quot;, &quot;35&quot; =&gt; &quot;.flv&quot;, &quot;37&quot; =&gt; &quot;.mp4&quot;, &quot;38&quot; =&gt; &quot;.mp4&quot;);

// HTMLファイルの取得
$html = file_get_contents($url);

// HTMLからタイトルを獲得する
preg_match(&quot;/&lt;meta name=\&quot;title\&quot; content=\&quot;([^\&quot;]*)\&quot;&gt;/s&quot;, $html, $matches);
$title = $matches[1];

// 動画URLの取得
preg_match(&quot;/url_encoded_fmt_stream_map=([^\&quot;]*)/i&quot;, $html, $matches);
$dataset = explode(&quot;%2C&quot;, $matches[1]);
for ($i = 0; $i &lt; count($dataset); $i++) {
    preg_match(&quot;/^url%3D(.*)/i&quot;, $dataset[$i], $matches);
    if (count($matches) != 0) {
        $flvs = explode(&quot;&amp;quality=&quot;, urldecode(urldecode($matches[1])));
        preg_match(&quot;/&amp;itag=(\d*)/i&quot;, $flvs[0], $itags);

        $video_url = $flvs[0];
        $itag = $itags[1];

        // 動画をDL
        if (isset($extension[$itag])) {
            echo &quot;title : $title\n&quot;;
            echo &quot;itag  : $itag\n&quot;;
            echo &quot;start  download.\n&quot;;

            $fp = fopen(mb_convert_encoding($title,&quot;sjis&quot;,&quot;auto&quot;).&quot;_fmt&quot; . $itag . $extension[$itag], &quot;wb&quot;);
            $handle = fopen($video_url, &quot;rb&quot;);
            while (!feof($handle)) fwrite($fp, fread($handle, 8192));
            echo &quot;finish download.\n\n&quot;;
        }
    }
}
?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/09/youtube_dl_php3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>「ActionScript Beautifl Code」にコードを掲載していただきました</title>
		<link>http://sakef.jp/blog/2011/06/as_beautifl_code/</link>
		<comments>http://sakef.jp/blog/2011/06/as_beautifl_code/#comments</comments>
		<pubDate>Sat, 11 Jun 2011 23:20:19 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[その他]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1394</guid>
		<description><![CDATA[ActionScript Beautifl Code～Beautifl: Flash Gallery of wonderfl～という本が発売になりました。 この本に、自分の書いたコードが載ったということで献本をいただきました。 今回掲載されたのは以下のコードです。 キラキラPixel3D！ &#8211; wonderfl build flash online コードのひとつひとつが丁寧に解説されていて、とても勉強になる本だと感じました。 興味のある方はぜひ！]]></description>
			<content:encoded><![CDATA[<p><img class = "img-style" src="http://sakef.jp/blog/blog_data/uploads/2011/06/p.jpg"/></p>
<div class="paragraph"></div>
<p><a href="http://www.amazon.co.jp/ActionScript-Beautifl-Code%E3%80%9CBeautifl-Gallery-wonderfl%E3%80%9C/dp/4862671098/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1307832848&#038;sr=8-1">ActionScript Beautifl Code～Beautifl: Flash Gallery of wonderfl～</a>という本が発売になりました。</p>
<p>この本に、自分の書いたコードが載ったということで献本をいただきました。</p>
<div class="paragraph"></div>
<p>今回掲載されたのは以下のコードです。</p>
<p><script type="text/javascript" src="http://wonderfl.net/blogparts/rwYK/js"></script>
<p class="ttlBpWonderfl" style="width: 465px; margin: 0; text-align: right; font-size: 11px;"><a href="http://wonderfl.net/c/rwYK" title="キラキラPixel3D！">キラキラPixel3D！ &#8211; wonderfl build flash online</a></p>
<div class="paragraph"></div>
<p>コードのひとつひとつが丁寧に解説されていて、とても勉強になる本だと感じました。</p>
<p>興味のある方はぜひ！</p>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/06/as_beautifl_code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>openFrameworksの環境構築 (Windows・VS2010)</title>
		<link>http://sakef.jp/blog/2011/06/of_vs2010/</link>
		<comments>http://sakef.jp/blog/2011/06/of_vs2010/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 01:09:40 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[C・C++]]></category>
		<category><![CDATA[openFrameworks]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1331</guid>
		<description><![CDATA[今更ですが、openFrameworks (oF)を触ってみました。 oFってのは、C/C++で描画したりインタラクティブなものを作るためのライブラリです。 OpenCVやBox2Dなどのライブラリも同梱されてる。 C++で描画が楽に出来るのはいいですよね。高速な処理もできるし。 今回は開発環境を作るまでを目標にやってみました。 1.本体をダウンロード まずは公式サイトからoF本体をダウンロード。 自分は普段VS2010を使ってるので、「windows visual studio 2010 FAT」ってのを選択しました。 あとは解凍して好きなところに置けばOK。 2.「emptyExample」を利用して新しいプロジェクトを作る 外部ライブラリをVS(VisualStudio)で利用する場合、普通はヘッダファイルやlibファイルのあるフォルダまでパスを通します。 ただ、oFはそのフォルダ数が多い。パス通すのめんどい。 補助ツールを公開してくれてる方もいましたが、VS2008用だったので使えず。 そこで今回は、「oF本体までの絶対パス\apps\examples」以下に置いてある、「emptyExample」をコピーして利用することに。 3.絶対パスを相対パスに書き換える emptyExampleに設定されているパスは全部相対パスです。 今回は自分の好きなところにプロジェクトを配置したいので、相対パスをすべて絶対パスに書き換えます。 まず、emptyExampleをコピーして好きなところに配置 (自分はVS2010のprojectフォルダに置きました)。 次に「 oF本体までの絶対パス\libs\openFrameworksCompiled\project\vs2010 」以下にあるopenframeworksLib.vcxprojをemptyExampleフォルダの中にコピー。 あとは設定ファイルを色々書き換えます。 emptyExample.slnは以下のように書き換えます。 5行目の「&#8221;..\..\..\libs\openFrameworksCompiled\project\vs2010\openframeworksLib.vcxproj&#8221;」を「&#8221;openframeworksLib.vcxproj&#8221;」に。 openframeworksLib.vcxprojは以下のように書き換えます。 すべての「..\..\..\..\」を「oF本体までの絶対パス\」に。 すべての「..\..\..\」を「oF本体までの絶対パス\libs\」に。 すべての「..\..\」を「oF本体までの絶対パス\libs\openFrameworksCompiled\」に。 emptyExample.vcxprojは以下のように書き換えます。 78行目の「xcopy /e /i /y &#8220;$(ProjectDir)..\..\..\export\vs2010\*.dll&#8221; &#8220;$(ProjectDir)bin&#8221;」を「xcopy /e /i /y &#8220;oF本体までの絶対パス\export\vs2010\*.dll&#8221; &#8220;$(ProjectDir)bin&#8221;」に。 すべての「..\..\..\」を「oF本体までの絶対パス\」に。 だいたいこんな感じで書き換えていきます。 4.テストしてみる 以下のサイトのサンプルを使わせていただきます。 openFrameworksで遊ぶ 01 » Every day [...]]]></description>
			<content:encoded><![CDATA[<p>今更ですが、<a href="http://www.openframeworks.cc/">openFrameworks (oF)</a>を触ってみました。</p>
<p>oFってのは、C/C++で描画したりインタラクティブなものを作るためのライブラリです。</p>
<p>OpenCVやBox2Dなどのライブラリも同梱されてる。</p>
<p>C++で描画が楽に出来るのはいいですよね。高速な処理もできるし。</p>
<p>今回は開発環境を作るまでを目標にやってみました。</p>
<div class="paragraph"></div>
<p><span id="more-1331"></span></p>
<p class="section_title">1.本体をダウンロード</p>
<p>まずは<a href="http://www.openframeworks.cc/">公式サイト</a>からoF本体をダウンロード。</p>
<p>自分は普段VS2010を使ってるので、「windows visual studio 2010 FAT」ってのを選択しました。</p>
<p>あとは解凍して好きなところに置けばOK。</p>
<div class="paragraph"></div>
<p class="section_title">2.「emptyExample」を利用して新しいプロジェクトを作る</p>
<p>外部ライブラリをVS(VisualStudio)で利用する場合、普通はヘッダファイルやlibファイルのあるフォルダまでパスを通します。</p>
<p>ただ、oFはそのフォルダ数が多い。パス通すのめんどい。</p>
<p><a href="http://zampoh.cocolog-nifty.com/blog/2010/04/of---openframew.html">補助ツール</a>を公開してくれてる方もいましたが、VS2008用だったので使えず。</p>
<p>そこで今回は、<strong>「oF本体までの絶対パス\apps\examples」</strong>以下に置いてある、<strong>「emptyExample」</strong>をコピーして利用することに。</p>
<div class="paragraph"></div>
<p class="section_title">3.絶対パスを相対パスに書き換える</p>
<p>emptyExampleに設定されているパスは<strong>全部相対パス</strong>です。</p>
<p>今回は自分の好きなところにプロジェクトを配置したいので、相対パスをすべて絶対パスに書き換えます。</p>
<div class="paragraph2"></div>
<p>まず、emptyExampleをコピーして好きなところに配置 (自分はVS2010のprojectフォルダに置きました)。</p>
<p>次に<strong>「 oF本体までの絶対パス\libs\openFrameworksCompiled\project\vs2010 」以下</strong>にある<strong>openframeworksLib.vcxproj</strong>をemptyExampleフォルダの中にコピー。</p>
<p>あとは設定ファイルを色々書き換えます。</p>
<div class="paragraph2"></div>
<p>emptyExample.slnは以下のように書き換えます。</p>
<ul>
<li>5行目の<strong>「&#8221;..\..\..\libs\openFrameworksCompiled\project\vs2010\openframeworksLib.vcxproj&#8221;」</strong>を<strong>「&#8221;openframeworksLib.vcxproj&#8221;」</strong>に。</li>
</ul>
<div class="paragraph2"></div>
<p>openframeworksLib.vcxprojは以下のように書き換えます。</p>
<ul>
<li>すべての<strong>「..\..\..\..\」</strong>を<strong>「oF本体までの絶対パス\」に。</strong></li>
<li>すべての<strong>「..\..\..\」</strong>を<strong>「oF本体までの絶対パス\libs\」</strong>に。</li>
<li>すべての<strong>「..\..\」</strong>を<strong>「oF本体までの絶対パス\libs\openFrameworksCompiled\」</strong>に。</li>
</ul>
<div class="paragraph2"></div>
<p>emptyExample.vcxprojは以下のように書き換えます。</p>
<ul>
<li>78行目の<strong>「xcopy /e /i /y &#8220;$(ProjectDir)..\..\..\export\vs2010\*.dll&#8221; &#8220;$(ProjectDir)bin&#8221;」</strong>を<strong>「xcopy /e /i /y &#8220;oF本体までの絶対パス\export\vs2010\*.dll&#8221; &#8220;$(ProjectDir)bin&#8221;」</strong>に。</li>
<li>すべての<strong>「..\..\..\」</strong>を<strong>「oF本体までの絶対パス\」に。</strong></li>
</ul>
<div class="paragraph2"></div>
<p>だいたいこんな感じで書き換えていきます。</p>
<div class="paragraph"></div>
<p class="section_title">4.テストしてみる</p>
<p>以下のサイトのサンプルを使わせていただきます。</p>
<ul>
<li><a href="http://matsu4512.jp/blog/2010/09/17/openframeworks01/">openFrameworksで遊ぶ 01 » Every day is Carnival</a></li>
</ul>
<div class="paragraph2"></div>
<p>ソースをコピペして実行。</p>
<p><img class = "img-style" src="http://sakef.jp/blog/blog_data/uploads/2011/06/pp.png"/></p>
<div class="paragraph2"></div>
<p>ちゃんとビルドできました。</p>
<div class="paragraph"></div>
<p>そんなわけで。</p>
<p>これで好きな場所にoFのプロジェクトが作れます。</p>
<p>なんか無理やり感があるけど動いたからよし。</p>
<p>プロジェクトを元々emptyExampleがあったフォルダ内に置くなら最後のパス書き換えはしなくても大丈夫です。</p>
<p>oFは楽しそうなので少しずつ触りたいですねー。</p>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/06/of_vs2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android(Java)を始める – AudioTrackで動的サウンド生成</title>
		<link>http://sakef.jp/blog/2011/05/android15_audiotrack/</link>
		<comments>http://sakef.jp/blog/2011/05/android15_audiotrack/#comments</comments>
		<pubDate>Sun, 08 May 2011 09:21:46 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1317</guid>
		<description><![CDATA[絶賛Androidの勉強中。 AudioTrackを使って動的に音を生成してます。 クリックするとランダムに音を作って鳴らしてくれます。 以前AS3で作ったものをAndroidに移植した感じです。 ちなみにIS06だとちゃんと動いたけど、HT-03Aだと音がプチプチでした。 Androidでも動的サウンド生成って出来るんですね。 知りませんでした。 以下、今回のソースです。 Main.java。]]></description>
			<content:encoded><![CDATA[<p><img class = "img-style" src="http://sakef.jp/blog/blog_data/uploads/2011/05/ppp.jpg" /></p>
<div class="paragraph"></div>
<p>絶賛Androidの勉強中。</p>
<p><a href="http://developer.android.com/reference/android/media/AudioTrack.html">AudioTrack</a>を使って動的に音を生成してます。</p>
<p>クリックするとランダムに音を作って鳴らしてくれます。</p>
<p><a href="http://sakef.jp/blog/2010/12/as3_dynamic_sound06/">以前AS3で作ったもの</a>をAndroidに移植した感じです。</p>
<p>ちなみにIS06だとちゃんと動いたけど、HT-03Aだと音がプチプチでした。</p>
<div class="paragraph"></div>
<p>Androidでも動的サウンド生成って出来るんですね。</p>
<p>知りませんでした。</p>
<div class="paragraph"></div>
<p>以下、今回のソースです。</p>
<p><span id="more-1317"></span></p>
<div class="paragraph"></div>
<p>Main.java。</p>
<pre class="brush: java; title: ; notranslate">
package jp.sakef;

import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class Main extends Activity
{
	private static int SAMPLING_RATE = 44100;
	private static int BUFFER = 1024;

	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		setVolumeControlStream(AudioManager.STREAM_MUSIC);
		setContentView(new MainView(getApplicationContext()));
	}

	// 描画＆音の生成を行うクラス
	public class MainView extends SurfaceView implements SurfaceHolder.Callback, Runnable
	{
		private AudioTrack track;
		private Paint paint;
		private SurfaceHolder sholder;
		private Thread thread;
		private short samples[];
		private ArrayList&lt;SoundData&gt; container;

		public MainView(Context context)
		{
			super(context);

			sholder = null;
			thread = null;
			paint = new Paint();
			paint.setAntiAlias(true);
			samples  = new short[BUFFER];
			container = new ArrayList&lt;SoundData&gt;();

			int minBufferSize = AudioTrack.getMinBufferSize(SAMPLING_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
			track = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLING_RATE, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
			track.play();

			getHolder().addCallback(this);
		}

		public void surfaceCreated(SurfaceHolder holder)
		{
			sholder = holder;
			thread = new Thread(this);
		}

		public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
		{
			if(thread != null ) thread.start();
		}

		public void surfaceDestroyed(SurfaceHolder holder)
		{
			thread = null;
			track.stop();
			track.release();
		}

		public void run()
		{
			SoundData sData;
			int sSize;

			while (thread != null)
			{
				// 白く塗りつぶす
				Canvas canvas = sholder.lockCanvas();
				canvas.drawColor(Color.argb(255, 255, 255, 255));

				// 音を生成＆書き込み
				for(int i = 0; i &lt; BUFFER; i++ )
				{
					float totalWav = 0.0f;
					sSize = container.size();
					while(sSize &gt; 0)
					{
						sData = container.get(sSize-1);
						sData.position =  (float) ((sData.position + sData.w)%(2*Math.PI));

						float eachWav;
						if(sData.position &lt; Math.PI) eachWav = (float) (1 - 2*sData.position/Math.PI);
						else eachWav = (float) (-1 + 2 * (sData.position - Math.PI)/Math.PI);

						totalWav += eachWav * 0.4 * sData.volume;
						sSize--;
					}

					// データを範囲内に丸める
					totalWav = (totalWav &gt; -0.9)?(totalWav):(-0.9f);
					totalWav = (totalWav &lt; 0.9)?(totalWav):(0.9f);
					samples[i] =  (short) (Short.MAX_VALUE * totalWav);
				}
				track.write(samples, 0, samples.length);

				// 音データの更新＆円の描画
				sSize = container.size();
				while(sSize &gt; 0)
				{
					sData = container.get(sSize-1);
					paint.setColor(Color.argb((int)(255*sData.volume), sData.cr, 255, sData.cb));
					canvas.drawCircle(sData.x, sData.y, sData.radius, paint);
					sData.render();
					if(sData.state == 3) container.remove(sData);
					sSize--;
				}
				sholder.unlockCanvasAndPost(canvas);
			}
		}

		// クリック時のイベント
		public boolean onTouchEvent(MotionEvent event)
		{
			if(event.getAction() == MotionEvent.ACTION_DOWN)
			{
				float frequency = (float) (440 * Math.pow(2, ((1.0 / 12.0) * 20 * Math.random())));
				container.add(new SoundData(frequency,0.4f, 0.01f, 2, 0.8f, event.getX(), event.getY()));
			}
			return true;
		}
	}

	// 音データを保持するクラス
	public class SoundData
	{
		public float frequency;
		public float volume;
		public float position;
		public float x;
		public float y;
		public float w;
		public int state;
		public int cr;
		public int cb;
		public int radius;
		private int count;
		private float fadeIn;
		private float fadeOut;
		private float show;
		private float volMax;

		// コンストラクタ
		public SoundData(float frequency, float fadeIn, float fadeOut, int show, float volMax, float x, float y)
		{
			this.frequency = frequency;
			this.fadeIn = fadeIn;
			this.fadeOut = fadeOut;
			this.show = show;
			this.volMax = volMax;
			this.x = x;
			this.y = y;

			position = 0;
			volume = state = count = radius = 0;
			w = (float) ((2*Math.PI * frequency) / SAMPLING_RATE);
			cr = (int)(255 * Math.random());
			cb = (int)(255 * Math.random());
		}

		// 更新用
		public void render()
		{
			radius +=2;
			switch(state)
			{
			// 音をフェードインさせる
			case 0:
				volume += fadeIn;
				if(volume&gt;=volMax)
				{
					volume = volMax;
					state = 1;
				}
				break;

				// 音を流す
			case 1:
				count ++;
				if(count == show) state = 2;
				break;

				// 音をフェードアウトさせる
			case 2:
				volume -= fadeOut;
				if(volume &lt;= 0)
				{
					state = 3;
					volume = 0;
				}
				break;
			}
		}
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/05/android15_audiotrack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AS3でハートを書く</title>
		<link>http://sakef.jp/blog/2011/04/as3_heart/</link>
		<comments>http://sakef.jp/blog/2011/04/as3_heart/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 14:03:05 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[AS3]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1310</guid>
		<description><![CDATA[はーと &#8211; wonderfl build flash online 簡単なハートの書き方。 以下のサイトを参考にしました。 Courbes ornementales この書き方は知りませんでした。 覚えておこう。]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript" src="http://wonderfl.net/blogparts/qY4L/js"></script>
<p class="ttlBpWonderfl" style="width: 465px; margin: 0; text-align: right; font-size: 11px;"><a href="http://wonderfl.net/c/qY4L" title="はーと">はーと &#8211; wonderfl build flash online</a></p>
<div class="paragraph2"></div>
<p>簡単なハートの書き方。</p>
<p>以下のサイトを参考にしました。</p>
<div class="paragraph2"></div>
<ul>
<li><a href="http://www.mathcurve.com/courbes2d/ornementales/ornementales.shtml">Courbes ornementales</a></li>
</ul>
<div class="paragraph2"></div>
<p>この書き方は知りませんでした。</p>
<p>覚えておこう。</p>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/04/as3_heart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android(Java)を始める – ColorMatrixで画像の彩度・コントラストをいじる</title>
		<link>http://sakef.jp/blog/2011/04/android14_colormatrix/</link>
		<comments>http://sakef.jp/blog/2011/04/android14_colormatrix/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 03:11:41 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1306</guid>
		<description><![CDATA[絶賛Androidの勉強中。 ColorMatrixを使って画像の彩度とコントラストをコントロールします。 AS3のColorMatrixFilterとほぼ同じ感じで使えるので楽でした。 以下、今回のソースです。 Main.java。 MainView.java。 main.xml。]]></description>
			<content:encoded><![CDATA[<p><img class = "img-style" src="http://sakef.jp/blog/blog_data/uploads/2011/04/p01.png" /></p>
<div class="paragraph"></div>
<p>絶賛Androidの勉強中。</p>
<p><a href="http://developer.android.com/reference/android/graphics/ColorMatrix.html">ColorMatrix</a>を使って画像の彩度とコントラストをコントロールします。</p>
<p>AS3のColorMatrixFilterとほぼ同じ感じで使えるので楽でした。</p>
<div class="paragraph"></div>
<p>以下、今回のソースです。</p>
<p><span id="more-1306"></span></p>
<div class="paragraph"></div>
<p>Main.java。</p>
<pre class="brush: java; title: ; notranslate">
package jp.sakef18;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.os.Bundle;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class Main extends Activity
{
	private MainView main;
	private ColorMatrix cont;
	private ColorMatrix sat;
	private ColorMatrix concat;

	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

		// 画面サイズを設定
		WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
		Display disp = wm.getDefaultDisplay();
		int height = disp.getHeight();

		// 画像を表示するView
		main = new MainView(this);
		setContentView(main);

		// xmlからviewを作成
		View view = this.getLayoutInflater().inflate(R.layout.main, null);
		view.setPadding(0, height-110, 0, 0);
		addContentView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));

		// ColorMatrix
		cont = new ColorMatrix();
		sat = new ColorMatrix();
		concat = new ColorMatrix();

		// 彩度を変更するSeekBar
		SeekBar contBar = (SeekBar)(view.findViewById(R.id.contrastBar));
		contBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener()
		{
			// 画像の彩度を変更する
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch)
			{
				float rl = 0.212671f;
				float gl = 0.715160f;
				float bl = 0.072169f;
				float sf = (float)(progress)/50.0f;
				float nf = 1-sf;
				float nr = rl * nf;
				float ng = gl * nf;
				float nb = bl * nf;
				sat.set(new float[] {
						nr+sf,	ng,		nb,		0,	0,
						nr,		ng+sf,	nb,		0,	0,
						nr,		ng,		nb+sf,	0,	0,
						0,  	0, 		0,  	1,  0 });

				concat.reset();
				concat.postConcat(sat);
				concat.postConcat(cont);
				main.drawImage(new ColorMatrixColorFilter(concat));
			}

			public void onStartTrackingTouch(SeekBar seekBar){}
			public void onStopTrackingTouch(SeekBar seekBar){}
		});

		// コントラストを変更するSeekBar
		SeekBar satBar = (SeekBar)(view.findViewById(R.id.satBar));
		satBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener()
		{
			// 画像のコントラストを変更する
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch)
			{
				float scale = (float)(progress)/50.0f ;
				float translate = (-.5f * scale + .5f) * 255.f;
				cont.set(new float[] {
						scale	,0		,0		,0	,translate,
						0		,scale	,0		,0	,translate,
						0		,0		,scale	,0	,translate,
						0		,0		,0		,1	,0});

				concat.reset();
				concat.postConcat(sat);
				concat.postConcat(cont);
				main.drawImage(new ColorMatrixColorFilter(concat));
			}

			public void onStartTrackingTouch(SeekBar seekBar){}
			public void onStopTrackingTouch(SeekBar seekBar){}
		});
	}
}
</pre>
<div class="paragraph"></div>
<p>MainView.java。</p>
<pre class="brush: java; title: ; notranslate">
package jp.sakef18;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainView extends SurfaceView implements SurfaceHolder.Callback
{
	private SurfaceHolder holder;
	private Paint paint;
	private Bitmap bmp;
	private float scale;

	// コンストラクタ
	public MainView(Context context)
	{
		super(context);
		getHolder().addCallback(this);

		paint = new Paint();
		bmp =  BitmapFactory.decodeResource(getResources(),R.drawable.img);
	}

	// 色々初期化
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
	{
		scale = (float) width / bmp.getWidth();
		this.holder = holder;
		drawImage(null);
	}

	// 描画
	public void drawImage(ColorMatrixColorFilter cmxf)
	{
		Canvas canvas = holder.lockCanvas();
		if(canvas!=null)
		{
			paint.reset();
			paint.setAntiAlias(true);
			paint.setColor(Color.rgb(200, 0, 0));
			paint.setColorFilter(cmxf);

			canvas.drawColor(Color.BLACK);
			canvas.scale(scale, scale);
			canvas.drawBitmap(bmp,0,0, paint);
			holder.unlockCanvasAndPost(canvas);
		}
	}

	public void surfaceDestroyed(SurfaceHolder holder){}
	public void surfaceCreated(SurfaceHolder holder){}
}
</pre>
<div class="paragraph"></div>
<p>main.xml。</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
	android:id = &quot;@+id/conponentLayout&quot;
    android:orientation=&quot;vertical&quot;
    android:layout_width=&quot;fill_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
&gt;
	&lt;SeekBar
	android:id = &quot;@+id/contrastBar&quot;
	android:layout_width=&quot;fill_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:max = &quot;100&quot;
    android:progress = &quot;50&quot;
	/&gt;
	&lt;SeekBar
	android:id = &quot;@+id/satBar&quot;
	android:layout_width=&quot;fill_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:max = &quot;100&quot;
    android:progress = &quot;50&quot;
	/&gt;
&lt;/LinearLayout&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/04/android14_colormatrix/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AS3でチルトシフトっぽいの</title>
		<link>http://sakef.jp/blog/2011/04/tiltshift01/</link>
		<comments>http://sakef.jp/blog/2011/04/tiltshift01/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 14:12:14 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[AS3]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1300</guid>
		<description><![CDATA[よく見るチルトシフトってのに挑戦。 写真をミニチュア風に見せてくれるそうです。 とりあえず、 画像の彩度を調整する 画像のコントラストを調整する 画像をぼかす 画像のふちを黒く塗る の4つの処理を適用することでそれっぽく見える。 こんな感じになりました。 左が処理後の写真で、右は処理前の写真です。 ちなみに写真は大学の公園。 以下、ソースです。]]></description>
			<content:encoded><![CDATA[<p><a href="http://sakef.jp/as3/tiltshift01/"><br />
<img class = "img-style" src="http://sakef.jp/blog/blog_data/uploads/2011/04/p.png" /><br />
</a></p>
<div class="paragraph"></div>
<p>よく見るチルトシフトってのに挑戦。</p>
<p>写真をミニチュア風に見せてくれるそうです。</p>
<div class="paragraph2"></div>
<p>とりあえず、</p>
<ul>
<li>画像の彩度を調整する</li>
<li>画像のコントラストを調整する</li>
<li>画像をぼかす</li>
<li>画像のふちを黒く塗る</li>
</ul>
<p>の4つの処理を適用することでそれっぽく見える。</p>
<p><a href="http://sakef.jp/as3/tiltshift01/">こんな感じ</a>になりました。</p>
<p>左が処理後の写真で、右は処理前の写真です。</p>
<p>ちなみに写真は大学の公園。</p>
<div class="paragraph"></div>
<p>以下、ソースです。</p>
<p><span id="more-1300"></span></p>
<div class="paragraph"></div>
<pre class="brush: as3; title: ; notranslate">
package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.GradientType;
	import flash.display.Graphics;
	import flash.display.SpreadMethod;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.Matrix;
	import flash.geom.Point;

	[SWF(backgroundColor=&quot;0xffffff&quot;)]
	public class Main extends Sprite
	{
		[Embed(source='img.jpg')]
		private var IMG:Class
		private var source:BitmapData;
		private var canvas:BitmapData;

		public function Main()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			stage.quality = StageQuality.HIGH;
			stage.frameRate = 40;

			// 画像の用意
			source = (new IMG as Bitmap).bitmapData;
			canvas = source.clone();

			// 画像をチルトシフト風にする
			// 1. コントラストをいじる
			setContrast(1, source, canvas);
			// 2. 彩度をいじる
			setSaturation(2, canvas, canvas);
			// 3. ふちを黒くぬる
			setBlackEdges(canvas, canvas);
			//　4. ブラーをかける
			setBlur(source.width*0.5, source.height*0.5, 80, canvas, canvas);

			// 処理後の画像を表示
			var bitmap1:Bitmap = addChild(new Bitmap(canvas)) as Bitmap;

			// 元の画像を表示
			var bitmap2:Bitmap = addChild(new Bitmap(source)) as Bitmap;
			bitmap2.x = 10+bitmap2.width;
		}

		// 端を黒くする
		private function setBlackEdges(src:BitmapData, dst:BitmapData):void
		{
			var container:Sprite = new Sprite;

			// 画像
			var baseBmpd:BitmapData = src.clone();
			var baseBmp:Bitmap = container.addChild(new Bitmap(baseBmpd)) as Bitmap;

			// 上にふちを黒く塗ったSpriteを設置
			var wrap:Sprite = container.addChild(new Sprite) as Sprite;
			var g:Graphics = wrap.graphics;
			var matrix:Matrix = new Matrix;
			matrix.createGradientBox(src.width+100, src.height+100,0,-50,-50);
			g.beginGradientFill(GradientType.RADIAL, [0x000000, 0x000000], [0, 1], [100,255], matrix, SpreadMethod.PAD);
			g.drawRect(-50,-50,src.width+50, src.height+50);
			g.endFill();

			// 描写
			dst.draw(container);

			// 描写につかったのを削除
			while(container.numChildren) container.removeChildAt(0);
			baseBmpd.dispose();
			baseBmp = null;
			wrap = null;
		}

		// ブラーをかける
		private function setBlur(x:Number, y:Number, radius:Number, src:BitmapData, dst:BitmapData):void
		{
			var container:Sprite = new Sprite;

			// 後ろにぼかした画像を配置
			var baseBmpd:BitmapData = src.clone();
			var baseBmp:Bitmap = container.addChild(new Bitmap(baseBmpd)) as Bitmap;
			baseBmpd.applyFilter(baseBmpd, baseBmpd.rect, new Point, new BlurFilter(4,4,3));

			// マスクをかけるBitmap
			var maskBmpd:BitmapData = src.clone();
			var maskBmp:Bitmap = container.addChild(new Bitmap(maskBmpd)) as Bitmap;
			maskBmp.cacheAsBitmap = true;

			// マスク
			var mask:Sprite = container.addChild(new Sprite) as Sprite;
			mask.graphics.beginFill(0x000000,1);
			mask.graphics.drawCircle(x, y, radius);
			mask.graphics.endFill();
			mask.cacheAsBitmap = true;
			mask.filters = [new BlurFilter(40,40,6)];

			// マスクでブラーがかかってない部分をくりぬく
			maskBmp.mask = mask;

			// 描写
			dst.draw(container);

			// 描写につかったのを削除
			while(container.numChildren) container.removeChildAt(0);
			baseBmpd.dispose();
			maskBmpd.dispose();
			baseBmp = null;
			maskBmp = null;
			mask = null;
			container = null;
		}

		// コントラストの変更
		private function setContrast(value:Number, src:BitmapData, dst:BitmapData):void
		{
			var mc:Number = value + 1;
			var co:Number = Math.round(value*-128);

			var matrix:Array = [
				mc,	0,	0, 	0, co,
				0,	mc,	0, 	0, co,
				0,	0,	mc,	0, co,
				0,  0, 	0, 	1,  0
			];

			dst.applyFilter(src, src.rect, new Point, new ColorMatrixFilter(matrix));
		}

		// 彩度の変更
		private function setSaturation(value:Number, src:BitmapData, dst:BitmapData):void
		{
			var rl:Number = 0.212671;
			var gl:Number = 0.715160;
			var bl:Number = 0.072169;

			var sf:Number = value;
			var nf:Number = 1-sf;
			var nr:Number = rl * nf;
			var ng:Number = gl * nf;
			var nb:Number = bl * nf;

			var matrix:Array = [
				nr+sf,	ng,		nb,		0,	0,
				nr,		ng+sf,	nb,		0,	0,
				nr,		ng,		nb+sf,	0,	0,
				0,  	0, 		0,  	1,  0
			];

			dst.applyFilter(src, src.rect, new Point, new ColorMatrixFilter(matrix));
		}
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/04/tiltshift01/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ボールをバネで円状に連結[Wonderfl版]</title>
		<link>http://sakef.jp/blog/2011/03/drag_spring_w/</link>
		<comments>http://sakef.jp/blog/2011/03/drag_spring_w/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 03:24:33 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[Wonderfl]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1295</guid>
		<description><![CDATA[バネを円状につないだ &#8211; wonderfl build flash online こないだ作ったのをWonderflにもアップ。 ワンダフるの久々。]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript" src="http://wonderfl.net/blogparts/q3Kp/js"></script>
<p class="ttlBpWonderfl" style="width: 465px; margin: 0; text-align: right; font-size: 11px;"><a href="http://wonderfl.net/c/q3Kp" title="バネを円状につないだ">バネを円状につないだ &#8211; wonderfl build flash online</a></p>
<div class="paragraph"></div>
<p>こないだ作ったのをWonderflにもアップ。</p>
<p>ワンダフるの久々。</p>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/03/drag_spring_w/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>バネを繋いで円にする</title>
		<link>http://sakef.jp/blog/2011/03/spring_circle/</link>
		<comments>http://sakef.jp/blog/2011/03/spring_circle/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 05:14:10 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[物理演算]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1290</guid>
		<description><![CDATA[バネを繋いで円状に。 ActionScript3.0アニメーションを読んで勉強してます。 Chapter8のバネの章を参考に作りました。 springTo関数はサンプルのものをほぼそのまま使わせてもらってます。 以下、ソースです。]]></description>
			<content:encoded><![CDATA[<p><a href="http://sakef.jp/as3/physics03/"><br />
<img class = "img-style" src="http://sakef.jp/blog/blog_data/uploads/2011/03/p01.png" /><br />
</a></p>
<div class="paragraph"></div>
<p>バネを繋いで円状に。</p>
<p><a href="http://www.amazon.co.jp/ActionScript-3-0-%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-Keith-Peters/dp/4862460496">ActionScript3.0アニメーション</a>を読んで勉強してます。</p>
<p>Chapter8のバネの章を参考に作りました。</p>
<p>springTo関数はサンプルのものをほぼそのまま使わせてもらってます。</p>
<div class="paragraph"></div>
<p>以下、ソースです。</p>
<p><span id="more-1290"></span></p>
<div class="paragraph"></div>
<pre class="brush: as3; title: ; notranslate">
package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.DropShadowFilter;

	public class Main extends Sprite
	{
		private static const K:Number = 0.1;
		private static const RADIUS:Number = 120;
		private static const RADIUS_BALL:Number = 15;
		private static const G:Number = 2;
		private static const F:Number = 0.95;
		private static const BALL_NUM:int = 8;
		private static const RADIAN:Number = Math.PI/180;

		private var len_side:Number;
		private var len_opp:Number;
		private var balls:Vector.&lt;Ball&gt;;
		private var drag_ball:int;
		private var mouse_x:Number;
		private var mouse_y:Number;

		public function Main()
		{
			// ステージの設定
			stage.frameRate=60;
			stage.quality=StageQuality.HIGH;
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.align=StageAlign.TOP_LEFT;

			// 初期化
			balls = new Vector.&lt;Ball&gt;(BALL_NUM, true);
			var theta:Number = 0;
			for(var i:int=0 ; i&lt;BALL_NUM ; i++, theta += 360/BALL_NUM)
			{
				var xx:Number = Math.cos(theta*RADIAN)*RADIUS + 300;
				var yy:Number = Math.sin(theta*RADIAN)*RADIUS + 300;
				var ball:Ball = addChild(new Ball(xx,yy,i,RADIUS_BALL)) as Ball;
				ball.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
				ball.buttonMode = true;
				balls[i] = ball;
			}

			// 隣接してるボールとの距離
			len_side = Math.sqrt((balls[0].x - balls[1].x)*(balls[0].x - balls[1].x) + (balls[0].y - balls[1].y)*(balls[0].y - balls[1].y));

			// 向かいのボールとの距離
			len_opp = RADIUS * 2;

			// ドラッグの用意
			mouse_x = mouseX;
			mouse_y = mouseY;
			drag_ball = -1;

			filters = [new DropShadowFilter(4,45,0x777777)];
			addEventListener(Event.ENTER_FRAME, onFrame);
		}

		// マウスアップ時に実行する関数
		private function onMouseUp(e:MouseEvent):void
		{
			var ball:Ball = balls[drag_ball];
			drag_ball = -1;
			stage.removeEventListener(MouseEvent.MOUSE_UP , onMouseUp);
			ball.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		}

		// マウスダウン時に実行する関数
		private function onMouseDown(e:MouseEvent):void
		{
			var ball:Ball = (e.target as Ball);
			drag_ball = ball.id;
			stage.addEventListener(MouseEvent.MOUSE_UP , onMouseUp);
			ball.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		}

		// 計算
		private function onFrame(e:Event):void
		{
			var ball:Ball;
			var i:int, j:int;

			mouse_x = mouseX;
			mouse_y = mouseY;
			graphics.clear();
			graphics.lineStyle(6,0xFF0000);
			graphics.beginFill(0xFFFF00,1);

			// ドラッグ中のBallを計算
			if(drag_ball != -1)
			{
				ball = balls[drag_ball];
				ball.dx = mouseX - mouse_x;
				ball.dy = mouseY - mouse_y;
				ball.x = mouseX;
				ball.y = mouseY;
			}

			// 向い同士のボールの計算
			var half:int = BALL_NUM * 0.5;
			for(i=0 ; i&lt;half ; i++)
			{
				j = i+half;
				if(i != drag_ball) springTo(balls[i], balls[j], len_opp);
				if(j != drag_ball) springTo(balls[j], balls[i], len_opp);
			} 

			//隣同士のボールの計算
			ball = balls[0];
			var last:Ball = balls[BALL_NUM-1];
			var startCx:Number=(ball.x + last.x) * 0.5;
			var startCy:Number=(ball.y + last.y) * 0.5;
			graphics.moveTo(startCx, startCy);
			for(i=0 ; i&lt;BALL_NUM ; i++)
			{
				j = (i+1)%BALL_NUM;
				ball = balls[i];
				var next:Ball=balls[j];
				var cx:Number=(ball.x + next.x) * 0.5;
				var cy:Number=(ball.y + next.y) * 0.5;
				if(i &lt; BALL_NUM-1) graphics.curveTo(ball.x, ball.y, cx, cy);
				if(i != drag_ball) springTo(ball, next, len_side);
				if(j != drag_ball) springTo(next, ball, len_side);
			}
			graphics.curveTo(last.x, last.y, startCx, startCy);
			graphics.endFill();

			// 壁とのあたり判定
			for(i=0;i&lt;BALL_NUM;i++)
			{
				ball = balls[i];
				if(ball.id != drag_ball)
				{
					if(ball.x &lt; RADIUS_BALL)
					{
						ball.x = RADIUS_BALL;
						ball.dx *= -1;
					}
					if(ball.y &lt; RADIUS_BALL)
					{
						ball.y = RADIUS_BALL;
						ball.dy *= -1;
					}
					if(ball.x &gt; stage.stageWidth-RADIUS_BALL)
					{
						ball.x = stage.stageWidth-RADIUS_BALL;
						ball.dx *= -1;
					}
					if(ball.y &gt; stage.stageHeight-RADIUS_BALL)
					{
						ball.y = stage.stageHeight-RADIUS_BALL;
						ball.dy *= -1;
					}
				}
			}
		}

		// ボールの位置を計算する
		private function springTo(ballA:Ball, ballB:Ball, length:Number):void
		{
			var angle:Number = Math.atan2(ballB.y - ballA.y, ballB.x - ballA.x);
			var targetX:Number = ballB.x - Math.cos(angle) * length;
			var targetY:Number = ballB.y - Math.sin(angle) * length;
			ballA.dx += (targetX - ballA.x) * K;
			ballA.dy += (targetY - ballA.y) * K;
			ballA.dx *= F;
			ballA.dy *= F;
			ballA.x += ballA.dx;
			ballA.y += ballA.dy;
		}
	}
}

// ボールクラス
import flash.display.Sprite;
import flash.filters.DropShadowFilter;
class Ball extends Sprite
{
	public var dx:Number;
	public var dy:Number;
	public var id:int;

	public function Ball(x:Number, y:Number, id:int, radius:Number)
	{
		this.x = x;
		this.y = y;
		this.id = id;
		dx = dy = 0;

		graphics.beginFill(0x00ff00,1);
		graphics.drawCircle(0,0, radius);
		graphics.endFill();
		graphics.beginFill(0xffffff,1);
		graphics.drawCircle(0,0, radius*0.5);
		graphics.endFill();
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/03/spring_circle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>簡単なボールの衝突判定 2</title>
		<link>http://sakef.jp/blog/2011/03/ball_collision02/</link>
		<comments>http://sakef.jp/blog/2011/03/ball_collision02/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 05:07:19 +0000</pubDate>
		<dc:creator>sakef</dc:creator>
				<category><![CDATA[AS3]]></category>
		<category><![CDATA[物理演算]]></category>

		<guid isPermaLink="false">http://sakef.jp/blog/?p=1285</guid>
		<description><![CDATA[物理の勉強中。 前に作ったのを改良。 こんな感じに。 以下、ソースです。]]></description>
			<content:encoded><![CDATA[<p><a href="http://sakef.jp/as3/physics02/"><br />
<img class = "img-style" src="http://sakef.jp/blog/blog_data/uploads/2011/03/p02.png" /><br />
</a></p>
<div class="paragraph"></div>
<p>物理の勉強中。</p>
<p><a href="http://sakef.jp/blog/2010/10/ball_collision01/">前に作ったの</a>を改良。</p>
<p><a href="http://sakef.jp/as3/physics02/">こんな感じ</a>に。</p>
<div class="paragraph"></div>
<p>以下、ソースです。</p>
<p><span id="more-1285"></span></p>
<div class="paragraph"></div>
<pre class="brush: as3; title: ; notranslate">
package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;

	[SWF(backgroundColor=&quot;0xFFFFFF&quot;)]
	public class Main extends Sprite
	{
		// はねかえり定数
		private static const E:Number = 0.8;
		// ボールの半径
		private static const RADIUS:Number = 40;
		// 摩擦
		private static const D:Number = 0.99;
		// ボールの数
		private static const BALL_NUM:int = 10;
		// ボールを保存するVector
		private var balls:Vector.&lt;Ball&gt;;
		// ドラッグ用
		private var drag_ball:int;
		private var mouse_x:Number;
		private var mouse_y:Number;

		// コンストラクタ
		public function Main()
		{
			// ステージの設定
			stage.frameRate=60;
			stage.quality=StageQuality.HIGH;
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.align=StageAlign.TOP_LEFT;

			// ボールを保存するVector
			balls = new Vector.&lt;Ball&gt;(BALL_NUM, true);

			// ボールの作成
			for(var i:int=0 ; i&lt;BALL_NUM ; i++)
			{
				var ball:Ball = addChild(new Ball(Math.random()*(stage.stageWidth - RADIUS), Math.random()*(stage.stageHeight - RADIUS), RADIUS, i)) as Ball;
				balls[i] = ball;
				ball.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			}

			// ドラッグの用意
			mouse_x = mouseX;
			mouse_y = mouseY;
			drag_ball = -1;

			// フレームイベントの追加
			addEventListener(Event.ENTER_FRAME, onFrame);
		}

		// マウスアップ時に実行する関数
		private function onUp(e:MouseEvent):void
		{
			var ball:Ball = balls[drag_ball];
			drag_ball = -1;
			stage.removeEventListener(MouseEvent.MOUSE_UP , onUp);
			ball.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
		}

		// マウスダウン時に実行する関数
		private function onDown(e:MouseEvent):void
		{
			var ball:Ball = (e.target as Ball);
			drag_ball = ball.id;
			stage.addEventListener(MouseEvent.MOUSE_UP , onUp);
			ball.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
		}

		// フレームイベント用関数
		private function onFrame(evt:Event):void
		{
			// ドラッグ中のノードを計算
			var ball:Ball;
			if(drag_ball != -1)
			{
				var dx:Number = mouseX - mouse_x;
				var dy:Number = mouseY - mouse_y;
				ball = balls[drag_ball];
				ball.dx = dx;
				ball.dy = dy;
				ball.x = mouseX;
				ball.y = mouseY;
			}
			mouse_x = mouseX;
			mouse_y = mouseY;

			// 衝突判定
			var i:int;
			var j:int;
			var a:Ball;
			var b:Ball;
			for(i=0 ; i&lt;BALL_NUM ; i++)
			{
				for(j = 0 ; j&lt;BALL_NUM ; j++)
				{
					if( j&lt;= i) continue;
					a = balls[i];
					b = balls[j];

					// ABベクトルを計算
					var AB_x:Number = b.x - a.x;
					var AB_y:Number = b.y - a.y;

					// 2つの円の中心間の距離
					var tr:Number = a.radius + b.radius;

					// 三平方の定理より衝突判定を行う
					if(AB_x * AB_x + AB_y * AB_y &lt; tr * tr)
					{
						// 円がめりこんだ量を計算
						var len:Number = Math.sqrt(AB_x * AB_x + AB_y * AB_y);
						var distance:Number = (a.radius + b.radius) - len;
						if(len &gt; 0) len = 1 / len;
						AB_x *= len;
						AB_y *= len;        

						// めり込んだ量の半分ずつを追加
						distance /= 2.0;
						a.x -= AB_x * distance;
						a.y -= AB_y * distance;
						b.x += AB_x * distance;
						b.y += AB_y * distance;

						// 衝突後の速度を計算
						var ma:Number = (b.m / (a.m + b.m))*(1 + E)* ((b.dx - a.dx)*AB_x + (b.dy - a.dy)*AB_y);
						var mb:Number = (a.m / (a.m + b.m))*(1 + E)* ((a.dx - b.dx)*AB_x + (a.dy - b.dy)*AB_y);
						a.dx += ma*AB_x;
						a.dy += ma*AB_y;
						b.dx += mb*AB_x;
						b.dy += mb*AB_y;

					}
				}
			}

			// 座標の更新
			for(i=0;i&lt;BALL_NUM;i++)
			{
				ball = balls[i];

				// ドラッグされているものはスキップする
				if(ball.id != drag_ball)
				{
					ball.dy +=0.8;

					// 速度に摩擦を乗算
					ball.dx *= D;
					ball.dy *= D;

					// 速度を座標に加算
					ball.x += ball.dx;
					ball.y += ball.dy;

					// 壁との当たり判定
					if(ball.x &lt; RADIUS)
					{
						ball.x = RADIUS;
						ball.dx *= -1;
					}
					if(ball.y &lt; RADIUS)
					{
						ball.y = RADIUS;
						ball.dy *= -1;
					}
					if(ball.x &gt; stage.stageWidth-RADIUS)
					{
						ball.x = stage.stageWidth-RADIUS;
						ball.dx *= -1;
					}
					if(ball.y &gt; stage.stageHeight-RADIUS)
					{
						ball.y = stage.stageHeight-RADIUS;
						ball.dy *= -1;
					}
				}
			}
		}
	}
}

// ボールクラス
import flash.display.Sprite;
import flash.filters.DropShadowFilter;
class Ball extends Sprite
{
	// 色をもつ配列
	private static const colors:Array = [0x770000, 0x007700, 0x000077, 0x777700];

	// 半径・ID・速度・質量
	public var radius:Number;
	public var id:int;
	public var dx:Number;
	public var dy:Number;
	public var m:Number;

	public function Ball(x:Number, y:Number, radius:Number, id:int)
	{
		// 変数初期化
		this.x = x;
		this.y = y;
		this.id = id;
		this.radius = radius;

		// radius・dx・dy・mの初期化
		dx = 6*Math.random() - 3;
		dy = 6*Math.random() - 3;
		m = 10;

		// 円の描写
		graphics.beginFill(colors[id%4],1);
		graphics.drawCircle(0,0, radius);
		graphics.endFill();
		graphics.beginFill(0xffffff,1);
		graphics.drawCircle(0,0,radius*0.5);
		graphics.endFill();
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://sakef.jp/blog/2011/03/ball_collision02/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

