ラベル code の投稿を表示しています。 すべての投稿を表示
ラベル code の投稿を表示しています。 すべての投稿を表示

土曜日, 10月 02, 2010

ArrayListについて認識を改めたところ

以前の投稿(build ribbons)で、
for文のところを単にかっこいい書き方としか認識してなかったんですけど、
配列の長さがループの途中で変わるので、ああいう風にしておかないとremoveで取り除かれた分の添字が詰まった結果、参照されないオブジェクトがでてきてしまってちらつきが起こってしまいます。

こういう場合。
試しにdraw()内のfor文の初期化式をint i=0、継続条件式をi<ripples.size()、再初期化式をi++にしてみると分かります。
リファレンスにも似たような例が書いてあって、Examples>Topics>Advanced Data>ArrayListClassでも確認できます。
[Ripple.pde]
class Ripple {
float x, y, w, speed;
float age;
int intensity;
color c;
float a;
boolean finished;

Ripple(float x, float y, int intensity, color c, float speed) {
this.x = x;
this.y = y;
this.intensity = intensity;
this.c = c;
this.speed = speed;
this.age = 0;
this.a = 255-255*(age-speed)/intensity;
this.finished = false;
}

void display() {
age += speed;
a = 255-255*(age-speed)/intensity;
if(a<=5) {
finished = true;
}
stroke(c, a);
ellipse(x, y, age, age);
}

boolean finished() {
return finished;
}
}

[drawRipple.pde]
Ripple r;
ArrayList ripples;
void setup() {
size(400, 400);
background(255);
noFill();
smooth();
ripples = new ArrayList();
for(int i=0; i < 100; i++) {
ripples.add(new Ripple(random(width), random(height), (int)random(20, 80), color(0), random(0.1, 0.4)));
}
}

void draw() {
background(255);
for (int i = ripples.size()-1; i >= 0; i--) {
Ripple ripple = (Ripple)ripples.get(i);
ripple.display();
if(ripple.finished()) {
ripples.remove(ripple);
}
}
}

火曜日, 10月 06, 2009

レイヤーカンプからWeb用のJPEGに書き出すJavaScript

Webデザイン(ワイヤーフレームから絵を起こす作業)はPhotoshopで常人の理解を超える数のレイヤーを駆使して行われます。そしてそれをコーダーと呼ばれる人達に渡してブラウザで動くようにしてもらったり、クライアントに対してこのデザインでいいですかという確認をとるために、マウスオーバーでこうなって、ボタンを押すこうなる、みたいな流れがわかるようにJPEGでスクリーンショット的な画像を書き出します。このような場合に「レイヤーカンプ」という機能を使い、それぞれのシーンを作っておくと便利です。

で、いつもJPEGに書き出す際に「Webおよびデバイスに保存...」をしてるのですが、数が増えてくると面倒(一度本当に嫌な思いをしました)なので、レイヤーカンプから自動でシーン毎のJPEGを書き出してくれるスクリプトを書きました(その時に書けば良かったです)。
「別名で保存」と同じようなものは既にファイルメニューにありますが、Webおよび...のやつがなかったので(少し変えればPNGなどにも書き出せます)。
exportLayerComp.jsx

使い方:
1.上の.jsxファイルをどこでもいいので保存して下さい。
2.Macの場合はホーム(デスクトップではありません。家のアイコンの場所)に、Windows場合はC:直下にlayercompsという名前のフォルダを作ります。ここに画像ファイルが書き出されます。
3.Photoshopのメニューからファイル>スクリプト>参照...を選びます。
保存したexportLayerComp.jsxを「読み込み」でレイヤーカンプにつけた名前の通りのjpgが書き出されます。
ファイル名はレイヤーカンプと同じ名前になります。日本語だったり長過ぎるとうまくいかないかも知れないです。書き出されるフォルダの位置や名前を変えたい場合は、任意のテキストエディタでexportLayerComp.jsxを開き、
filePath = ""
の二重引用符内を好きなフォルダのパスに置き換えて下さい。
Windowsの場合は\(または¥)に注意して下さい。一つだと次の文字が特殊文字として扱われてしまうので、階層の区切りには2つ入ることになります。

デフォルトでの書き出しの設定は普通にWebおよび...をした時と同じにしてあります。
画質を変更したい場合は、
exp.quality = 70;
の値を0から100の範囲で指定して下さい。

exp.format = SaveDocumentType.JPEG;
のJPEGのところを変更すればCOMPUSERVEGIF, PNG-8, PNG-24, BMPで書き出しできます。ファイルの拡張子を追加している".jpg"のところも合わせて変えるのを忘れずに。

細かい設定などはAdobe Photoshop CS3/スクリプティングガイドフォルダ内にPhotoshop CS3 JavaScript Ref.pdfというのがあるので参照して下さい(106ページ)。ここからダウンロードもできます。

下記のサイトを参考にしました。
Adobe Photoshop CS3自動化作戦
PhotoShop JavaScript(ExtendScript):Note - ホコホコ hoko-hoko

書き出すファイルや画質の設定をGUIでできるようにしたいのだけど、それはまた次。
こういう感じで社内のワークフローを楽にしてくれる専門の人っていないのかな。

木曜日, 9月 03, 2009

openFrameworksでSndObjを使う

Programming Interactivityに載ってた。著者のJoshua NobleさんがofxSndObjを作ってるのですね。

