- 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
- Newer:
- Older: ≪ Color