这个模型展示了乌龟可以制作有趣和多样的声音,或者如果你喜欢的话,音乐。它利用一些简单的物理学原理制作了可以扭转、旋转、转动、抽搐和弹跳的“机器”。当机器的一部分接触到墙壁、天花板或地板时,它会发出声音。声音的音调取决于触碰的位置。
你可以从一个标准的机器开始,或者随机生成一个。你可以通过改变每个部分的特性来改变和构建机器。你可以坐下来让机器自己演奏,也可以使用鼠标移动它们来控制声音。
这些机器由杠杆组成。杠杆可以是不同的大小,并受到重力(与其大小成比例)和摩擦的影响。
每个杠杆都有一个或两个“钩”来连接它与相邻的杠杆。每个杠杆都会努力移动和旋转,以保持其钩连接(或至少朝向)其邻居的钩。
一些杠杆有额外的约束。一个杠杆可以固定在位置上,所以它不能移动。它也可以旋转,就好像由电机驱动一样。
规则并不完美;例如,有时杠杆会分开。尽管如此,行为通常都是令人惊讶地逼真,足以产生有趣的运动,从而产生有趣的声音。
按下SETUP...按钮之一来创建一个机器。如果你想要,首先改变NUM-LEVERS来获取更多或更少的杠杆。
按下GO来启动机器。你应该开始听到声音,尽管如果你的机器从未接触到墙壁(或天花板或地板),你将听不到任何声音。
你可以使用鼠标通过点击来选择一个杠杆,或者通过拖动来移动一个杠杆。被选中的杠杆周围有一个圆圈。
一旦你选中了一个杠杆,左侧的各种控件让你改变该杠杆的属性。这里不会详细描述它们;玩一玩,亲自看看它们的作用。
一些影响整个系统的参数位于左下角和右侧。F是摩擦力,G是重力。还有旋转的控件。
你可以使用INSTRUMENT滑块来选择乐器,让杠杆演奏不同的乐器。
如果你制作了一个特别喜欢的机器,你可以使用文件菜单上的Export World和Import World来保存并重新加载它。
杠杆遵循的简单规则产生了一些看起来非常逼真的行为。
有些机器什么也不做。其他机器做简单、重复的运动。还有一些则非常混乱。
extensions [sound]
globals [
selected ;; lever that is currently selected
dragged ;; lever that is currently being dragged
]
breed [levers lever]
levers-own [
neighbor1 neighbor2 ;; each holds an adjacent lever (or nobody)
fixed? ;; if true, lever only turns, never changes position
spin ;; -1, 0, or 1
len ;; this times SCALE slider equals size
new-xcor new-ycor ;; next values for xcor and ycor
new-heading ;; next value for heading
xvel yvel ;; x and y velocities
]
;;;
;;; SETUP PROCEDURES
;;;
to setup-begin
clear-all
set-default-shape levers "lever"
create-ordered-levers num-levers [
set heading 180
set new-xcor 0
set ycor ((who / num-levers) * world-height + min-pycor ) * -0.8
set new-ycor ycor
set fixed? false
set len 0.5
set neighbor1 turtle (who - 1)
set neighbor2 turtle (who + 1)
]
ask lever 0 [ set fixed? true ]
end
to setup-dangle
setup-begin
ask turtle (num-levers - 4) [
set len len * 2
set spin 1
]
setup-finish
end
to setup-finish
set selected last sort levers ;; select last lever
ask levers [ lever-display ]
reset-ticks
end
to setup-chaos-tentacle
setup-begin
ask levers
[ set len (num-levers - who) * 0.1
set spin (who mod 2) * 2 - 1
]
ask first sort levers
[ set new-xcor 0
set new-ycor 0
setxy 0 0
set fixed? true
]
setup-finish
end
to setup-crazy-machine
setup-begin
ask levers
[ ; choose random location, in the inner area of the world
set new-xcor (random-float 1.6 - 0.8) * max-pxcor
set new-ycor (random-float 1.6 - 0.8) * max-pycor
setxy new-xcor new-ycor
set fixed? (random 5 = 0)
set spin one-of [-1 0 1]
set len precision (0.5 + 0.5 * random 4) 1
lever-display
]
setup-finish
end
;;;
;;; RUNTIME PROCEDURES
;;;
to go
ask levers [ monitor-mouse ]
ask levers [ lever! ]
ask levers [ lever-display ]
tick
end
to lever!
ifelse self = dragged
[ ; if being dragged, then go there the mouse tells you
set new-xcor mouse-xcor
set new-ycor mouse-ycor
]
[
if not fixed?
[ set xvel (xvel * f) + ((n1x2 - x1) + (n2x1 - x2)) * 0.5
set yvel (yvel * f) + ((n1y2 - y1) + (n2y1 - y2)) * 0.5
set yvel yvel - g * len
set new-xcor xcor + xvel
set new-ycor ycor + yvel
if abs new-xcor > max-pxcor [ set xvel xvel * -0.99
set new-xcor max-pxcor * sign new-xcor + xvel
bonk! ycor ]
if abs new-ycor > max-pycor [ set yvel yvel * -0.99
set new-ycor max-pycor * sign new-ycor + yvel
bonk! xcor ]
]
]
; calculate new heading of lever
; if node2 of neighbor1 is overlapping center, keep same heading
; otherwise, find heading to hook 2 of neighbor1
let a 180 + heading
let b heading
if distancexy n1x2 n1y2 > 0
[ set a 180 + towardsxy n1x2 n1y2 ]
; likewise hook 1 of neighbor2
if distancexy n2x1 n2y1 > 0
[ set b towardsxy n2x1 n2y1 ]
; use trig to take mean of a and b
set new-heading atan (sin a + sin b)
(cos a + cos b)
+ spin * spin-speed
end
to lever-display
setxy new-xcor new-ycor
set heading new-heading
set size 2 * scale * len
let -s ""
ifelse self = selected
[ set -s "-s"
let new-label (word "selected: " who " - " (precision len 2) " ")
ask patch max-pxcor max-pycor [ set plabel new-label ]
set label (word who " - " (precision len 2) " " " ----> ")
]
[ set label "" ]
set shape (word "lever"
ifelse-value fixed? ["-f"] [""]
item (spin + 1) ["-ws" "" "-cw"]
-s)
end
;; lever procedures; these report the x and y coordinates
;; of this lever's hooks
to-report x1 report xcor - dx * scale * len end
to-report y1 report ycor - dy * scale * len end
to-report x2 report xcor + dx * scale * len end
to-report y2 report ycor + dy * scale * len end
;; lever procedures; these report the x and y coordinates
;; of our neighbor's hooks. if no neighbor, use own hook.
to-report n1x1 ifelse neighbor1 = nobody [ report x2 ] [ report [x1] of neighbor1 ] end
to-report n1y1 ifelse neighbor1 = nobody [ report y2 ] [ report [y1] of neighbor1 ] end
to-report n1x2 ifelse neighbor1 = nobody [ report x1 ] [ report [x2] of neighbor1 ] end
to-report n1y2 ifelse neighbor1 = nobody [ report y1 ] [ report [y2] of neighbor1 ] end
to-report n2x1 ifelse neighbor2 = nobody [ report x2 ] [ report [x1] of neighbor2 ] end
to-report n2y1 ifelse neighbor2 = nobody [ report y2 ] [ report [y1] of neighbor2 ] end
to-report n2x2 ifelse neighbor2 = nobody [ report x1 ] [ report [x2] of neighbor2 ] end
to-report n2y2 ifelse neighbor2 = nobody [ report y1 ] [ report [y2] of neighbor2 ] end
to-report sign [a]
ifelse a = 0
[ report 0 ]
[ ifelse a < 0 [ report -1 ]
[ report 1 ] ]
end
;;;
;;; SELECTION & DRAGGING PROCEDURES
;;;
to monitor-mouse
let mouse-here? abs (mouse-xcor - xcor) < scale / 2 and
abs (mouse-ycor - ycor) < scale / 2
ifelse mouse-here?
[ if color != white [ set color white ] ]
[ if color = white [ set color item (who mod 14) base-colors ] ]
ifelse mouse-down?
[ if dragged = nobody and mouse-here?
[ set dragged self
set selected self
]
]
[ set dragged nobody ]
end
to select-lever [which-lever]
let new lever (which-lever + [who] of selected)
if new != nobody [ set selected new ]
end
;;;
;;; SOUND PROCEDURES
;;;
to bonk! [coordinate]
sound:play-note my-instrument (pitch coordinate) 90 0.05
end
to-report pitch [coordinate] ;; lever procedure
report 16 + round (96 * (coordinate + max-pxcor) / world-width)
end
to-report my-instrument ;; lever procedure
report item ((who + instrument) mod length sound:instruments)
sound:instruments
end
; Copyright 2005 Uri Wilensky. Includes code by James P. Steiner.
; See Info tab for full copyright and license.
尝试所有不同的SETUP按钮。
尝试左侧的所有杠杆控件。
探索右侧参数的影响。
看看能否制作一些有些重复但也有些不可预测和混乱的机器。有时这些会产生最令人愉悦的“音乐”。
使用命令中心,告诉乌龟放下它们的笔(使用pen-down
命令,简写为pd
)。这会产生一些令人愉悦的图案。使用clear-drawing
(简写为cd
)开始一幅新的图画。
相同的基本物理引擎可以用来产生声音,有无限的可能性。杠杆可以:
等等。
你能让模型的声音变得多么“正常”和“音乐化”?目前模型的规则并不是基于音阶或音调的;通过更仔细地选择音调,你也许可以制作出更少奇怪、更像人类创作的音乐。你也可以尝试通过将声音与规律的节拍相协调,产生更规律的节奏。
另一方面,你也可以采取相反的方法,看看你能让声音变得多么狂野、不同和不寻常。制作一些你以前从未听过的东西!