前回ofxMSAPhysicsでものすごく面倒なやり方をしてましたが、これは僕がXcodeの使い方をわかってなかった。
XcodeのProjectメニューからAdd to Project...して追加したいaddonのsrcフォルダとlibフォルダを選べばいいだけのことでした。それでXcodeの画面で追加したsrcとlibsをaddonsというグループにまとめておくという流れ。XcodeのGroups & Filesは実際のフォルダ構成とは別物。合わせておくとわかりやすい場合もあるというだけ。

僕のopenFrameworks関係のフォルダ構成は
+of
-addons_contributed
+of_preRelease_v0.06_xcode_FAT
-addons
+apps
-addonsExamples
-examples
-sketch
-libs
-other
-samples

という風にしていて、標準で入っているaddonとそうでないものを分けています。ofxSndObjはaddons_contributedに入れてる。samplesはネットとかで拾ってきたコードを入れておくフォルダ。

以上を踏まえて新しいemptyExampleをsketch以下にコピーして名前を変えた後、ofxSndObjのsrcとlibsを追加し、testApp.hとtestApp.cppを以下のようにすればお約束の440Hzのサイン波が鳴るはず。

testApp.h
#ifndef _TEST_APP
#define _TEST_APP


#include "ofMain.h"
#include "ofxSndObj.h"
#include "AudioDefs.h"

class testApp : public ofBaseApp{

public:
void setup();
ofxSOTable t;
ofxSOOscillator o;
ofxSndObj sndobj;
};

#endif

testApp.cpp
#include "testApp.h"

void testApp::setup(){
sndobj.startOut(true, 1);
t.init(sndobj, 2500l, SINE, 1.f);
o.init(sndobj, t, 440.f, 10000.f);
sndobj.setOutput(o, OFXSNDOBJOSCILLATOR, 1);
sndobj.startProcessing();
}

火曜日, 8月 11, 2009

Processing IDEからEcho Nest APIを使う

Echo NestのJavaクライアントが出ていたのでProcessingで動かしてみた。
Echo Nestが何なのかよくわかってないけど、とりあえずネットと音という大好きな要素が混ざっている。
曲やレビュー、記事のリコメンドからテンポ、ビート等の音響解析にも使えるらしい。

まずはdeveloper用のサイトでEcho NestのAPI Accountを取得してAPI Keyを発行してもらう。
サイトも綺麗だしブラウザから実行例を見られるので勉強しやすい。APIキーとか入れといてくれてる。

Echo NestのJava APIをダウンロードする。

Javaのライブラリなので、OSXの場合"ユーザ名/Library/Java/Extensions"以下にEchoNestAPI.jarを置いて.bash_profileにCLASSPATHを書くのでもいいけど、Documents/Processing/librariesの中にEchoNestAPIというフォルダを作り、さらにlibraryフォルダを作って、その中にEchoNestAPI.jarを入れても動く。ProcessingのIDEから簡単にimportできる。

JavaのサンプルそのままだとProcessingのIDEの場合for文のところでエラーになってしまうので書き換えた。
import com.echonest.api.v3.artist.Artist;
import com.echonest.api.v3.artist.ArtistAPI;
import com.echonest.api.v3.artist.Audio;
import com.echonest.api.v3.EchoNestException;
import com.echonest.api.v3.artist.Scored;
import java.util.List;

String API_KEY = "自分のAPI KEY";
String ARTISTNAME = "weezer";

ArtistAPI artistAPI;

try {
artistAPI = new ArtistAPI(API_KEY);
List<Artist> artists = artistAPI.searchArtist(ARTISTNAME, false);
if(artists.size()>0) {
for(int i=0; i<artists.size(); i++) {
Artist artist = artists.get(i);
List<Scored<Artist>> similars = artistAPI.getSimilarArtists(artists, 0, 10);
println(" === Similar artists for " + artist.getName() + " ===");
for(int j=0;j<similars.size(); j++) {
Scored<Artist> simArtist = similars.get(j);
println(simArtist.getItem());
}
}
}
}
catch(EchoNestException e) {
System.err.println("Trouble: " + e);
}


実行結果

=== Similar artists for Weezer ===
The Smashing Pumpkins
Ozma
Biffy Clyro
The Breeders
Rivers Cuomo
Nerf Herder
Jimmy Eat World
Foo Fighters
Veruca Salt
The Flaming Lips
=== Similar artists for Weezer Tribute ===
The Smashing Pumpkins
Ozma
Biffy Clyro
The Breeders
Rivers Cuomo
Nerf Herder
Jimmy Eat World
Foo Fighters
Veruca Salt
The Flaming Lips
=== Similar artists for Matt Sharp (of Weezer, The Rentals) ===
The Smashing Pumpkins
Ozma
Biffy Clyro
The Breeders
Rivers Cuomo
Nerf Herder
Jimmy Eat World
Foo Fighters
Veruca Salt
The Flaming Lips



開発者の人のデモがここにある。eclipseで開発してる。

*2009年11月11日追記
EchoNestAPIを使用する場合はJavaのバージョンを1.6にする必要があります。
Applications/Utilities/Java Preferencesを起動して、GeneralタブのJava ApplicationsのJava SE 6を一番上にする。

で、いつの間にかechonestp5というものができてた。

日曜日, 7月 26, 2009

openframeworksでaddonを試す

FATで入ってるaddonはいいとして、他のaddonを使う時はどういう方法がいいのかなと思って試してみました。かなり愚直なやり方です。

ofxMSAPhysicsを使ってみる。
processingのtraer physics(いつの間にかソースが公開されている!)に似たAPI。

1.ダウンロード
svnがわかる人は
svn checkout http://ofxmsaof.googlecode.com/svn/trunk/ ofxmsaof-read-only

わからない人はミラーからダウンロードできます。
ofxPhysics以外にも色々入ってます。

