Category:Home/tutorial/specifics (Total 5 items)
Categories - tutorial/specifics
Math
- 2008-07-07 (月)
- tutorial/specifics
原文http://nodebox.net/code/index.php/Math
しばしば、NodeBoxスクリプトのプログラミングをすると、少しの数学が関わる。
流体の動作の、行動の軌跡、内外への緩和、全て数学の定石を必要とする。
多分我々の多くは数学のクラスにおいて注意を払ってないので、このドキュメントは幾つかの有用な数学テクニックを説明する。
Math geometry
2点の座標がある場合に、この2点間の角度(もしくは距離)を知りたいことがある。
もしくは調節された1点があり、角度と距離を基にして2つめの点を知りたい時。
次のmathコマンドは手助けになるかもしれない。
またsineとcosineを基に見付けることも出来る。 http://nodebox.net/code/index.php/Math_trigonometry
2点間の角度
def angle(x0, y0, x1, y1):
from math import degrees, atan2
a = degrees( atan2(y1-y0, x1-x0) )
return a
2点間の距離
ef distance(x0, y0, x1, y1):
from math import sqrt, pow
return sqrt(pow(x1-x0, 2) + pow(y1-y0, 2))
距離と角度を基にした点の位置
def coordinates(x0, y0, distance, angle):
from math import radians, sin, cos
x1 = x0 + cos(radians(angle)) * distance
y1 = y0 + sin(radians(angle)) * distance
return x1, y1
点に関して対称
def reflect(x0, y0, x1, y1, d=1.0, a=180):
d *= distance(x0, y0, x1, y1)
a += angle(x0, y0, x1, y1)
x, y = coordinates(x0, y0, d, a)
return x, y
これらのコマンドをスクリプト内で使うにはシンプルにこれらをimportする。
from nodebox.geo import angle, distance, coordinates, reflect
いくつかの例:
randomポイントの中心からの方向
x0, y0, r = WIDTH/2, HEIGHT/2, 2
for i in range(5):
x1 = random(WIDTH)
y1 = random(HEIGHT)
oval(x1-r, y1-r, r*2, r*2)
a = angle(x0, y0, x1, y1)
transform(CORNER)
translate(x0, y0)
rotate(-a)
arrow(30, 0, 10)
reset()
x0, y0への軌跡
x0, y0, r = WIDTH/2, HEIGHT/2, 2
oval(x0-r, y0-r, r*2, r*2)
for i in range(10):
a = 36*i
x1, y1 = coordinates(x0, y0, 85, a)
oval(x1-r, y1-r, r*2, r*2)
line(x0, y0, x1, y1)
円パス上の垂直線: 点と-90度操作したものの角度
path = oval(100, 100, 105, 105)
for t in range(50):
pt = path.point(float(t) / 50)
a = angle(pt.x, pt.y,
pt.ctrl2.x, pt.ctrl2.y)
transform(CORNER)
push()
translate(pt.x, pt.y)
rotate(-a+90)
line(0, 0, 35, 0)
pop()
時々、オブジェクトの位置やサイズを、お互いに関連づけ、ある種の注文や調和があるような方法で、与えたいことがある。
例えば、サイン波は、動作を記述するのに良い。なぜなら、ゆるやかにin outする。
別の面白い比例した原則は黄金比、3-5-8ルールである。
長い長い時間、回りには美的感覚がある。
その素晴しい事柄は、数学のシリーズ、フィナボッチ配列として表すことができる。
def fib(n):
if n == 0: return 0
if n == 1: return 1
if n >= 2: return fib(n-1) + fib(n-2)
def goldenratio(n, f=4):
# Returns two proportional numbers whose sum is n.
f = max(1, min(f, 10))
n /= float(fib(f+2))
return n*fib(f+1), n*fib(f)
着色された矩形が黄金比で形成される。
w1, w2 = goldenratio(260)
h1, h2 = goldenratio(260)
b1, b2 = goldenratio(1.0)
b3, b4 = goldenratio(b1)
fill(0, b1/2, b1)
rect(0, 0, w1, h1)
fill(0, b2/2, b2)
rect(w1, 0, w2, h1)
fill(0, b4/2, b4)
rect(0, h1, w1+w2, h2)
x, y = 0, 0
w, h = 260, 260
th = h # top height
bh = 0 # bottom height
for i in range(10):
th, bh = goldenratio(th)
v = float(th)/w + 0.3
fill(0, v/2, v)
rect(x, y, w, th)
y += th
th = bh
- Comments (Close): 0
- TrackBack (Close): 0
Color
- 2008-07-01 (火)
- tutorial/specifics
NodeBoxのcolor()コマンドから返されたColorはいくつかの有用なattributeを持ち、同時に異なる色空間を考えさせる。
例えば、ランダムな色でグリッド線を描画したい時、次のようなコードを使う。:
for i in range(HEIGHT):
c = color(random(), random(), random())
stroke(c)
strokewidth(1)
line(0, i, WIDTH, i)
しかし、各lineがランダムなstrokeだと、幾つかのlineはさえなく、明るく見える傾向がある。
色を持ち上げるために、異なる色空間に切り替えせず、lineのサチュレーションを簡単に調節できる。
同じ理由から、strokewidthを1の代りに2を使用し、lineをオーバーラッピングさせ、より明るくさせる。
for i in range(HEIGHT):
c = color(random(), random(), random())
c.saturation = 1.0
stroke(c)
strokewidth(2)
line(0, i, WIDTH, i)
Color attributes
color()コマンド(さらに言えばfill()やstroke()コマンド)から返されたColorは、次にattributeを持つ:
color.r: the RGB red component
color.g: the RGB green component
color.b: the RGB blue component
color.a: the alpha component
color.c: the CMYK cyan component
color.m: the CMYK magenta component
color.y: the CMYK yellow component
color.k: the CMYK black component
color.hue: the HSB hue component
color.saturation: the HSB saturation component
color.brightness: the HSB brightness component
これらはスクリプト内でいつでも使用出来、NodeBoxは正確にcolorを計算する。
CMYK output?
出力の為に何の色空間が使われていますか?
スクリプト内でどのようなcolormode()が使用されていても、出力はoutputmode()に追随する。
これは、技術的詳細について心配する必要がないような印刷ドキュメントを働かせる時、それを簡単にし、好きなcolorに焦点を合わせることが出来る。
もっとも、全てのRGBカラーが印刷可能であるわけではないことを覚えておくこと。
Colors are stored in the graphics state
NodeBoxは最後に定義したcolorを覚えており、異なるものを定義するまで、fillやstroke colorが使っているcolorを留める。
Harmonious colors
調和のある、一貫したcolorを作る為のトリックは、完全にランダムにしないで、一定の範囲で制限する。
一般的な落とし穴は、colorを可能なかぎり全て使うことである。
これは、しばしば、一貫したデザインを作らない。
HSBカラーモードはcolorのハーモニーを作るために優秀である。
次のサンプルを考察せよ。:
colormode(HSB)
nofill()
for i in range(10):
c = color(0.5, random(0.5), random(0.5,1.0))
stroke(c)
strokewidth(random(50))
radius = random(200)
oval(random(WIDTH), random(HEIGHT), radius, radius)
色相(Hue)はいつも同じ、0.5もしくは180の色相(シアン)である。
彩度(Saturation)と明度(Brightnes)だけが少し変えられる。
これは、いつも青の色を持つことを確実にし、全てフィットする。
彩度(Saturation)は、色褪せて見えるため、0.0から0.5間で制限された。
その上、明度(Brightnes)が0.0から0.5間(50%から100%)で制限されたので、我々はブライトなcolorを得る。
これらの「color range」の素晴しいサポートを持つ colorライブラリを見よ。
画像略
Gradients
NodeBoxにおいて、lineをfor-loopで描画し、各lineの透明度を増大することによって、グラーションを作ることが出来る。
例では、color cの透明度を0.0から1.0に下げた。
(浮動小数点を得る為に、1.0で乗算していることに注意せよ。)
colormode(HSB)
c = color(0.5, 1, 1)
for i in range(HEIGHT):
c.a = 1.0 * i / HEIGHT
stroke(c)
line(0, i, WIDTH, i)
colorライブラリはより複雑なグラデーションを操縦する、手軽なgradientコマンドを持つ。
- Comments (Close): 0
- TrackBack (Close): 0
Animation
- 2008-06-19 (木)
- tutorial/specifics
原文http://www.nodebox.net/code/index.php/Animation
NodeBoxはPDFや画像書き出すだけでなく、アニメーションも操作し、QuickTimeムービーで書き出せる。
描画と同じ構文を使い、スクリプトをアニメーションに変えることが出来、それば素晴しく、活気のあることだ。
The speed(), setup(), and draw() commands
アニメーションを動かす為に3つの事が必要である。:
- speed(): speed()コマンドはアニメーションの毎秒毎のフレーム数(frames per second, fps)を示す。注意点として、この値は最大値であるということ: より作業が必要な大きなアニメーションでは設定値より遅く動く。
- setup(): setup()定義により、global変数を宣言したり、それらを初期化する。
- draw(): draw()定義により、実際の描画をする。
Templating(Commands)チュートリアルより、Commandsの定義についてあなたは既に少ししっているかもしれない。
setup()コマンドはアニメーションの開始において一度だけ実行される、そしてdraw()はアニメーション内の各フレームもしくは各ステップで実行される。
上のサンプルを見なさい。(画像のため省略)
setup()の定義で何をしてるかというと、frameと命名したglobal変数を宣言している。これは後でdraw()において使われ、キャンバス上にレンダリングされたアニメーションフレームのトラックを保持する。
setup()とdraw()がコミュニケート出来ず、また共有できないので変数はglobalにしなければならない。
draw()の定義について吟味する。
それは、アニメーションスクリプトの典型例である。
draw()コマンドがNodeBoxに呼び出され、アニメーションのフレーム毎にレンダリングする。
上の例では、draw()の定義は基本的は4つのことをする。
- frame変数を1つ増やす。(これは、私のフレームカウンタである。)
- 背景を描画する為、色の付いたrectangleを使う。
- 30度回転したcurveを描画する。
- curveが流動的に歪ませるためにmathのsin()ファンクションを使う。
Fluid movement
draw()定義内の数学的なsineファンクションに注意せよ。
sineは、0.0から1.0(そして0.0へ戻る)の値をもたらす振動ファンクションで、直線的ではない。
0もしくは1にアプローチすると、ゆっくり向う。
これはアニメーションがゆるやかにin outするのに有用である。
sin()ファンクションを使うには、radians()ファンクションとともにPythonのmathパッケージをインポートする。
(sineは円周率PIと同じくラジアンと共に動作する)
上の例では、sineファンクションをラジアンでframe変数に与える。
そして、各curveで異なる数を乗算する。
各カーブは緩やかな流体歪みのvectorを与える。
sineファンクションは通常このように呼び出す。
from math import sin, radians
ease = sin(radians(x)) * y
Tips for speed optimization
- アニメーションの中で多数のlinesを使う計画であるなら、lineto()やmoveto()の単体のパスをグループ化する。 単体の大きなパスは沢山の小さいパスより高速にレンダリングされる。 全てのラインはしかしながら、同じcolorとwidthである。
- アニメーションの中で多数のtextを使う計画であるなら、setup()コマンドでtextpath()バージョンのキャッシュを作成し、draw()コマンドにおいて、text()を連続的に呼び出して描画する代りにtranslate()を使う。
- 必要な速さにspeed()コマンドを調整せよ。NodeBoxがあまりにアップデートを試みてしまう為、できるだけ高く設定することが、欠点となってしまうことがある。
- 必要な大きさにキャンパスのサイズをsize()で調節せよ。より小さいスクリーンならリフレッシュも少ないことを意味する。
Exporting as a Quicktime movie
アニメーションをQuicktimeムービーとして書き出すことができる。
NodeBoxのメニューからExport as Quicktime Movie...を選ぶか、cmd+shif+eを押す。
フレームの数とfpsを指定出来る。
NodeBoxのQuicktime機能は、Bob IppolitoによるPyQTSequenceをベースにしている。
http://undefined.org/python/
ムービは圧縮されないので巨大なサイズになる。
Quicktime Pro等で圧縮することが出来る。
…これで、あなたはwebサイトに出すムービーを持った!
- Comments (Close): 0
- TrackBack (Close): 0
Interaction
- 2008-06-18 (水)
- tutorial/specifics
原文http://www.nodebox.net/code/index.php/Interaction
NodeBoxはPDF書類や画像を出力する為に設計されており、いろいろ動かしたりインタラクティブなことをしたい場合はProcessingのようなツールを使ったほうがより良い。
しかし、NodeBoxによりインタラクティブな実験をしたいならば、いくつかのビルトイン サポートが助けになるかもしれない。
これは、あなたが既にNodeBoxでのアニメーションの作り方を知っていると仮定する。
Interacting with the mouse
NodeBoxのアニメーションでは、3つの事前に定義された変数があり、マウスカーソルの位置と、マウスボタンの状態を保持する。:
- MOUSEX: マウスカーソルの水平方向の位置
- MOUSEY: マウスカーソルの垂直方向の位置
- mousedown: マウスボタンが押しているならTrue、そうでないならFalse
通常mousedown変数はifステートメントと一緒に使う。
if mousedown:
# do stuff when the mouse is pressed
else:
# do stuff when the mouse isn't pressed
Interacting with the keyboard
3つの事前に定義された変数がNodeBoxアニメーションの最中にユーザーが押したキーを保持する。
- key: 最後に押したキー
- keycode: 最後に押したキーの整数値のキーコード
- keydown: キーが押されていればTrue、そうでなければFalse
どのようなキーでも押されている限り、keyとkeycode変数はアップデートする。
矢印キーや、バックスペースの為に、KEY_UP, KEY_DOWN_ KEY_LEFT, KEY_RIGHT, KEY_BACKSPACE がkeycodeに含まれる。
Example
面白い例が、この小さなスケッチアプリケーションである。
単にコードを走らせ、キャンバス上にいくつかものを描画する。
size(400 ,400)
speed(30)
def setup():
global path, d
path = []
def draw():
global path
nofill()
stroke(0)
autoclosepath(False)
if mousedown:
pt = Point(MOUSEX, MOUSEY)
path.append(pt)
if len(path) > 0:
first = True
for pt in path:
if first:
beginpath(pt.x, pt.y)
first = False
else:
lineto(pt.x, pt.y)
endpath()
- Comments (Close): 0
- TrackBack (Close): 0
Paths
- 2008-06-13 (金)
- tutorial/specifics
NodeBox内のパスはベジェカーブ http://en.wikipedia.org/wiki/B%E9zier_curveにより作られる。
ベジェはコンピュータグラフィックスで曲線を描画する際一般的に使われる。
ベジェカーブは始点、終点、それらの点のベクトルを説明する2つのコントロールハンドルで定義される。
最初のハンドルは前方の始点の湾曲を説明し、二番目のハンドルは後方の二番目の点の湾曲を説明する。
例:
nofill()
stroke(0)
autoclosepath(False)
beginpath(100,100)
curveto(150, 100, 200, 200, 50, 400)
p = endpath()
図(略)
パスのデフォルトの状態は、strokeの色が無く、fillがTrueでパスは閉じている。
プレーンなヴィジュアルにするにはnofill(), autoclosepath() and stroke() を使う。
Bezier math in NodeBox
NodeBoxでは、パス上のすべての点、全てのコントロールハンドルにアクセスする方法がある。
この方法は、パスをオンザフライで変形させ、(textpathI()を使って)タイプを操作出来る。
さらに、パス上で沢山のmathオペレーションをつかうことができ、(例えば、パスの中間点のx,y座標を見付ける)、異なるパスを結合したり、交差させたり出来る。
- Manipulating points on a pathhttp://nodebox.net/code/index.php/Manipulating_Paths
- Path mathematicshttp://nodebox.net/code/index.php/Path_Mathematics
- Compound paths: union, intersection, differencehttp://nodebox.net/code/index.php/Compound_paths
- Clamping pathshttp://nodebox.net/code/index.php/Clamping_paths
- Comments (Close): 0
- TrackBack (Close): 0
- Entries in this Category
- Tutorial
- Library
- Syndicate this site