## PhysicsPlayground

FF - 2008-01-17 - I'm just playing with speed and acceleration.... I also added a collision check at bounds. I wanted to add multiple objects and collision check between every object, but I figured it would have been a pain...

In the beginning I was working with vectors in polar coordinates, but I figured that also was a pain, so I switched to rect coords, but here and there there in the code could be some wastes of polar stuff :-)

``` set PI [expr atan(1)*4]
set x 50.0 ; set y 50.0
set vec_x   0.0 ; set vec_y   0.0
set timediv 50.0
array set input {
joy_sz 64
target null
dragging 0
dx 0.0
dy 0.0
}
set cnv [canvas .c -width 640 -height 400 -background white]
set joy [canvas .j -width \$::input(joy_sz) -height \$::input(joy_sz) -background gray]
grid \$cnv -column 0 -row 0 -columnspan 2 -sticky news
grid columnconfigure . 0 -weight 10
grid rowconfigure . 0 -weight 10
grid [label .l1 -textvar ::lab1] -column 0 -row 1
grid [checkbutton .cb1 -text Spring -variable ::spring] -column 0 -row 2
grid [checkbutton .cb2 -text Control_accel -variable ::mode] -column 0 -row 3
grid \$joy -column 1 -row 1 -rowspan 3 -sticky news

proc init_vect {cnv {bdot 1}} {
if \$bdot {
\$cnv create rectangle 0 0 10 10 -tags {dot} -fill blue
} else {
\$cnv create line [expr \$::input(joy_sz)*0.5] 0 [expr \$::input(joy_sz)*0.5] \$::input(joy_sz)
\$cnv create line 0 [expr \$::input(joy_sz)*0.5] \$::input(joy_sz) [expr \$::input(joy_sz)*0.5]
}
\$cnv create line 0 0 10 10 -tags {vector vector_line} -fill red
\$cnv create polygon 0 0 10 10 20 20 -tags {vector vector_arrow} -fill red
}

proc rec2pol {dx dy} {
if {\$dx == 0} {set angle [expr \$::PI*((\$dy>0)?0.5:1.5)]} \
{set angle [expr fmod(\$::PI*((\$dx>=0)?2:3)+atan(+1.0*\$dy/\$dx), \$::PI*2)]}
set length [expr sqrt(pow(\$dx,2)+pow(\$dy,2))]
return [list \$angle \$length]
}

proc upd_vect_pol {cnv x y lx ly} {
\$cnv coords dot [expr \$x-5] [expr \$y-5] [expr \$x+5] [expr \$y+5]
set ex [expr \$x+\$lx] ; set ey [expr \$y+\$ly]
\$cnv coords vector_line \$x \$y \$ex \$ey
set angle [lindex [rec2pol \$lx \$ly] 0]
set Al [expr fmod(\$::PI*1.25+\$angle, \$::PI*2)]
set Ar [expr fmod(\$::PI*2.75+\$angle, \$::PI*2)]
if {\$lx != 0 || \$ly != 0} {
\$cnv coords vector_arrow \
[expr \$ex+cos(\$Al)*6] [expr \$ey+sin(\$Al)*6] \
\$ex \$ey [expr \$ex+cos(\$Ar)*6] [expr \$ey+sin(\$Ar)*6]
} else {
\$cnv coords vector_arrow \
[expr \$x-3] \$y \$x [expr \$y-3] [expr \$x+3] \$y \$x [expr \$y+3]
}
}

proc upd {__cnv st {ex_ 0} {ey_ 0}} {
if {\$st == 0 && \$::input(dragging)} {
set ::input(dx) [expr \$ex_-\$::input(joy_sz)*0.5]
set ::input(dy) [expr \$ey_-\$::input(joy_sz)*0.5]
upd_vect_pol \$::joy [expr \$::input(joy_sz)*0.5] [expr \$::input(joy_sz)*0.5] \$::input(dx) \$::input(dy)
upd_vect_pol \$::cnv \$::x \$::y \$::vec_x \$::vec_y
} elseif {\$st > 0} {
set ::input(dragging) 1
} elseif {\$st < 0} {
set ::input(dragging) 0
if \$::spring {
set ::input(dx) 0 ; set ::input(dy) 0 ; upd_vect_pol \$::joy [expr \$::input(joy_sz)*0.5] [expr \$::input(joy_sz)*0.5] \$::input(dx) \$::input(dy)
}
}
}

proc go {cnv} {
set amt 0.1
# handle speed vector / acceleration
if {\$::mode == 0} {
set ::vec_x \$::input(dx)
set ::vec_y \$::input(dy)
} elseif {\$::mode == 1} {
set ::vec_x [expr \$::vec_x+\$::input(dx)*\$amt]
set ::vec_y [expr \$::vec_y+\$::input(dy)*\$amt]
}
set ::x [expr \$::x+\$::vec_x*\$amt]
set ::y [expr \$::y+\$::vec_y*\$amt]
# handle collisions
set cnvw [expr ([winfo width \$cnv]-[winfo reqwidth \$cnv]+[\$cnv cget -width])]
set cnvh [expr ([winfo height \$cnv]-[winfo reqheight \$cnv]+[\$cnv cget -height])]
if {\$::x < 0} {
set ::x [expr 0-\$::x]
set ::vec_x [expr 0-\$::vec_x]
} elseif {\$::x > \$cnvw} {
set ::x [expr \$cnvw*2-\$::x]
set ::vec_x [expr 0-\$::vec_x]
}
if {\$::y < 0} {
set ::y [expr 0-\$::y]
set ::vec_y [expr 0-\$::vec_y]
} elseif {\$::y > \$cnvh} {
set ::y [expr \$cnvh*2-\$::y]
set ::vec_y [expr 0-\$::vec_y]
}
set ::lab1 "D(joy)=(\${::input(dx)},\${::input(dy)}) Vec=(\${::vec_x},\${::vec_y}) w=\$cnvw h=\$cnvh"
upd_vect_pol \$cnv \$::x \$::y \$::vec_x \$::vec_y
after [expr int(1000/\$::timediv)] [list go \$cnv]
}

init_vect \$cnv
init_vect \$joy 0
upd \$joy 1; upd \$joy 0 [expr \$::input(joy_sz)*0.5] [expr \$::input(joy_sz)*0.5]; upd \$joy -1

bind \$cnv <ButtonPress-1> {set ::x %x ; set ::y %y}

bind \$joy <ButtonPress-1> {upd %W 1}
bind \$joy <ButtonRelease-1> {upd %W -1}
bind \$joy <ButtonPress-3> {upd %W 1; upd %W 0 %x %y; upd %W -1}
bind \$joy <Motion> {upd %W 0 %x %y}

go \$cnv```