2.プロジェクトを作る

apps/examples/emptyexamplesフォルダをコピーしてペースト。フォルダの名前をPhysicsTestとする。その中にaddonsというフォルダを作り、ダウンロードしたフォルダの中からofxMSAPhysicsとofxObjcPointerをコピーしてaddonsフォルダの中にペースト。srcフォルダ以外を消しておく。
ofxObjcPointerはメモリ管理に使っているらしい。

xcodeprojファイルを開いて、Finderからaddonsフォルダをドラッグして「Groups & Files」にドロップ。日本語環境だと「グループとファイル」。僕は調子こいて英語にしています。

ダイアログが出てくるので多分そのままOKすればいい。上の方にフォルダをコピーするかどうかチェックする項目があるけど、今回はプロジェクト内に既にコピーしてあるのでチェックは外しておく。ラジオボタンは「Recursively Create Groups for any added folders(追加したフォルダに再帰的にグループを作成する)」方で。src以外を消したのはここで変なことにならないため。

これで準備完了。

3.コードを書く
examplesの中身をコピーしてもいいですが、複雑なので使い方を覚える意味でも必要そうなところを抜き出して改変しました。マウスをクリックしたらボールが落ちてくるサンプルです。キーボードを押すと消えます。

ofxMSAPhysics physics;
でofxMSAPhysicsクラス型を宣言して、physics.makeParticle(x,y,z)でパーティクルの生成。
p->xとかが何なのかわからない場合はSBAW09の第11回目とかOF for Processing usersとかOoops!を参照。

ソースコードがうまく貼付けられなかったのでプロジェクトごとアップしました。
physicsTest.zip
---
*2.についてもう少しましなやり方を後日知った

木曜日, 4月 02, 2009

actionscript3でglitchする

glitchlena
参考にしたのはこのforum。
Processing 1.0 - glitch art

ヘッダになっているであろう位置をとばして適当な位置のデータを置き換える。
ヘッダの位置予想は適当。ヘッダがあれば、何でもできる。
バイナリのいじり方はflash oopを参考にした。

本当はhex editorみたいに全部展開してちゃんと狙ってglitchさせたいけど、イベント処理が重く分割させる必要がある。これもflash oopにイベントを分割してドラゴン曲線を描くライブラリの作り方が書かれているので参考にするつもり。


package {
import flash.display.Sprite;
import flash.display.Loader;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
import flash.net.URLStream;
import flash.utils.ByteArray;

public class LoadBinaryURLStream extends Sprite {
private var stream :URLStream;
private var request:URLRequest;
private var data:ByteArray;
private var loader:Loader;
public function LoadBinaryURLStream(){
data = new ByteArray();
request = new URLRequest("img/pic.jpg");
loader = new Loader();
addChild(loader);

stream = new URLStream();
stream.addEventListener(Event.COMPLETE, onComplete);
stream.addEventListener(ProgressEvent.PROGRESS, onProgress);

stream.load(request);
}

private function onComplete(e:Event):void {
loader.loadBytes(data);
}

private function onProgress(e:ProgressEvent):void {
stream.readBytes(data, data.length);
if(data.length > 1024) {
data.position = Math.floor(Math.random()*data.length)-1;
if(data.position<1024) {
data.position += 1024;
}
data.writeByte(0);
}
}
}
}

金曜日, 3月 20, 2009

as3corelibのJSONクラスを使ってNew York TimesのAPIからデータを取得する2

JSONというのが何なのかというのが今回の話題。

詳しくは公式ドキュメントなりwikipediaなりを読むとして、とりあえずはXMLなどのようなデータフォーマットの一種であると。JavaScript Object Notationが正式名称だけど、JavaScriptのオブジェクトの表記をベースにしているというだけで、JavaScript以外でも使える。
"キー":値というシンプルな形。入れ子にもできる。
例:

{
"name":"hayashi",
"age":26,
"occupation":[
{"main":"designer"},
{"sub":"programmer"}
]
}


前回のプログラムで、loaderから読み取ったデータをそのまま出力してみる(loader.dataをtraceする)と、このような形式の文字列が出力されているはず。

で、あとはXMLと同じようにドットとキーで欲しい値にアクセスする。
前回のソースの27行目を下のように一旦オブジェクト型の変数に格納する形にして、
var o:Object = JSON.decode(loader.data);

o.tokensで何てキーワードで検索したかとか、o.totalで何件ひっかかったとかが取得できる。

o.resultsはリクエストに合致した記事のデータがそれぞれ配列になっていて、o.results[0].titleで1件目の記事のタイトルを取得したり、o.results[2].bylineで3件目の記事の筆者を取得したりできる。o.results.lengthで結果の総数を得てfor文と一緒に使うケースが多いと思う。

この辺のキーの与え方に関しては返ってきたデータ(loader.dataでtraceした結果)を見ながらの作業になる。

視覚化の方法についてはまた次回。

actionscript2とpapervision3D

papervisionXがどうとか騒がれている2009年の3月ですが、Flash Player8(もしかすると7)で3Dっぽいものを動作させなければならないのでpapervisionについて調べてる。
が、古い情報はなかなか見つからない。検索結果と見られるページ全部をある時期に戻せたらいいのに。メディアアートに文化財保存修復学科的なものがあればいいのに。

svnからpapervision3Dを全部check outすると、一応as2のsrcもあるのだけど、as3用のpritivesのようなSphereやCylinderがない。wikiにあるとの情報だったが、wikiもう見られない。

3Dに関しては全然知識がなく、ここ数日でわかったことは、立体を作るためには三角形をひたすら組み合わせるということ。

