- A follows a straight line and B follows A at a right angle
- C1 to C4 start off at a square and follow each other to give a spiralling motion
- If you have a dot with an autonomous movement, the speed may influence the resulting curve for a following dot.
- The speed at which dots follow each other is proportional to their distance. This makes the differential equations that are being solved linear. A variation would be to make the speed constant and have only the direction depend on the vector between the two dots.
- There is no error checking (fast results, remember?).
# movedots.tcl --
# Define moving dots that can trace each other
#
package require Tk
# dot --
# Define a dot (give it a name)
# Arguments:
# name Name of the dot (new command)
# x X-coordinate at start
# y Y-coordinate at start
# colour Colour of the line to draw
# Result:
# None
# Side effect:
# Command "name" will be created
#
proc dot {name x y colour} {
variable all_dots
variable dot_prop
lappend all_dots $name
set dot_prop($name,x) $x
set dot_prop($name,y) $y
set dot_prop($name,colour) $colour
interp alias {} $name {} DotImpl $name
}
# DotImpl --
# Handle the commands for a dot (motion etc.)
# Arguments:
# name Name of the dot
# subcomm Subcommand
# args Any arguments
# Result:
# None
# Side effect:
# Whatever the subcommand means
#
proc DotImpl {name subcomm args} {
variable all_dots
variable dot_prop
switch -- $subcomm {
"moves" { set dot_prop($name,movex) [lindex $args 0]
set dot_prop($name,movey) [lindex $args 1]
set dot_prop($name,move) "move"
}
"follows" { set dot_prop($name,follows) [lindex $args 0]
set dot_prop($name,move) "follows"
set dot_prop($name,angle) 0.0
if { [llength $args] == 3 } {
set dot_prop($name,angle) [expr {[lindex $args 2]/180.0*3.1415926}]
}
}
"draw" { DotDraw $name }
"update" { set dot_prop($name,x) $dot_prop($name,xn)
set dot_prop($name,y) $dot_prop($name,yn)
}
default { # Ingnore }
}
}
# DotDraw --
# Draw the (new) position of the dot
# Arguments:
# name Name of the dot (new command)
# Result:
# None
# Side effect:
# Line segment drawn, position updated
#
proc DotDraw {name} {
variable all_dots
variable dot_prop
variable t
variable dt
if { $dot_prop($name,move) == "move" } {
set x [expr $dot_prop($name,movex)]
set y [expr $dot_prop($name,movey)]
} else {
set target $dot_prop($name,follows)
set angle $dot_prop($name,angle)
set x $dot_prop($name,x)
set y $dot_prop($name,y) ;# Updates should be delayed!
set tx $dot_prop($target,x)
set ty $dot_prop($target,y)
set vx [expr {$tx-$x}]
set vy [expr {$ty-$y}]
set dx [expr {$dt*(cos($angle)*$vx-sin($angle)*$vy)}]
set dy [expr {$dt*(sin($angle)*$vx+cos($angle)*$vy)}]
set x [expr {$x+$dx}]
set y [expr {$y+$dy}]
}
# Updates should be delayed!!
.c create line $dot_prop($name,x) $dot_prop($name,y) $x $y -fill $dot_prop($name,colour)
set dot_prop($name,xn) $x
set dot_prop($name,yn) $y
}
# main --
# Main code:
# - Create the canvas
# - Define some dots
# - Draw the tracks they produce
#
canvas .c -background white -width 500 -height 500
pack .c -fill both
set t 0
set dt 0.02
set nosteps 1000
#dot A 450.0 250.0 blue
#dot B 470.0 250.0 green
#A moves {250.0+200.0*cos($t)} {250.0+200.0*sin($t)}
dot A 0.0 200.0 blue
dot B 0.0 230.0 green
A moves {30*$t} 200.0
B follows A -angle -90
dot C1 400.0 0.0 blue
dot C2 400.0 400.0 green
dot C3 0.0 400.0 red
dot C4 0.0 0.0 magenta
C1 follows C2 -angle -10
C2 follows C3 -angle -10
C3 follows C4 -angle -10
C4 follows C1 -angle -10
for { set i 0 } { $i < $nosteps } { incr i } {
foreach dot $all_dots {
$dot draw
}
foreach dot $all_dots {
$dot update
}
set t [expr {$t+$dt}]
}Theo Verelst Well well, contractive difference equations, it would be good to take the accompanying differential equations, which for as it seems here limited order linear problems (oops, maybe I didn't see right, is the distance linear?) would seems solvable. Maybe even automatically. I remember a big book with diff. eq. that definitely contained images of this kind.

