Code/NodeBox

David Hirmes - lines14

maetel 2007. 7. 31. 18:46
The mission:

David Hirmes - lines14

from Flash Math Creativity


첫번째 시도... 실패
s = 300
r = 10

size(s, s)
speed(10)

from math import cos, sin, atan, sqrt

def setup():
    global x
    global y    
    global f   
    global g
            
    x = range(s)
    y = range(s)    
    for i in range(s):
        x[i] = random(s)
        y[i] = random(s)

    f = 0
    g = 0
   

def draw():
    global x
    global y
    global f 
    global g
      
    dd = (x[f+1] - x[f])**2 + (y[f+1] - y[f])**2
    d = sqrt(dd)

    ta = atan(y[f+1]/x[f+1]) - atan(y[f]/x[f])
#    ta = atan((y[f+1]-y[f]) / (x[f+1]-x[f]))
    a = g * ta/r
    
    rx = d*cos(a)
    ry = d*sin(a)
    
    for k in range(f):
        stroke(0)
        line(x[k], y[k], x[k+1], y[k+1])        
        line(x[f], y[f], x[f]+rx, y[f]+ry)


    g += 1
        
    if g > r:
        g = 0
        f += 1

아웅~
인덱스가 꼬여 있고, ta가 잘못되었다. (원인은 아는데 해결을 못하고 있다.)
+ 회전하는 line을 그릴 때 (또는 계산할 때) translate를 활용할 수 있음을 기억할 것.


python에서의 삼각함수 테스트:
## testing trigonometry

from math import cos, radians, degrees

a = range(13)
for i in range(13):
    a[i] = 30*i
    x = a[i]
    print x, ":", cos(radians(x)), ":", cos(degrees(x)), ":", cos(x)

결과:
0 : 1.0 : 1.0 : 1.0
30 : 0.866025403784 : -0.912188068927 : 0.154251449888
60 : 0.5 : 0.664174146187 : -0.952412980415
90 : 6.12323399574e-17 : -0.299515394756 : -0.448073616129
120 : -0.5 : -0.117745407075 : 0.814180970527
150 : -0.866025403784 : 0.514327305764 : 0.699250806478
180 : -1.0 : -0.820581056609 : -0.598460069058
210 : -0.866025403784 : 0.982721193088 : -0.883877473182
240 : -0.5 : -0.972272038226 : 0.325781305535
270 : -1.83697019872e-16 : 0.791068712954 : 0.984381950633
300 : 0.5 : -0.470934845091 : -0.0220966192787
330 : 0.866025403784 : 0.0680935809118 : -0.991198821755
360 : 1.0 : 0.346706540931 : -0.283691091487
  
radians이군. 그래, 전에도.
그러나... arctangent 값은 이미 radians이므로 필요없다. (원래 알았었는데 괜히 몇 시간 허비... ㅡㅜ)


회전만 시험하면서 여전히 헤맨다. 역시나 회전 각도 da가 문제인데,
dx와 dy의 부호 때문이다. phase를 잡아 주어야 하는 것.
상식적인데 잘 안 된다. 고등학교 때였으면 바로 됐을 텐데... orz


(몇 십분이 흐른 후...) 2pi 잖아! 바보다...
이제 회전은 의도대로 된다. 몇 가지 변수명을 수정하고 정리하면 다음과 같다.
이제 갖다 붙이기만 하면...

from math import cos, sin, sqrt, acos, degrees

s = 100
size(200, 200)
speed(100)

def setup():
    global x
    global y
    global f
    global ph
   
    x = range(2)
    y = range(2)
    for i in range(2):
        x[i] = random(50,100)
        y[i] = random(s)
   
    f = 0
    ph = 0
   
def draw():
    global x
    global y
    global f
    global ph

    oval(x[0],y[0],5,5)
    oval(x[1],y[1],3,3)

    dx = x[1] - x[0]
    dy = y[1] - y[0]   

    dd = dx**2 + dy**2
    d = sqrt(dd)
   
    da = acos(dx/d)
   
    if dy < 0:   
        da = -da
        ph = 6.28
      
    r = f * (da+ph)/10   
   
    stroke(0)
    translate(x[0], y[0])
    line(0, 0, d*cos(r), d*sin(r))
        
    if f < 10:
        f += 1

cos을 통해 각도 차이를 구했으므로 dy에 대해서만 고려해 주면 된다. sin 함수 역시 2pi를 주기로 한다. 바보야. (sin(a) = sin(2pi + a))


성공!

s = 200
n = 5

size(s, s)
speed(200)

from math import cos, sin, acos, sqrt

def setup():   
    global x
    global y
    global f     
    global g
    
    x = range(s)
    y = range(s)    
    for i in range(s):
        x[i] = random(s)
        y[i] = random(s)

    f = 0
    g = 0


def draw():
    global x
    global y    
    global f    
    global g
    
    #oval(x[f], y[f], 5, 5)
    #oval(x[f+1], y[f+1], 3, 3)

    dx = x[f+1] - x[f]
    dy = y[f+1] - y[f]
        
    dd = dx**2 + dy**2
    d = sqrt(dd)
   
    da = acos(dx/d)

    if dy < 0:
        da = -da
        ph = 6.28
    else:
        ph = 0

    a = g * (da+ph)/n
    #rx = d*cos(a)
    #ry = d*sin(a)
    #print f, g, da, a
       
    for k in range(f):
        stroke(0)
        line(x[k], y[k], x[k+1], y[k+1])        
        line(x[f], y[f], x[f]+d*cos(a), y[f]+d*sin(a))
        
        
    g += 1
        
    if g > n:
        g = 0
        f += 1
        
    if f > s-1:
        f = 0