自分で書くのは大変そうなのでinternet archiveで探してサルベージ。

objectフォルダに入れておく。とりあえずSphereは動いた。
ファミコンで鉄拳2とか観て自分を奮い立てる。

import org.papervision3d.cameras.Camera3D;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.scenes.Scene3D;

import org.papervision3d.objects.Sphere;

var container:MovieClip;
var scene:Scene3D;
var camera:Camera3D;
var sphere:Sphere;

init3D();
this.onEnterFrame = loop3D;

function init3D():Void {
container = this.createEmptyMovieClip("container", this.getNextHighestDepth());
container._x = 275;
container._y = 200;

scene = new Scene3D(container);

camera = new Camera3D();
camera.z = -2000;
camera.zoom = 1;
camera.focus = 500;

var material:WireframeMaterial = new WireframeMaterial(0xffffff);

sphere = new Sphere(material, 400, 10, 10);

scene.push(sphere);
}

function loop3D():Void {
sphere.rotationY = container._xmouse / 2;
sphere.rotationX = container._ymouse / 2;

scene.renderCamera(camera);
}

火曜日, 3月 03, 2009

as3corelibのJSONクラスを使ってNew York TimesのAPIからデータを取得する

ProcessingでNew York TimesのAPIからデータを取ってきて視覚化するサンプルを参考に、ActionScript 3.0で実現してみます。
Processing, JSON & The New York Times | blprnt.blg

環境はMac OS 10.5.6、Flex SDK 3、Xcode 3.1です。

まずNew York TimesのDevelopper Networkにアクセスしてアカウントを作成し、API KEYを取得する必要があります。
Times Developer Network - Welcome

色々ありますが今回はThe Article Search APIを使います。
レスポンス形式はJSON。

ActionScriptでJSONを扱うには、as3corelibを使うのが良いと思います。
as3corelib - Google Code
ファイルをダウンロードして解凍したら、libというフォルダにas3corelib.swcというファイルがあるので、それをFlex SDKのframeworksフォルダに入っているlibsの中に入れます。

新しいプロジェクトを作って、NYTimesTestと名付けます。
2005年1月1日から2009年3月3日まででObamaという言葉がいくつあるかというプログラム。

NYTimesTest.as

package {
import com.adobe.serialization.json.JSON;

import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;

public class NYTimesTest extends Sprite {
private var baseURL:String = "http://api.nytimes.com/svc/search/v1/article";
private var apiKey:String = "取得したAPIキー";
private var word:String = "Obama";
private var beginDate:String = "20050101";
private var endDate:String = "20090303";

public function NYTimesTest() {
var loader:URLLoader = new URLLoader();

loader.load(new URLRequest(baseURL+"?query="+word+"&begin_date="+beginDate+"&end_date="+endDate+"&api-key="+apiKey));
loader.addEventListener(Event.COMPLETE, decodeJSON);
loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
}

private function decodeJSON(e:Event):void {
var loader:URLLoader = URLLoader(e.target);
var totalArticles:uint = JSON.decode(loader.data).total;
trace("there were " + totalArticles + " occurences of the term " + word + " between " + beginDate + " and " + endDate);
}

private function ioErrorHandler(e:IOErrorEvent):void {
trace("ioErrorHandler: " + e);
}
}
}

Flash CSを持ってなくてFlex SDKで開発している場合、Flash Playerで普通に再生しても何も起こらないと思います。Flash Playerのdebugger versionsと、その他色々と設定が必要です。
Archived Flash Players available for testing purposes
flickr APIの時にやった色々設定(今気付いたけど01って何...続きないし)
hysysk:blog: using flickr api 01

フォルダはアカウントの権限とか環境によって変わるのかも。

今の僕の環境では

ユーザ名/ライブラリ/Preferences/Macromedia/FlashPlayer

の中に#Securityというフォルダがあり、その中にFlashPlayerTrustフォルダを置いて、mms.cfgを格納しています。ない場合は作って下さい。
最近は通信関係を開発しているフォルダはまとめてこのファイルで指定しています。

traceした結果はこのFlashPlayerフォルダの中のLogs/flashlog.txtに出力されています。これもない場合は作って下さい。
there were 9595 occurences of the term Obama between 20050101 and 20090303
と出れば成功。
次回(!)以降データの中身をもう少しみていくつもり。

あとこのblprintの人が書いてるActionScriptの本が面白そう。彼だけでなくJonathan HarrisとかAaron KoblinとかProcessingの強者達が書いてる。値段が変動してるな。
Amazon.co.jp: Best Practice: The Pros on Adobe Flash: Douglas Easterly: 洋書

土曜日, 2月 14, 2009

E15:oGFx

alpha版出た(Mac OS10.5のみ)。
http://ogfx.mitplw.com/
pythonベースで、processingとかnodeboxみたいな感じで書ける。
アニメーションを実行させながらコードを書き換えられるon the flyなスタイル。

今のところスクリプトの保存はwebに。
http://e15web.media.mit.edu/users/52
この仕組みいい。
見るためには登録しないといけないかも。

保存したらすぐスクリーンショットができてページが作られてる。
そういうところがどうなってるのか気になったり。

何かエラー出た後直してもちゃんと動かなかったり、deleteしたらポインタが変なとこに行ったりして不安定なところがある気がするけど、楽しい。新鮮。
あと止め方がわからない。

日曜日, 11月 23, 2008

forward kinematics

関節みたいな動きのプログラミング。
ActionScript 3.0アニメーションからporting。
PVectorクラスを使ってみた。
Processing Monster作りたい。

walking.pde

Segment s1, s2, s3, s4;
float cycle = 0;
float offset = -PI*0.5;

void setup() {
size(200, 200);
smooth();
frameRate(30);
fill(255);
s1 = new Segment(width*0.5, height*0.5, 30, 10);
s2 = new Segment(s1.getPin().x, s1.getPin().y, 30, 10);
s3 = new Segment(width*0.5, height*0.5, 30, 10);
s4 = new Segment(s3.getPin().x, s3.getPin().y, 30, 10);
}

void draw() {
background(255);
walk(s1, s2, cycle);
walk(s3, s4, cycle+PI);
cycle += .2;
}

void walk(Segment segA, Segment segB, float cyc) {
float angleA = sin(cyc) * HALF_PI*0.25 + HALF_PI;
float angleB = sin(cyc+offset) * HALF_PI*0.17 + HALF_PI*0.12;
segA.rotation = angleA;
segB.rotation = segA.rotation + angleB;
segB.x = segA.getPin().x;
segB.y = segA.getPin().y;
segA.render();
segB.render();
}

Segment.pde

class Segment {
float x;
float y;
float w;
float h;
float rotation;
PVector v;

Segment(float x, float y, float w, float h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
v = new PVector();
}

void render() {
pushMatrix();
translate(x, y);
rotate(rotation);
rect(0, -h*0.5, w, h);
ellipse(0, 0, 2, 2);
ellipse(w, 0, 2, 2);
popMatrix();
}

PVector getPin() {
v.x = x + cos(rotation) * w;
v.y = y + sin(rotation) * w;
return v;
}
}

火曜日, 11月 04, 2008

build ribbons

erik natzkeのflash on the beachの発表なのかな。jonathan harrisへのレスポンスと一緒に上げられてた気がするけど。
Untitled Document
Flash on the Beach and “The Jonathan Harris Affair” | THOMAS KRÄFTNER

これのParticlesのソース見て、動かしてみて、この書き方がいいのかどうかは知らないけどprocessingでもループ内でnewしてParticlesを生み出したいと思った。最初に思いついたのが配列を使って実現する方法。サイズの宣言と値を代入する必要があるので、適当に埋めてやってたんだけど、ださい(し、これでは意味がない。最初に決まった数のオブジェクトを作るんじゃなくて、ループの度に増やしたい)。

とりあえずParticleクラス
Particle.pde

class Particle {
float x;
float y;
float vx;
float vy;
float rad;

Particle(float x, float y, float vx, float vy, float rad) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.rad = rad;
}
void draw() {
x += vx;
y += vy;
ellipse(x, y, rad, rad);
}
}

実行するメインのコード。
particleTest1.pde

Particle[] p = new Particle[500];
int idx = 0;
float rad = 10;
void setup() {
size(800, 400);
fill(0);
smooth();
for(int i=0;i<p.length;i++) {
p[i] = new Particle(0,0,0,0,0);
}
}

void draw() {
background(255);
spawnParticles();
drawParticles();
}

void spawnParticles() {
if(idx>p.length-1) {
idx = 0;
}
float vx = random(-1, 1);
float vy = random(-1, 1);
p[idx] = new Particle(mouseX, mouseY, vx, vy, rad);
idx++;
}

void drawParticles() {
for(int i=0;i<p.length;i++) {
p[i].draw();
}
}


actionscript3の場合は描画されるオブジェクトはディスプレイリストで管理されるから、addChildでひたすらオブジェクトを追加しつつ増え過ぎたら削除、みたいな書き方ができる。
processingでもそんな方法はないのかなと思ったらサンプルにあった。
ArrayListClass \ Learning \ Processing 1.0 (BETA)

これはBallクラスにlifeプロパティをもたせてあり、255回ループで呼ばれたらfinished()メソッドがtrueを返して、ballsから削除されるようになってる。

(Example>Topics>Simulate>MultipleParticleSystemsとかもいい。nature of codeでやったVector3DクラスがPVectorクラスとして組み込まれてる。各メソッドについてもサンプルがついてて親切。)


for (int i = balls.size()-1; i >= 0; i--) {

は毎回balls.size()を参照しなくてもいいようにするかっこいい書き方。

というのを参考にしつつ、一定数超えたら削除していく方法で書き直したのがこれ。前出のParticleクラスはそのまま使える。
ArrayList使った思い通りの方法。
particleTest1_2.pde

ArrayList particles;
float rad = 10;
void setup() {
size(800, 400);
fill(0);
smooth();
particles = new ArrayList();
}

void draw() {
background(255);
spawnParticles();
drawParticles();
}

void spawnParticles() {
float vx = random(-1, 1);
float vy = random(-1, 1);
particles.add(new Particle(mouseX, mouseY, vx, vy, rad));
if (particles.size()>500) {
particles.remove(0);
}
}

void drawParticles() {
for(int i=particles.size()-1; i >= 0; i--) {
Particle p = (Particle)particles.get(i);
p.draw();
}
}


(11/7修正)重力のための変数gravityを削除。まだ関係ないので。

日曜日, 11月 02, 2008

non-formatize

六本木のTSUTAYAでお洒落なデザイン本などを眺めていたら発見したnon-formatの作品集。
これの左上。
で大体やりたいことはわかると思うけど、やってみました。

輝度が低い、暗いとこは振幅を大きくして、線が重なることで濃くしてある。だけ。
オリジナルに近づけるにはもうちょっと詰める必要あるな。元画像の作り方にも左右されると思うけど。

モナリザの画像探してる時に見つけたこんなんもある。錯視とかもっと勉強したい。

トラック毎に切り分けて音で聴けるようにしたいところだけど、それはまたいずれ。
最新版(0154)だとminim音鳴らないし。
Processing 1.0 (BETA) - Minim problem... I can't hear ANYTHING

flashでもできるな。BitmapDataクラスでgetPixel()して、値をSampleDataEventに渡す感じだろうか(地味に昨日flashでsine wave鳴らすの直した)。ファイル書き出しもできるからwaveファイルとかも作れるし(miztにソースいただきました)。

ビジュアルからインスパイアされて誰にでも説明できる方法で音作りに持っていけるようになったのはよかったよね。

scriptographerでやりたい。

PImage img;
int x = 0;
int y = 0;
int imgW;
int imgH;
float val;
float amp;

background(255);
colorMode(HSB, 255);
img = loadImage("lisa.jpg");
imgW = img.width;
imgH = img.height;
size(imgW*2, imgH);
image(img, 0, 0);

loadPixels();
for(y = 0; y < imgH; y++) {
for(x = 0; x < imgW; x+=5) {
val = brightness(pixels[y*imgW*2+x]);
amp = (255-val)*0.05;
stroke(100, amp+100);
line(imgW+x-amp, y, imgW+x+amp, y);
}
}
saveFrame("nonformatize.jpg");

日曜日, 10月 12, 2008

sketch20081012


ドキュメントの左下(0, 0)から選択したオブジェクトのパスにアンカーポイントを追加して線を引く。curvesToPoints()の第二引数がよくわからない。

var sel = document.getMatchingItems(Path, { selected: true });
for(var i=0; i<sel.length; i++) {
var art = sel[i];
art.curvesToPoints(10, 1);
for(var j=0; j<art.curves.length; j++) {
var p = new Path();
p.moveTo(art.curves[j].point1);
p.lineTo(0,0);
}
}

水曜日, 9月 24, 2008

scriptographer Timer class

Helpより。
1秒毎に円を描いてx位置が500pixelを超えたら止まる。
timerTest.js

var x = 0;
var timer = new Timer(1, true);
timer.start();
timer.onExecute = function() {
document.createCircle(x, 100, 10);

if(x>500) {
timer.stop();
}
x+=10;
}

月曜日, 9月 22, 2008

drawCircles

scriptographerで円を描く。Documentクラスが持ってる関数を使う。

document.createCircle(x, y, radius);

xとyを中心点とした半径radiusの円が描かれる。
他にも興味深い関数がいくつかあるのでまた試す。

ランダムに色を選びつつ透明度と線の太さを変更。
こういうのは手作業やブレンドツールでやろうとしても難しいのではないかと思う。

drawCircles.js

var radius=10;
var xOff=250;
var yOff=450;
for(var i=0; i<10; i++) {
for(var j=0; j<10; j++) {
var circle = document.createCircle(xOff+i*radius*2, yOff+j*radius*2, radius);
circle.style.fill.color = new RGBColor(Math.random(),Math.random(),Math.random());
circle.style.stroke.color = new RGBColor(Math.random(),Math.random(),Math.random());
circle.style.stroke.width = (i+j)/2;
circle.opacity = (i+j)/20;
}
}

再びscriptographerに興味を持ち出したのはjonathan puckeyのDelaunay Rasterがかっこよすぎたからで、これこのままvjできるっていうか、昔illustratorでプレゼンやって怒られたり怒られなかったりしたんだけど、illustratorで絵を描くことがそのままパフォーマンスになる。scriptographer0.5だと他のオブジェクトに跳ね返りながらパスを描いていくスクリプトがあって、それも同じような面白さがあった。Timerクラスが変わったみたいで実装方法がわからない。

今のところforumを読むのが一番勉強になりそう。
来年jonathanが授業でscriptographerやるって言ってるのが楽しみ。

情報少ないけど、その分キレキレで純度が高いアウトプットに出会える。

日曜日, 9月 14, 2008

getting started with scriptographer

scriptographer、色々エフェクトを試す分にはいいけど、自分で一からコードを書く場合どこから始めればわからなかったので、ちょっと調べた。環境はCS3。

General Scriptsに分類される、三角のPlayボタンを押して実行するタイプのものから。scriptsフォルダのscripts以下に入るやつ。

illustratorを起動して、書類のアイコンをクリック。drawline.jsという名前をつけて、scriptsフォルダの中に保存。Mainのコンソールのscriptsの中にdrawline.jsが出来ているはず。ダブルクリックすると何かしらのエディタが立ち上がる。

色々と他のソースを読むと、線を描くにはどうやらPathクラスを使えばよさそう。
Pathクラスのインスタンスを作る。

var p = new Path();


actionscriptと同じように、描画する点へ移動する場合moveTo(x, y)を使う。ペンを置くイメージ。

p.moveTo(0, 0);


目的の点まで線を引くのはlineTo(x, y)。ここが次の線の開始点にもなる。置いたペンを動かすイメージ。

p.lineTo(100, 100);

この3行を書いて保存。Reloadボタン(矢印が2つ回転してるやつ)を押して、Playボタンを押す。
アートボードの左下から右上に向かって線が引かれたはず。

3行目を少し書き換えてみる。

for(var i=0;i<100;i++) {
p.lineTo(i*5, Math.random()*100);
}

とか。
オブジェクトに対して「フィルタ>パスの変形>ラフ」でギザギザ選ぶのと同じような感じ。コードと手作業でうまく行き来ができると嬉しい。

ちなみに多分scriptographer入れたせいで、illustratorで印刷をするとconsoleにエラーが表示されて、tabを2回押さないとアクティブにならなくなりました...。

土曜日, 8月 09, 2008

Vectors

nature of codeをちゃんとやろうと思った。何となく読んだりコード書き換えてみたりはしてたんだけど、いくつか勉強しておきたい項目を取り上げて書くつもり。まずはVectorsから。実はVector3Dクラスが何をしてるのかとかよく理解してなかった。

motion 101のメインになる部分(hellomotion.pde)とThingクラスの余計なところを削って円の動きだけに注目。Vector3Dクラスを使うにはVector3D.javaをAdd File...でスケッチフォルダに追加するかライブラリを入れてimport noc.*;と書いておく必要がある。

vec3dmotion.pde

Thing t;
void setup() {
t = new Thing(new Vector3D(0.01, 0.01), new Vector3D(0, 0), new Vector3D(0, 0));
}

void draw() {
background(204);
t.go();
}

Thing.pde

class Thing {
Vector3D loc;
Vector3D vel;
Vector3D acc;

Thing(Vector3D a, Vector3D v, Vector3D l) {
this.acc = a.copy();
this.vel = v.copy();
this.loc = l.copy();
}

void go() {
update();
borders();
render();
}

void update() {
vel.add(acc);
loc.add(vel);
}

void borders() {
if(loc.x > width) {
loc.x = 0;
}
if(loc.x < 0) {
loc.x = width;
}
if(loc.y > height) {
loc.y = 0;
}
if(loc.y < 0) {
loc.y = height;
}
}

void render() {
ellipse(loc.x, loc.y, 10, 10);
}
}


位置は点(Points)であり、速度/加速度はベクトル(Vectors)。コーディングをシンプルにするために、これらを全てベクトル(大きさと方向)として扱う。

setup()メソッドの中でThingクラスのインスタンスを作る時に、Vector3Dのインスタンスを生成して値を渡してるんだけど、この時の引数が2つ(new Vector3D(x,y))だと2次元、3つ(new Vector3D(x,y,z))だと3次元になる。実際には2つの場合はzに0が入るというだけなのでVector3Dのインスタンスは常にx,y,zで3次元の値を持ってるんだけど。

Thingクラスのコンストラクタではcopy()メソッドを使って、先ほど生成されたVector3Dクラスのインスタンス変数からThingクラスのインスタンス変数に値をコピーして格納してる。

加速度から速度を導いて、速度から位置を導く、という流れ。

Vector3D使わないとすればこうなる。
normalmotion.pde

Thing t;
void setup() {
t = new Thing(0.01, 0.01, 0, 0, 0, 0);
}

void draw() {
background(204);
t.go();
}

Thing.pde

class Thing {
float x;
float y;
float vx;
float vy;
float ax;
float ay;

Thing(float ax, float ay, float vx, float vy, float x, float y) {
this.ax = ax;
this.ay = ay;
this.vx = vx;
this.vy = vy;
this.x = x;
this.y = y;
}

void go() {
update();
borders();
render();
}

void update() {
vx += ax;
vy += ay;
x += vx;
y += vy;
}

void borders() {
if(x > width) {
x = 0;
}
if(x < 0) {
x = width;
}
if(y > height) {
y = 0;
}
if(y < 0) {
y = height;
}
}

void render() {
ellipse(x, y, 10, 10);
}
}

これはこれでわかりやすい。けど多分後々Vector3Dが効いてくるんだと思う。

ベクトルとかの数学的な概念とか、コード使ったアニメーションで勉強になるのは『ActionScript 3.0 アニメーション』。
スクリプトだけで全部やるからflash持ってなくても動くものが作れる。flex環境のセットアップとかも丁寧に書いてあるしその辺は検索すれば出てくる。値段は高いけど、夏休み(もう大分過ぎてますが)にこれ1冊やると思えばどっか遊びに行くより楽めるし安い。続編も出るらしいし。

processingとActionscript3.0の行き来はそれほど苦ではないと思うので、両方読み書きできるといいと思う。既に使えるソースコードが沢山公開されてる訳だし。

今までは使えそうなコードを集めて勘でプログラミングしてたんだけど、細かい調整できるようにそろそろスクラッチでも色々ちゃんと書けるようになりたい。DJからトラックメイカーへ。

自前のblog環境整えないとな、と思う。かゆいところに手が届かないストレスで投稿が減ってるってのもあるから、何とかしたい。

火曜日, 7月 22, 2008

using flickr api 01

flickrから画像を取得する方法。提供されてるAPIを使う。使用の際に必要となるAPIキーはここで取得。
http://www.flickr.com/services/api/keys/

よく使われてるのはこのライブラリらしい。
as3flickrlib - Google Code

ライブラリ使わなくてもある程度は自分でできる。
[Think IT] 第4回:外部API(Flickr)を試す! (1/3)

MVCモデルを使ってとか、僕にはまだわかりません。
下にあるコードは手っ取り早く使う場合とか、前段階として。
慣れだと思うけど、一回散らかさないと片付け方がわからない。

とりあえず、ブラウザに直接URLを入力してみると、xmlが返ってくる。
例えば、「test」というキーワードで全文検索して10件取得した1ページ目だったらこんな感じ(見やすいように改行入れてますが本来は一行です)。

http://api.flickr.com/services/rest/
?method=flickr.photos.search&api_key=取得したAPIキー
&text=test&page=1&per_page=10


結果。


他のを試したければここに出てるargumentsから選んで&でつないで=で代入すればいい。
&tags=music
とか。
Flickr Services: Flickr API: flickr.photos.search

ここまでくれば、あとは普通にxmlの処理するのと一緒。
SSAW07 » 第5回:ActionScript 3.0応用 I - 外部イメージの読み込み

Make your own Flickr search engine with Flash and AS3 | The Tech Labs

thinkitにも書かれているように、crossdomain.xmlをロードするのを忘れずに。

さらに、flash CS3とかで動かしてるブルジョアは大丈夫かも知れませんが、普通にflash player落としてXcodeとかで開発してる場合、セキュリティのエラーが出ると思う。

FlashPlayerTrustというフォルダを作り、Macintosh HD/Library/Application Support/Macromedia/に保存。その中にcfgファイルを作る(名前は何でもいいそうです。とりあえずmm.cfgとかにしておく)。
cfgファイルに目的のswfやフォルダのパスを設定する。こういう話題はどこに書いてあるかというと、ここからダウンロードできるpdfです。そんなん知らんよね。
Adobe - Developer Center : White paper: Adobe Flash Player 9 security

これもどうやって辿り着けたのか思い出せないが、とにかくここのドキュメントはダウンロードしていつでも参照できるようにしておく。
Adobe Flex resources

testで全文検索した結果から10枚表示。マウスクリックで表示順変更。
YOUR API KEYの部分を取得したAPIキーと差し替えないと実行した時にエラーが出て表示されません。

package {
import flash.display.MovieClip;
import flash.display.Stage;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Bitmap;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.display.Loader;
import flash.system.LoaderContext;

public class TestFlickr extends MovieClip {
private var APIkey:String;
private var text:String;
private var searchURL:String;
private var startPage:uint = 1;
private var pageValue:uint = 10;

public function TestFlickr() {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(MouseEvent.CLICK, onMouseClick);
init();
}

private function init():void {
//your API key
APIkey= "YOUR API KEY";
//search word
text = "test";

search();
}

private function search():void {
while(this.numChildren > 0){
this.removeChildAt(this.numChildren-1);
}
setSearchURLString();
}

private function setSearchURLString():void {
var baseURL:String = "http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=" + APIkey;
searchURL = baseURL + "&text="+ text + "&page=" +startPage + "&per_page=" + pageValue;
trace(searchURL);
startXMLLoad();
}

private function startXMLLoad():void {
var req:URLRequest = new URLRequest(searchURL);
var XMLLoader:URLLoader = new URLLoader();
XMLLoader.addEventListener(Event.COMPLETE, onXMLLoadComplete);
XMLLoader.load(req);
}

private function onXMLLoadComplete(e:Event):void {
var imgLoader:URLLoader = URLLoader(e.target);
var xmlData:XML = XML(imgLoader.data);

var xmlList:XMLList = xmlData.photos.photo;
for(var i:uint = 0; i < pageValue; i++) {
var farm:String = xmlList[i].@farm;
var server:String = xmlList[i].@server;
var id:String = xmlList[i].@id;
var secret:String = xmlList[i].@secret;
var imgURL:String = "http://farm" + farm + ".static.flickr.com/" + server + "/" + id + "_" + secret +".jpg";
trace("URL:" + imgURL);
var imgReq:URLRequest = new URLRequest(imgURL);
var loader:Loader = new Loader();

loader.contentLoaderInfo.addEventListener(Event.INIT, loadImageInit);
loader.load(imgReq, new LoaderContext(true));
}
}

private function loadImageInit(e:Event):void {
var bitmap:Bitmap = e.target.content;
addChild(bitmap);
}

private function onMouseClick(e:MouseEvent):void {
setChildIndex(getChildAt(0), numChildren - 1);
}
}
}

日曜日, 5月 25, 2008

adobe made some noise

BIT-101のコード試してもSamplesCallbackEventがどこにあるのかわからず発狂しかけた。
Astro Dynamic Sound! » BIT-101 Blog
Joa Ebertがフルコードをzipでくれ!てるからそれ参考にした。
Simple Astro synthesizer at blog.je2050.de - Blog of Joa Ebert

最新のsdkをダウンロードしてパスを通す。
Download Flex 3 - Flex SDK - Confluence

flex-config.xmlも書き換えておくこと。
Targeting Flash Player 10 Beta with Flex SDK 3.0.x
osxのスタンドアローンのflash playerはないのかな。
コンパイルしたらとりあえずブラウザにdrag & dropしてる。

SDKの中にruntime/playerフォルダがあって、各OS毎のflash playerインストーラーがある。

そのうち環境構築も含めてまとまった記事を書く。

(11/1)書き直しました。不要なimportをなくして、akihiro kamijo: Flash Player 10 の動的サウンド生成機能 (Sound クラス)を参考にサンプル数を増やした。
さて、イベントハンドラ内では 2048 以上 8192 以下のサンプルデータを書き込みます。パフォーマンス上はできるだけ多くのサンプルデータを (つまり 8192 個) 書くのが有利と考えられます。


package {
import flash.display.Sprite;
import flash.media.Sound;
import flash.events.Event;
import flash.events.SampleDataEvent;

public class SoundTest extends Sprite{
private var sound:Sound;
private var freq:Number = 440;
private var rate:Number = 44100;
private var phase:Number = 0;

public function SoundTest() {
init();
}

private function init():void {
sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, sineWaveGenerator);
sound.play();
}

private function sineWaveGenerator(event:SampleDataEvent):void {
for(var i:int = 0; i < 8192; i++) {
phase += freq / rate;
var phaseAngle:Number = phase * Math.PI * 2;
var sample:Number = Math.sin(phaseAngle)*0.25;
event.data.writeFloat(sample);
event.data.writeFloat(sample);
}
}
}
}