REVO2700Follow the bouncing ballXfunction perpDist tP,tLine put item 1 of tLine into x2 put item 2 of tLine into y2 put item 3 of tLine into x3 put item 4 of tLine into y3 put item 1 of tP into x1 put item 2 of tP into y1 if x3-x2 is 0 then return abs(x1-x2) else put (y3-y2)/(x3-x2) into m -- The slope return abs(m*(x1-x2)-(y1-Y2))/sqrt(1+m*m) end if end perpDist on openstack choose the browse tool end openstack on preOpenStack choose the browse tool end preOpenStack + ULucida Grande U W U9 UTimes New Roman WTimes New Roman$WTimes New Roman W9W9U9W9 WLucida GrandecREVGeometryCachestackID6556 cREVGeneralscriptChecksum9kmP8 bookmarks debugObjects?button id 1005 of card id 1002 of stack "Rubber Ball" graphic id 1003 of card id 1002 of stack "Elastic ball" graphic id 5743 of card id 5738 of stack "Rubber ball" graphic id 1003 of card id 1002 of stack "Rubber ball" button id 5748 of card id 5738 of stack "Rubber ball" graphic id 5732 of card id 5738 of stack "Rubber ball" graphic id 5732 of card id 5738 of stack "myLine" graphic id 5815 of card id 5827 of stack "Rubber ball" graphic id 5815 of card id 5827 of stack "Graphic 1" graphic id 5815 of card id 5827 of stack "Bouncing ball" graphic id 5850 of card id 5863 of stack "Bouncing ball" graphic id 5815 of card id 5827 of stack "Graphic tools" graphic id 5884 of card id 5897 of stack "Graphic tools" graphic id 5917 of card id 5929 of stack "Graphic tools" graphic id 5917 of card id 5929 of stack "card id 5929" graphic id 5732 of card id 5738 of stack "card id 5929" graphic id 6045 of card id 6047 of stack "Follow the bouncing ball" graphic id 5884 of card id 5897 of stack "Follow the bouncing ball" graphic id 6200 of card id 6202 of stack "Follow the bouncing ball" handlerListperpDist openstack preOpenStackscriptSelectionchar 477 to 476 prevHandlerperpDist tempScriptscript)

function perpDist tP,tLine

put item 1 of tLine into x2

put item 2 of tLine into y2

put item 3 of tLine into x3

put item 4 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return abs(x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return abs(m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)

end if

end perpDist

on openstack

choose the browse tool

end openstack

on preOpenStack

choose the browse tool

end preOpenStack

 P cREVGeometryCacheIDs 110834370561957301108342523075572811084241659445747110842415071157461109349981985617711083426332215729110834086646757271108343966445573111078703210971003cREVGeometrycacheordertotal9 cREVGeneralscriptChecksumh)ژ@ح\@ bookmarks handlerList breakPoints tempScript prevHandlerperpDistscriptSelection char 1 to 0script

_`abcrs!j Pmfunction thePolyLines tPolyPoints repeat with i = 1 to the number of lines in tPolyPoints put line i of tPolyPoints & comma & line i+1 of tPolyPoints & return after results end repeat delete last line of results return results end thePolyLines function perpDist tP,tLine put item 1 of tLine into x2 put item 2 of tLine into y2 put item 3 of tLine into x3 put item 4 of tLine into y3 put item 1 of tP into x1 put item 2 of tP into y1 if x3-x2 is 0 then return (x1-x2) else put (y3-y2)/(x3-x2) into m -- The slope return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m) end if end perpDist cREVGeometryCacheIDs1108343705619573611083950067105744110851149227258031109350108503617811083426332215735110850687477057681108343966445573711084985361555755110834252307557341108498536156575611084983073865754110843005869657481107870321097573211083408664675733cREVGeometryCacheordertotal14 cREVGeneralscriptChecksum*ˎ$)R饍 bookmarks breakPoints handlerListthePolyLines perpDistscriptSelection char 1 to 256 prevHandler thePolyLines tempScriptscript

function thePolyLines tPolyPoints

repeat with i = 1 to the number of lines in tPolyPoints

put line i of tPolyPoints & comma & line i+1 of tPolyPoints & return after results

end repeat

delete last line of results

return results

end thePolyLines

function perpDist tP,tLine

put item 1 of tLine into x2

put item 2 of tLine into y2

put item 3 of tLine into x3

put item 4 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return (x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)

end if

end perpDist

efghipt{|dz" Pmfunction thePolyLines tPolyPoints repeat with i = 1 to the number of lines in tPolyPoints put line i of tPolyPoints & comma & line i+1 of tPolyPoints & return after results end repeat delete last line of results return results end thePolyLines function perpDist tP,tLine put item 1 of tLine into x2 put item 2 of tLine into y2 put item 3 of tLine into x3 put item 4 of tLine into y3 put item 1 of tP into x1 put item 2 of tP into y1 if x3-x2 is 0 then return (x1-x2) else put (y3-y2)/(x3-x2) into m -- The slope return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m) end if end perpDist cREVGeometryCacheIDs110834370561960361108395006710603811085114922726043110834396644560371108506874770604211084985361556040110935011524161791108498536156604111088990148816044110849830738660461108942517596609711084300586966039110787032109760451108942420955609511083426332216035110834252307560341108942503466609611083408664676033cREVGeometryCachetotal18order cREVGeneralscriptChecksum*ˎ$)R饍 bookmarks handlerListthePolyLines perpDist breakPoints tempScript prevHandler thePolyLinesscriptSelection char 1 to 256script

function thePolyLines tPolyPoints

repeat with i = 1 to the number of lines in tPolyPoints

put line i of tPolyPoints & comma & line i+1 of tPolyPoints & return after results

end repeat

delete last line of results

return results

end thePolyLines

function perpDist tP,tLine

put item 1 of tLine into x2

put item 2 of tLine into y2

put item 3 of tLine into x3

put item 4 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return (x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)

end if

end perpDist

# P Ffunction ProjPointLiesWithinEndPts tProjPt,tLine put item 1 to 2 of tLine into tLinePt1 put item 3 to 4 of tLine into tLinePt2 put theTwoPtDist(tLinePt1,tLinePt2) into L put theTwoPtDist(tProjPt,tLinePt1) into s1 put theTwoPtDist(tProjPt,tLinePt2) into s2 if s1 < L and s2 < L then return true else return false end ProjPointLiesWithinEndPts end tDistProjPtFromEitherEnd function theDistPtAndEndPoints p1,tLine put item 1 to 2 of tLine into p2 put item 3 to 4 of tLine into p3 put theTwoPtDist(p1,p2) into s1 put theTwoPtDist(p1,p3) into s2 return s1+s2 end theDistPtAndEndPoints function theTwoPtDist p1,p2 put item 1 of p1 into x1 put item 2 of p1 into y1 put item 1 of p2 into x2 put item 2 of p2 into y2 return sqrt((x2-x1)^2 + (y2-y1)^2) end theTwoPtDist on changeToReflectedVel tLine put item 1 to 2 of tLine into p1 put item 3 to 4 of tLine into p2 put the loc of me into tLoc put theTwoPtDist(tLoc,p1) into d1 put theTwoPtDist(tLoc,p2) into d2 if d1 function ProjPointLiesWithinEndPts tProjPt,tLine

put item 1 to 2 of tLine into tLinePt1

put item 3 to 4 of tLine into tLinePt2

put theTwoPtDist(tLinePt1,tLinePt2) into L

put theTwoPtDist(tProjPt,tLinePt1) into s1

put theTwoPtDist(tProjPt,tLinePt2) into s2

if s1 < L and s2 < L then

return true

else return false

end ProjPointLiesWithinEndPts

end tDistProjPtFromEitherEnd

function theDistPtAndEndPoints p1,tLine

put item 1 to 2 of tLine into p2

put item 3 to 4 of tLine into p3

put theTwoPtDist(p1,p2) into s1

put theTwoPtDist(p1,p3) into s2

return s1+s2

end theDistPtAndEndPoints

function theTwoPtDist p1,p2

put item 1 of p1 into x1

put item 2 of p1 into y1

put item 1 of p2 into x2

put item 2 of p2 into y2

return sqrt((x2-x1)^2 + (y2-y1)^2)

end theTwoPtDist

on changeToReflectedVel tLine

put item 1 to 2 of tLine into p1

put item 3 to 4 of tLine into p2

put the loc of me into tLoc

put theTwoPtDist(tLoc,p1) into d1

put theTwoPtDist(tLoc,p2) into d2

if d1 <rMax or d2 < rMax then

multiply vx by -1

multiply vy by -1

exit changeToReflectedVel

end if

put item 2 of p2 - item 2 of p1 into dy

put item 1 of p2 - item 1 of p1 into dx

put aTan2(dy,dx) into angleL

put aTan2(vy,vx) into angleV

put sqrt(vx*vx+vy*vy) into v

put v * cos(2*angleL-angleV) into vx--A lettle geometry here.

put v * sin (2*angleL - angleV) into vy

end changeToReflectedVel

function thePolyLines tPolyPoints

repeat with i = 1 to the number of lines in tPolyPoints

put line i of tPolyPoints & comma & line i+1 of tPolyPoints & return after results

end repeat

delete last line of results

return results

end thePolyLines

function perpDist tP,tLine

put item 1 of tLine into x2

put item 2 of tLine into y2

put item 3 of tLine into x3

put item 4 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return (x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)

end if

end perpDist

function perpProjPt p0, tLine

put item 1 to 2 of tLine into p1

put item 3 to 4 of tLine into p2

put item 1 of p1 into x1

put item 2 of p1 into y1

put item 1 of p2 into x2

put item 2 of p2 into y2

put item 1 of p0 into x0

put item 2 of p0 into y0

if x2 = x1 then

put 1 into s

put 0 into c

else

put (y2-y1)/(x2-x1) into m

put m/sqrt(1+m*m) into s --sine

put 1/sqrt(1+m*m) into c -- cosine

end if

put x1+(y0-y1)*s*c+(x0-x1)*c*c into x

put y1 + (y0-y1)*s*s + (x0-x1) * s * c into y

return round(x),round(y)

end perpProjPt

$ Pfunction perpDist tP,tLine put item 1 of line 1 of tLine into x2 put item 2 of line 1 of tLine into y2 put item 1 of line 2 of tLine into x3 put item 2 of line 2 of tLine into y3 put item 1 of tP into x1 put item 2 of tP into y1 if x3-x2 is 0 then return (x1-x2) else put (y3-y2)/(x3-x2) into m -- The slope return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m) end if end perpDist --function ProjPointLiesWithinEndPts tProjPt,tLine -- put line 1 of tLine into p1 -- put line 2 of tLine into p2 -- put theDistBEtweenPoints(p1,p2) into L -- -- put theDistBetweenPoints(tProjPt,p1) into s1 -- put theDistBetweenPoints(tProjPt,p2) into s2 -- -- if s1 < L and s2 < L then -- return "between" -- else return "not"& cr& "between" --end ProjPointLiesWithinEndPts function perpProjPt p0, tLine put line 1 of tLine into p1 put line 2 of tLine into p2 put item 1 of p1 into x1 put item 2 of p1 into y1 put item 1 of p2 into x2 put item 2 of p2 into y2 put item 1 of p0 into x0 put item 2 of p0 into y0 if x2 = x1 then put 1 into s put 0 into c else put (y2-y1)/(x2-x1) into m put m/sqrt(1+m*m) into s --sine put 1/sqrt(1+m*m) into c -- cosine end if put x1+(y0-y1)*s*c+(x0-x1)*c*c into x put y1 + (y0-y1)*s*s + (x0-x1) * s * c into y return round(x),round(y) end perpProjPt function ProjPointLiesWithinEndPts tProjPt,tLine put line 1 of tLine into p1 put line 2 of tLine into p2 put theDistBEtweenPoints(p1,p2) into L put theDistBetweenPoints(tProjPt,p1) into s1 put theDistBetweenPoints(tProjPt,p2) into s2 if s1 < L and s2 < L then return "Between end points" else return "Not between end points" end ProjPointLiesWithinEndPts function theDistBetweenPoints a,b put item 1 of a into x1 put item 2 of a into y1 put item 1 of b into x2 put item 2 of b into y2 return sqrt((x2-x1)^2 + (y2-y1)^2) end theDistBetweenPoints cREVGeometryCacheIDs 110867926750658681108511492272585711087035660605873110843005869658541109350126647618111086765534345865110859777103458581107870321097585011086775044295866cREVGeometryCacheordertotal9 cREVGeneralscriptChecksuml?c%Efunction perpDist tP,tLine

put item 1 of line 1 of tLine into x2

put item 2 of line 1 of tLine into y2

put item 1 of line 2 of tLine into x3

put item 2 of line 2 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return (x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)

end if

end perpDist

--function ProjPointLiesWithinEndPts tProjPt,tLine

-- put line 1 of tLine into p1

-- put line 2 of tLine into p2

-- put theDistBEtweenPoints(p1,p2) into L

--

-- put theDistBetweenPoints(tProjPt,p1) into s1

-- put theDistBetweenPoints(tProjPt,p2) into s2

--

-- if s1 < L and s2 < L then

-- return "between"

-- else return "not"& cr& "between"

--end ProjPointLiesWithinEndPts

function perpProjPt p0, tLine

put line 1 of tLine into p1

put line 2 of tLine into p2

put item 1 of p1 into x1

put item 2 of p1 into y1

put item 1 of p2 into x2

put item 2 of p2 into y2

put item 1 of p0 into x0

put item 2 of p0 into y0

if x2 = x1 then

put 1 into s

put 0 into c

else

put (y2-y1)/(x2-x1) into m

put m/sqrt(1+m*m) into s --sine

put 1/sqrt(1+m*m) into c -- cosine

end if

put x1+(y0-y1)*s*c+(x0-x1)*c*c into x

put y1 + (y0-y1)*s*s + (x0-x1) * s * c into y

return round(x),round(y)

end perpProjPt

function ProjPointLiesWithinEndPts tProjPt,tLine

put line 1 of tLine into p1

put line 2 of tLine into p2

put theDistBEtweenPoints(p1,p2) into L

put theDistBetweenPoints(tProjPt,p1) into s1

put theDistBetweenPoints(tProjPt,p2) into s2

if s1 < L and s2 < L then

return "Between end points"

else return "Not between end points"

end ProjPointLiesWithinEndPts

function theDistBetweenPoints a,b

put item 1 of a into x1

put item 2 of a into y1

put item 1 of b into x2

put item 2 of b into y2

return sqrt((x2-x1)^2 + (y2-y1)^2)

end theDistBetweenPoints

% P f function theDistPtAndEndPoints p1,tLine put item 1 to 2 of tLine into p2 put item 3 to 4 of tLine into p3 put theTwoPtDist(p1,p2) into s1 put theTwoPtDist(p1,p3) into s2 return s1+s2 end theDistPtAndEndPoints function ProjPointLiesWithinEndPts tProjPt,tLine put item 1 to 2 of tLine into tLinePt1 put item 3 to 4 of tLine into tLinePt2 put theTwoPtDist(tLinePt1,tLinePt2) into L put theTwoPtDist(tProjPt,tLinePt1) into s1 put theTwoPtDist(tProjPt,tLinePt2) into s2 if s1 <= L and s2 <= L then return true else return false end ProjPointLiesWithinEndPts function dist p1,p2 return theTwoPtDist(p1,p2) end dist function theTwoPtDist p1,p2 put item 1 of p1 into x1 put item 2 of p1 into y1 put item 1 of p2 into x2 put item 2 of p2 into y2 return sqrt((x2-x1)^2 + (y2-y1)^2) end theTwoPtDist on changeToReflectedVel tLine put item 1 to 2 of tLine into p1 put item 3 to 4 of tLine into p2 put the loc of me into tLoc put theTwoPtDist(tLoc,p1) into d1 put theTwoPtDist(tLoc,p2) into d2 if d1

function theDistPtAndEndPoints p1,tLine

put item 1 to 2 of tLine into p2

put item 3 to 4 of tLine into p3

put theTwoPtDist(p1,p2) into s1

put theTwoPtDist(p1,p3) into s2

return s1+s2

end theDistPtAndEndPoints

function ProjPointLiesWithinEndPts tProjPt,tLine

put item 1 to 2 of tLine into tLinePt1

put item 3 to 4 of tLine into tLinePt2

put theTwoPtDist(tLinePt1,tLinePt2) into L

put theTwoPtDist(tProjPt,tLinePt1) into s1

put theTwoPtDist(tProjPt,tLinePt2) into s2

if s1 <= L and s2 <= L then

return true

else return false

end ProjPointLiesWithinEndPts

function dist p1,p2

return theTwoPtDist(p1,p2)

end dist

function theTwoPtDist p1,p2

put item 1 of p1 into x1

put item 2 of p1 into y1

put item 1 of p2 into x2

put item 2 of p2 into y2

return sqrt((x2-x1)^2 + (y2-y1)^2)

end theTwoPtDist

on changeToReflectedVel tLine

put item 1 to 2 of tLine into p1

put item 3 to 4 of tLine into p2

put the loc of me into tLoc

put theTwoPtDist(tLoc,p1) into d1

put theTwoPtDist(tLoc,p2) into d2

if d1 <rMax or d2 < rMax then

multiply vx by -1

multiply vy by -1

exit changeToReflectedVel

end if

put item 2 of p2 - item 2 of p1 into dy

put item 1 of p2 - item 1 of p1 into dx

put aTan2(dy,dx) into angleL

put aTan2(vy,vx) into angleV

put sqrt(vx*vx+vy*vy) into v

put v * cos(2*angleL-angleV) into vx--A lettle geometry here.

put v * sin (2*angleL - angleV) into vy

end changeToReflectedVel

function thePolyLines tPolyPoints

repeat with i = 1 to the number of lines in tPolyPoints

put line i of tPolyPoints & comma & line i+1 of tPolyPoints & return after results

end repeat

delete last line of results

return results

end thePolyLines

function perpDist tP,tLine

put item 1 of tLine into x2

put item 2 of tLine into y2

put item 3 of tLine into x3

put item 4 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return (x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)

end if

end perpDist

function perpProjPt p0, tLine

put item 1 to 2 of tLine into p1

put item 3 to 4 of tLine into p2

put item 1 of p1 into x1

put item 2 of p1 into y1

put item 1 of p2 into x2

put item 2 of p2 into y2

put item 1 of p0 into x0

put item 2 of p0 into y0

if x2 = x1 then

put 1 into s

put 0 into c

else

put (y2-y1)/(x2-x1) into m

put m/sqrt(1+m*m) into s --sine

put 1/sqrt(1+m*m) into c -- cosine

end if

put x1+(y0-y1)*s*c+(x0-x1)*c*c into x

put y1 + (y0-y1)*s*s + (x0-x1) * s * c into y

return round(x),round(y)

end perpProjPt

&e: Pon clean repeat until the number of images is 0 delete image 1 end repeat end clean function perpDist tP,tLine put item 1 of tLine into x2 put item 2 of tLine into y2 put item 3 of tLine into x3 put item 4 of tLine into y3 put item 1 of tP into x1 put item 2 of tP into y1 if x3-x2 is 0 then return abs(x1-x2) else put (y3-y2)/(x3-x2) into m -- The slope return abs((m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)) end if end perpDist function intersection line1,line2 put item 1 to 2 of line1 into p1 put item 3 to 4 of line1 into p2 put item 1 to 2 of line2 into pp1 put item 3 to 4 of line2 into pp2 put item 1 of p1 into x1 put item 2 of p1 into y1 put item 1 of p2 into x2 put item 2 of p2 into y2 put item 1 of pp1 into xp1 put item 2 of pp1 into yp1 put item 1 of pp2 into xp2 put item 2 of pp2 into yp2 if x1 = x2 and xp1= xp2 then add .001 to xp2 if x1 = x2 or xp1 = xp2 then if x1 = x2 then return x1&comma&yp2 + (x1-xp2)*(yp2-yp1)/(xp2-xp1) else return xp2&comma& y2 + (xp1-x2)*(y2-y1)/(x2-x1) end if end if if (y2-y1)/(x2-x1) = (yp2-yp1)/(xp2-xp1) then add .0001 to y2--if lines are parallel put yp2 - y2 + x2*(y2-y1)/(x2 - x1) - xp2*(yp2 - yp1)/(xp2 - xp1) into numerator put ((y2 - y1)/(x2 - x1) -( yp2 - yp1)/(xp2-xp1)) into denom put numerator / denom into x put y2 + (x-x2) *(y2-y1)/(x2-x1) into y return x & comma & y end intersection InnerBoundary720,20,513,20 513,20,513,513 20,20,20,513 20,513,513,513BoundaryLines/0,0,533,0 533,0,533,533 0,0,0,533 0,533,533,533cREVGeometryCacheIDs1109350482393622711093504823946228110935048239562291109350482396623011093504823976231110935043756962241109033759789618511092843133416195110928461576161981109284671922619911090337708056200110928440462561971109284290642619411093432155956201110928432580861961109350795813624211093515973896249110911286360061871109109886658618611093507971576243110911516160361891109350793365624111095301556736455110935048239162251109282519719619011093504823926226cREVGeometrycacheordertotal26 cREVGeneralscriptChecksumm:*z bookmarks handlerListclean perpDist intersection breakPointsscriptSelectionchar 463 to 462 prevHandler theNewVel tempScriptscriptj

on clean

repeat until the number of images is 0

delete image 1

end repeat

end clean

function perpDist tP,tLine

put item 1 of tLine into x2

put item 2 of tLine into y2

put item 3 of tLine into x3

put item 4 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return abs(x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return abs((m*(x1-x2)-(y1-Y2))/sqrt(1+m*m))

end if

end perpDist

function intersection line1,line2

put item 1 to 2 of line1 into p1

put item 3 to 4 of line1 into p2

put item 1 to 2 of line2 into pp1

put item 3 to 4 of line2 into pp2

put item 1 of p1 into x1

put item 2 of p1 into y1

put item 1 of p2 into x2

put item 2 of p2 into y2

put item 1 of pp1 into xp1

put item 2 of pp1 into yp1

put item 1 of pp2 into xp2

put item 2 of pp2 into yp2

if x1 = x2 and xp1= xp2 then add .001 to xp2

if x1 = x2 or xp1 = xp2 then

if x1 = x2 then

return x1&comma&yp2 + (x1-xp2)*(yp2-yp1)/(xp2-xp1)

else

return xp2&comma& y2 + (xp1-x2)*(y2-y1)/(x2-x1)

end if

end if

if (y2-y1)/(x2-x1) = (yp2-yp1)/(xp2-xp1) then add .0001 to y2--if lines are parallel

put yp2 - y2 + x2*(y2-y1)/(x2 - x1) - xp2*(yp2 - yp1)/(xp2 - xp1) into numerator

put ((y2 - y1)/(x2 - x1) -( yp2 - yp1)/(xp2-xp1)) into denom

put numerator / denom into x

put y2 + (x-x2) *(y2-y1)/(x2-x1) into y

return x & comma & y

end intersection

)*+-.2345689PQRSTUVWabci77N P on clean repeat until the number of images is 0 delete image 1 end repeat end clean function perpDist tP,tLine put item 1 of tLine into x2 put item 2 of tLine into y2 put item 3 of tLine into x3 put item 4 of tLine into y3 put item 1 of tP into x1 put item 2 of tP into y1 if x3-x2 is 0 then return abs(x1-x2) else put (y3-y2)/(x3-x2) into m -- The slope return abs((m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)) end if end perpDist function intersection line1,line2 put item 1 to 2 of line1 into p1 put item 3 to 4 of line1 into p2 put item 1 to 2 of line2 into pp1 put item 3 to 4 of line2 into pp2 put item 1 of p1 into x1 put item 2 of p1 into y1 put item 1 of p2 into x2 put item 2 of p2 into y2 put item 1 of pp1 into xp1 put item 2 of pp1 into yp1 put item 1 of pp2 into xp2 put item 2 of pp2 into yp2 if x1 = x2 and xp1= xp2 then add .001 to xp2 if x1 = x2 or xp1 = xp2 then if x1 = x2 then return x1&comma&yp2 + (x1-xp2)*(yp2-yp1)/(xp2-xp1) else return xp2&comma& y2 + (xp1-x2)*(y2-y1)/(x2-x1) end if end if if (y2-y1)/(x2-x1) = (yp2-yp1)/(xp2-xp1) then add .0001 to y2--if lines are parallel put yp2 - y2 + x2*(y2-y1)/(x2 - x1) - xp2*(yp2 - yp1)/(xp2 - xp1) into numerator put ((y2 - y1)/(x2 - x1) -( yp2 - yp1)/(xp2-xp1)) into denom put numerator / denom into x put y2 + (x-x2) *(y2-y1)/(x2-x1) into y return x & comma & y end intersection InnerBoundary720,20,513,20 513,20,513,513 20,20,20,513 20,513,513,513stopMefalseBoundaryLines/0,0,533,0 533,0,533,533 0,0,0,533 0,533,533,533cREVGeometryCacheIDs110955488096064941109350779779624011094378995996295110928952623562041109033759789620511092843133416211110928461576162141109343305467622011092883732566218110928429064262101109351706087625111092843258086212110935077977162321109350779772623311093507797736234110935170340162501109350779774623511093507797756236110935077977662371109350779777623811092825197196209cREVGeometrycacheordertotal21 cREVGeneralscriptChecksumDpcuݹ bookmarks handlerListclean perpDist intersection tempScript prevHandler theNewVelscriptSelection char 1 to 0script*

on clean

repeat until the number of images is 0

delete image 1

end repeat

end clean

function perpDist tP,tLine

put item 1 of tLine into x2

put item 2 of tLine into y2

put item 3 of tLine into x3

put item 4 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return abs(x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return abs((m*(x1-x2)-(y1-Y2))/sqrt(1+m*m))

end if

end perpDist

function intersection line1,line2

put item 1 to 2 of line1 into p1

put item 3 to 4 of line1 into p2

put item 1 to 2 of line2 into pp1

put item 3 to 4 of line2 into pp2

put item 1 of p1 into x1

put item 2 of p1 into y1

put item 1 of p2 into x2

put item 2 of p2 into y2

put item 1 of pp1 into xp1

put item 2 of pp1 into yp1

put item 1 of pp2 into xp2

put item 2 of pp2 into yp2

if x1 = x2 and xp1= xp2 then add .001 to xp2

if x1 = x2 or xp1 = xp2 then

if x1 = x2 then

return x1&comma&yp2 + (x1-xp2)*(yp2-yp1)/(xp2-xp1)

else

return xp2&comma& y2 + (xp1-x2)*(y2-y1)/(x2-x1)

end if

end if

if (y2-y1)/(x2-x1) = (yp2-yp1)/(xp2-xp1) then add .0001 to y2--if lines are parallel

put yp2 - y2 + x2*(y2-y1)/(x2 - x1) - xp2*(yp2 - yp1)/(xp2 - xp1) into numerator

put ((y2 - y1)/(x2 - x1) -( yp2 - yp1)/(xp2-xp1)) into denom

put numerator / denom into x

put y2 + (x-x2) *(y2-y1)/(x2-x1) into y

return x & comma & y

end intersection

<=ABCDFJLXYZ[\]^`jk_speediaF 7040 cREVGeneral revUniqueID 1108340866467 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script `Field 1)}2 cREVGeneral revUniqueID 1108342523075  Speed aField 1+Q cREVGeneral revUniqueID 1108342633221  9Drag the ball to a starting point and release the mouse. Hit the shift key to stop.b Diameteriqon scrollbardrag tValue set the width of grc "ball" to 2*tValue set the height of grc "ball" to 2*tValue end scrollbardrag  550 cREVGeneralscriptChecksumba닋N'OHP bookmarks revUniqueID 1108343705619 handlerList scrollbardragscriptSelectionchar 103 to 102 prevHandler scrollbardrag tempScriptscript?

on scrollbardrag tValue

set the width of grc "ball" to 2*tValue

set the height of grc "ball" to 2*tValue

end scrollbardrag

cField 1)52 cREVGeneral revUniqueID 1108343966445  Flexespeedia  T240 cREVGeneral bookmarks revUniqueID 1108340866467 handlerListscriptSelection char 1 to 0 prevHandler tempScriptscript fField 1)D2 cREVGeneral revUniqueID 1108342523075 j Speed gField 1+  H cREVGeneral revUniqueID 1108342633221 j +Confine a ball within any concave polygon.  *hflexia 0 24.908904 cREVGeneral revUniqueID 1108343705619 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script iField 1)F2 cREVGeneral revUniqueID 1108343966445 j FlexpmyLineKblackpoitns 272.445501,144.300445! cREVGeneral bookmarks revUniqueID 1108395006710 handlerListscriptSelection char 1 to 0 prevHandler tempScriptscriptrflexia 050 cREVGeneral revUniqueID 1108424150711 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script s)J cREVGeneral revUniqueID 1108424165944  DiametertReset the ballEpe on mouseUP set the loc of grc "ball" to 200,100 set the width of grc "ball" to 25 set the height of grc "ball"to 25 repeat until the number of images is 0 delete image 1 end repeat put (the thumbposition of scrollbar "diameter") into rMax set the width of grc "ball" to 2*rMax set the height of grc "ball" to 2*rMax end mouseUP h E cREVGeneral scriptChecksumeF a+]h: breakPoints10 handlerListmouseUPscriptSelectionchar 318 to 317 bookmarks revUniqueID 1108430058696 prevHandler mouseMove tempScriptscript-

on mouseUP

set the loc of grc "ball" to 200,100

set the width of grc "ball" to 25

set the height of grc "ball"to 25

repeat until the number of images is 0

delete image 1

end repeat

put (the thumbposition of scrollbar "diameter") into rMax

set the width of grc "ball" to 2*rMax

set the height of grc "ball" to 2*rMax

end mouseUP

{ Diameteriqon scrollbardrag tValue set the width of grc "ball" to 2*tValue set the height of grc "ball" to 2*tValue end scrollbardrag  ǂS550 cREVGeneralscriptChecksumba닋N'OHP bookmarks revUniqueID 1108498536155 handlerList scrollbardragscriptSelectionchar 103 to 102 prevHandler scrollbardrag tempScriptscript?

on scrollbardrag tValue

set the width of grc "ball" to 2*tValue

set the height of grc "ball" to 2*tValue

end scrollbardrag

|)J cREVGeneral revUniqueID 1108498536156 j DiameterPen UpEpon mouseUP if the penState of grc "ball" is true then set the penState of grc "ball" to false set the name of me to "Pen Up" else set the penState of grc "ball" to true set the name of me to "Pen Down" end if end mouseUP %F! cREVGeneralscriptChecksumմ߽P7S bookmarks revUniqueID 1108506874770 handlerListmouseUPscriptSelectionchar 231 to 230 prevHandler tempScriptscriptc

on mouseUP

if the penState of grc "ball" is true then

set the penState of grc "ball" to false

set the name of me to "Pen Up"

else

set the penState of grc "ball" to true

set the name of me to "Pen Down"

end if

end mouseUP

 Instructions)` 2 cREVGeneral revUniqueID 1108511492272 j What it does:  QConstruct a polygon (apex angles < 180 for the time begin) and name it "myPoly". 1Drag the blue ball into the polygon and let go. Hit the shift key to stop the action and use the Reset button to bring the ball back where you can get at it should it be hard to find. The ball makes "elastic collisions" with the walls, that is, the angle of incidence and the incidednt speed are equal to the angle of reflection and reflected speed. MUse the "Pen" button to see a tracing of the path of the CENTER of the ball. 0You can drag the ball to its initial position. How does it work:  The script in the ball uses the perpDist function to find the perpendicular distance between the ball and a line. When this is less than the radius of the ball, a collision has been detected.  MThe only complicated part is determining the angle for specular reflection.  `3ballKT Qlocal vx,vy,rMax,tSpeed,theLines,L,W,H,pendown --da on mouseUp --Erase the trace line. repeat until the number of images is 0 delete image 1 end repeat --Get the radius of the ball. put (the width of me)/2 into rMax put the thumbposition of scrollbar "speed" into tspeed put the endvalue of scrollbar "speed" - tSpeed into tSpeed if tSpeed =0 then put 1 into tSpeed put true into tFlag put ""into theLines repeat with i = 1 to the number of graphics if the style of grc i is "polygon" then put the points of grc i into tPoints --Break the polygon down into its --conponent lines. This is necessary --for the ball to examine its position --relative to the indivdual lines. put thePolyLines(tPoints) after theLines end if end repeat put item 1 of the loc of me into x put item 2 of the loc of me into y put item 1 of field "velocity" into vx put item 2 of field "velocity" into vy if pendown then choose the pencil tool put the penState of grc "ball" into pendown moveBall x,y end mouseUp on moveBall x,y put the loc of me into tOldPt--Used for dragging the pencil set the loc of me to x,y put x,y into tNewPT--Used for dragging the pencil if penDown then drag from tOldPt to tNewPt--Draw a line from the CENTER of the ball. repeat for each line tLine in theLines --Get the distance between the ball and each line --as well as the projection point. put abs(perpDist(the loc of me, tLine)) into tDistToLine put perpProjPt(the loc of me, tLine) into tProjPoint if tDistToLine < rMax and ProjPointLiesWithinEndPts(tProjPoint,tLine) then subtract vx from x subtract vy from y set the loc of me to x,y--backup to keep from getting trapped on the line if char 1 to 2 of the systemversion is 10 then beep changeToReflectedVel tLine--Set the vel components to their reflected values exit repeat end if end repeat if the optionkey is down then wait until the optionkey is up if the ShiftKey is down then choose the browse tool set the cursor to hand exit to top else send "moveBall x+vx,y+vy" to me in tSpeed millisec end moveBall on changeToReflectedVel tLine put item 1 to 2 of tLine into p1 put item 3 to 4 of tLine into p2 put the loc of me into tLoc put theTwoPtDist(tLoc,p1) into d1 put theTwoPtDist(tLoc,p2) into d2 if d1 local vx,vy,rMax,tSpeed,theLines,L,W,H,pendown

--da

on mouseUp

--Erase the trace line.

repeat until the number of images is 0

delete image 1

end repeat

--Get the radius of the ball.

put (the width of me)/2 into rMax

put the thumbposition of scrollbar "speed" into tspeed

put the endvalue of scrollbar "speed" - tSpeed into tSpeed

if tSpeed =0 then put 1 into tSpeed

put true into tFlag

put ""into theLines

repeat with i = 1 to the number of graphics

if the style of grc i is "polygon" then

put the points of grc i into tPoints

--Break the polygon down into its

--conponent lines. This is necessary

--for the ball to examine its position

--relative to the indivdual lines.

put thePolyLines(tPoints) after theLines

end if

end repeat

put item 1 of the loc of me into x

put item 2 of the loc of me into y

put item 1 of field "velocity" into vx

put item 2 of field "velocity" into vy

if pendown then choose the pencil tool

put the penState of grc "ball" into pendown

moveBall x,y

end mouseUp

on moveBall x,y

put the loc of me into tOldPt--Used for dragging the pencil

set the loc of me to x,y

put x,y into tNewPT--Used for dragging the pencil

if penDown then drag from tOldPt to tNewPt--Draw a line from the CENTER of the ball.

repeat for each line tLine in theLines

--Get the distance between the ball and each line

--as well as the projection point.

put abs(perpDist(the loc of me, tLine)) into tDistToLine

put perpProjPt(the loc of me, tLine) into tProjPoint

if tDistToLine < rMax and ProjPointLiesWithinEndPts(tProjPoint,tLine) then

subtract vx from x

subtract vy from y

set the loc of me to x,y--backup to keep from getting trapped on the line

if char 1 to 2 of the systemversion is 10 then beep

changeToReflectedVel tLine--Set the vel components to their reflected values

exit repeat

end if

end repeat

if the optionkey is down then wait until the optionkey is up

if the ShiftKey is down then

choose the browse tool

set the cursor to hand

exit to top

else send "moveBall x+vx,y+vy" to me in tSpeed millisec

end moveBall

on changeToReflectedVel tLine

put item 1 to 2 of tLine into p1

put item 3 to 4 of tLine into p2

put the loc of me into tLoc

put theTwoPtDist(tLoc,p1) into d1

put theTwoPtDist(tLoc,p2) into d2

if d1 <rMax or d2 < rMax then

multiply vx by -1

multiply vy by -1

exit changeToReflectedVel

end if

put item 2 of p2 - item 2 of p1 into dy

put item 1 of p2 - item 1 of p1 into dx

put aTan2(dy,dx) into angleL

put aTan2(vy,vx) into angleV

put sqrt(vx*vx+vy*vy) into v

put v * cos(2*angleL-angleV) into vx--A lettle geometry here.

put v * sin (2*angleL - angleV) into vy

end changeToReflectedVel

on mouseDown

grab me

end mouseDown

speedia 7240 cREVGeneral revUniqueID 1108340866467 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script Field 1)F2 cREVGeneral revUniqueID 1108342523075  Speed Field 1)j cREVGeneral revUniqueID 1108342633221  Shift key to stopReset the ballEpe on mouseUP set the loc of grc "ball" to 200,100 set the width of grc "ball" to 25 set the height of grc "ball"to 25 repeat until the number of images is 0 delete image 1 end repeat put (the thumbposition of scrollbar "diameter") into rMax set the width of grc "ball" to 2*rMax set the height of grc "ball" to 2*rMax end mouseUP h  cREVGeneral scriptChecksumeF a+]h: handlerListmouseUP breakPoints10scriptSelectionchar 318 to 317 revUniqueID 1108430058696 bookmarks tempScript prevHandler mouseMovescript-

on mouseUP

set the loc of grc "ball" to 200,100

set the width of grc "ball" to 25

set the height of grc "ball"to 25

repeat until the number of images is 0

delete image 1

end repeat

put (the thumbposition of scrollbar "diameter") into rMax

set the width of grc "ball" to 2*rMax

set the height of grc "ball" to 2*rMax

end mouseUP

 Diameteriqon scrollbardrag tValue set the width of grc "ball" to 2*tValue set the height of grc "ball" to 2*tValue end scrollbardrag h 550 cREVGeneralscriptChecksumba닋N'OHP revUniqueID 1108498536155 bookmarks handlerList scrollbardrag tempScript prevHandler scrollbardragscriptSelectionchar 103 to 102script?

on scrollbardrag tValue

set the width of grc "ball" to 2*tValue

set the height of grc "ball" to 2*tValue

end scrollbardrag

)J cREVGeneral revUniqueID 1108498536156  Diameter  Instructions)`( cREVGeneral revUniqueID 1108511492272  @Now you see that the ball moves freely throughout the polygon. @? @ The ball not only checks the distance to the polygon lines but whether it will strike a line between its end points. It does this by checking the perpProjPt (perpendicular projection from the ball to the line.) If this point lies between the ends, it recognizes the line; otherwise not. @ @ (It determines whether the projection point is between the end points by looking at the distance to the end points. These distances must both be less than the length of the line. @ @ hThis technique may be extended to obstacles other than the confining walls of a polygon. See next card. @g  `)  velocity)`$= cREVGeneral revUniqueID 1108655182496  0,3 +i! cREVGeneral revUniqueID 1108674937012  Starting velocity componentsReset the ballEph on mouseUP set the loc of grc "ball" to 127,298 set the width of grc "ball" to 30 set the height of grc "ball"to 30 repeat until the number of images is 0 delete image 1 end repeat --put (the thumbposition of scrollbar "diameter") into rMax --set the width of grc "ball" to 2*rMax -- set the height of grc "ball" to 2*rMax end mouseUP h g cREVGeneral scriptChecksumh?4ߵװ breakPoints10 handlerListmouseUPscriptSelectionchar 123 to 122 bookmarks revUniqueID 1108430058696 prevHandlermouseUP tempScriptscript)

on mouseUP

set the loc of grc "ball" to 127,298

set the width of grc "ball" to 30

set the height of grc "ball"to 30

repeat until the number of images is 0

delete image 1

end repeat

--put (the thumbposition of scrollbar "diameter") into rMax

--set the width of grc "ball" to 2*rMax

-- set the height of grc "ball" to 2*rMax

end mouseUP

 Instructions)h cREVGeneral revUniqueID 1108511492272  How does it work? @ @ `Drag the blue ball. When the ball encounters a line (and this lines, like those in the previous examples, act like the lines in Euclidean geometry, that is, they are assumed to extend to infinity in both directions.) To keep the ball from interacting with the line segment beyond the end points, I have used the perpProjPt function (see ball script). @_ @ wConsider any point above a geometrical line. Drop a perpendicular from the point to the line. That is the perpProjPt. @v @ NIf this point lies outside the finite line segment (bewteen the end points), the line ignores the ball or, if you like, the bouncing ball (of the previous card) ignores the line. It recognizes the point to be between the end points of the line segment if the distance from perpProjPt to EACH end is less than the length of the line. @M @ 2The line of code which triggers the collision is: @1 @ Q if tDistToLine < rMax and ProjPointLiesWithinEndPts(tProjPoint,tLine) then Qwhere tDistToLine is calculated with the "perpDist" function (see card script.) @ 1I have not included flexing. Im all flexed out. @0 `myLineKV&on mouseDown grab me end mouseDown s.du 0 cREVGeneralscriptChecksum{zSQl bookmarks revUniqueID 1108597771034 handlerList mouseDownscriptSelection char 23 to 22 prevHandler tempScriptscript9

on mouseDown

grab me

end mouseDown

 projLineKV&on mouseDown grab me end mouseDown #$6$X cREVGeneralscriptChecksum{zSQl revUniqueID 1108676553434 bookmarks handlerList mouseDown tempScript prevHandlerscriptSelection char 23 to 22script9

on mouseDown

grab me

end mouseDown

data*cb& cREVGeneral revUniqueID 1108677504429  Between end points ballKTlocal myName, tPoints on mouseDown put the name of me into myName put points of grc "myLine" into tPoints end mouseDown on mouseUP put "" into myname end mouseUP on mouseMove u,v if myName is "" then exit mouseMove set the loc of me to u,v put perpProjPt(the loc of me, tPoints) into thePerpPoint set the points of grc "projLine" to (the loc of me, thePerpPoint) put ProjPointLiesWithinEndPts(thePerpPoint,tPoints) into tText put tText into field "data" set the loc of field "data" to item 1 of thePerpPoint + 20, (item 2 of thePerpPoint +30) put "Distance to line is " &round(abs(perpDist(the loc of me, tPoints))) into field "data2" set the loc of field "data2" to (item 1 of the loc of me +60),item 2 of the loc of me end mouseMove  penStatetrueh cREVGeneral scriptChecksum3ZP³W=/: handlerListmouseDown mouseUP mouseMove breakPoints17 63scriptSelectionchar 140 to 139 revUniqueID 1107870321097 bookmarks tempScript prevHandlerProjPointLiesWithinEndPtsscript

local myName, tPoints

on mouseDown

put the name of me into myName

put points of grc "myLine" into tPoints

end mouseDown

on mouseUP

put "" into myname

end mouseUP

on mouseMove u,v

if myName is "" then exit mouseMove

set the loc of me to u,v

put perpProjPt(the loc of me, tPoints) into thePerpPoint

set the points of grc "projLine" to (the loc of me, thePerpPoint)

put ProjPointLiesWithinEndPts(thePerpPoint,tPoints) into tText

put tText into field "data"

set the loc of field "data" to item 1 of thePerpPoint + 20, (item 2 of thePerpPoint +30)

put "Distance to line is " &round(abs(perpDist(the loc of me, tPoints))) into field "data2"

set the loc of field "data2" to (item 1 of the loc of me +60),item 2 of the loc of me

end mouseMove

data2*Q& cREVGeneral revUniqueID 1108679267506 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script  Distance to line is 62 ReturnEp.on mouseUP go to previous card end mouseUP NA cREVGeneralscriptChecksum~aȣzg, revUniqueID 1108703566060 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 33 to 32scriptA

on mouseUP

go to previous card

end mouseUP

dballKT plocal vx,vy,rMax,tFlex,tSpeed,theLines,x,y,penDown,myName on mouseUP repeat until the number of images is 0 delete image 1 end repeat put the penState of me into penDown put the thumbposition of scrollbar "diameter" into rMax set the endvalue of scrollbar "flex" to rMax -3 put the thumbposition of scrollbar "flex" into tFlex set the width of me to 2*rMax set the height of me to 2*rMax put the thumbposition of scrollbar "speed" into tspeed put the endvalue of scrollbar "speed" - tSpeed into tSpeed put 4 into vx--or whatever put 4 into vy--or whatever put the loc of me into tLoc --Separate the polygon into a collection of individual lines --See the card script put thePolyLines(the points of grc "myPoly") into theLines put item 1 of the loc of me into x put item 2 of the loc of me into y put 350,300 into temp if penDown then choose the pencil tool MoveBall x,y--item 1 of tLoc, item 2 of tLoc--random(L),random(L) end mouseUp on moveBall x,y put the loc of me into tOldPt--Used for dragging the pencil set the loc of me to x,y put x,y into tNewPT--Used for dragging the pencil --Draw a line from the CENTER of the ball. if penDown then drag from tOldPt to tNewPt repeat for each line theLine in theLines --Check for distance between ball and line. put x,y into tPoint put Abs(perpDist(tPoint,theLine))into tDist if tDist+tFlex < rMax then subtract vx from x subtract vy from y set the loc of me to x,y--backup to keep from getting trapped on the line if char 1 to 2 of the systemversion is 10 then beep changeToReflectedVel theLine--Set the vel components to their reflected values add vx to x; add vy to y end if end repeat setDiameter tPoint--Adjust the diameter for the flex if the optionkey is down then wait until the optionkey is up if the ShiftKey is down then choose the browse tool set the cursor to hand exit to top else send "moveBall x+vx,y+vy" to me in tSpeed millisec end moveBall on changeToReflectedVel tLine put aTan2(item 4 of tLine-item 2 of tLine,item 3 of tLine - item 1 of tLine) into angleL put aTan2(vy,vx) into angleV put sqrt(vx*vx+vy*vy) into v put v * cos(2*angleL-angleV) into vx--A lettle geometry here. put v * sin (2*angleL - angleV) into vy end changeToReflectedVel on setDiameter pt repeat with i = 1 to the number of lines in theLines put line i of theLines into tLine put abs(perpDist(pt,tLine)) into d if d < rMax then set the width of me to 2*d set the height of me to 2*d exit "setDiameter" -- Don't worry about corners end if end repeat set the width of me to 2*rMax set the height of me to 2*rMax end setDiameter function perpDist tP,tLine put item 1 of tLine into x2 put item 2 of tLine into y2 put item 3 of tLine into x3 put item 4 of tLine into y3 put item 1 of tP into x1 put item 2 of tP into y1 if x3-x2 is 0 then return (x1-x2) else put (y3-y2)/(x3-x2) into m -- The slope return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m) end if end perpDist on mouseDown grab me end mouseDown  blue77 penStatefalseh cREVGeneral scriptChecksumD^,uth": handlerListDmouseUP moveBall changeToReflectedVel setDiameter perpDist mouseDown breakPoints35 102scriptSelectionchar 847 to 846 revUniqueID 1107870321097 bookmarks tempScript prevHandlermoveBallscript2

local vx,vy,rMax,tFlex,tSpeed,theLines,x,y,penDown,myName

on mouseUP

repeat until the number of images is 0

delete image 1

end repeat

put the penState of me into penDown

put the thumbposition of scrollbar "diameter" into rMax

set the endvalue of scrollbar "flex" to rMax -3

put the thumbposition of scrollbar "flex" into tFlex

set the width of me to 2*rMax

set the height of me to 2*rMax

put the thumbposition of scrollbar "speed" into tspeed

put the endvalue of scrollbar "speed" - tSpeed into tSpeed

put 4 into vx--or whatever

put 4 into vy--or whatever

put the loc of me into tLoc

--Separate the polygon into a collection of individual lines

--See the card script

put thePolyLines(the points of grc "myPoly") into theLines

put item 1 of the loc of me into x

put item 2 of the loc of me into y

put 350,300 into temp

if penDown then choose the pencil tool

MoveBall x,y--item 1 of tLoc, item 2 of tLoc--random(L),random(L)

end mouseUp

on moveBall x,y

put the loc of me into tOldPt--Used for dragging the pencil

set the loc of me to x,y

put x,y into tNewPT--Used for dragging the pencil

--Draw a line from the CENTER of the ball.

if penDown then drag from tOldPt to tNewPt

repeat for each line theLine in theLines

--Check for distance between ball and line.

put x,y into tPoint

put Abs(perpDist(tPoint,theLine))into tDist

if tDist+tFlex < rMax then

subtract vx from x

subtract vy from y

set the loc of me to x,y--backup to keep from getting trapped on the line

if char 1 to 2 of the systemversion is 10 then beep

changeToReflectedVel theLine--Set the vel components to their reflected values

add vx to x; add vy to y

end if

end repeat

setDiameter tPoint--Adjust the diameter for the flex

if the optionkey is down then wait until the optionkey is up

if the ShiftKey is down then

choose the browse tool

set the cursor to hand

exit to top

else send "moveBall x+vx,y+vy" to me in tSpeed millisec

end moveBall

on changeToReflectedVel tLine

put aTan2(item 4 of tLine-item 2 of tLine,item 3 of tLine - item 1 of tLine) into angleL

put aTan2(vy,vx) into angleV

put sqrt(vx*vx+vy*vy) into v

put v * cos(2*angleL-angleV) into vx--A lettle geometry here.

put v * sin (2*angleL - angleV) into vy

end changeToReflectedVel

on setDiameter pt

repeat with i = 1 to the number of lines in theLines

put line i of theLines into tLine

put abs(perpDist(pt,tLine)) into d

if d < rMax then

set the width of me to 2*d

set the height of me to 2*d

exit "setDiameter" -- Don't worry about corners

end if

end repeat

set the width of me to 2*rMax

set the height of me to 2*rMax

end setDiameter

function perpDist tP,tLine

put item 1 of tLine into x2

put item 2 of tLine into y2

put item 3 of tLine into x3

put item 4 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return (x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)

end if

end perpDist

on mouseDown

grab me

end mouseDown

zmyPolyK black9A'!uXC^^+;+uW cREVGeneral bookmarks revUniqueID 1108498307386 handlerListscriptSelection char 1 to 0 prevHandler tempScriptscriptspeedia  240 cREVGeneral revUniqueID 1108340866467 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script Field 1)D2 cREVGeneral revUniqueID 1108342523075  Speed Field 1)j cREVGeneral revUniqueID 1108342633221  Shift key to stopflexia 7.953672 cREVGeneral bookmarks revUniqueID 1108343705619 handlerListscriptSelection char 1 to 0 prevHandler tempScriptscript Field 1)F2 cREVGeneral revUniqueID 1108343966445  FlexmyLineKblackpoitns 272.445501,144.300445! cREVGeneral revUniqueID 1108395006710 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0scriptReset the ballEpe on mouseUP set the loc of grc "ball" to 200,100 set the width of grc "ball" to 25 set the height of grc "ball"to 25 repeat until the number of images is 0 delete image 1 end repeat put (the thumbposition of scrollbar "diameter") into rMax set the width of grc "ball" to 2*rMax set the height of grc "ball" to 2*rMax end mouseUP h & cREVGeneral scriptChecksumeF a+]h: handlerListmouseUP breakPoints10scriptSelectionchar 318 to 317 revUniqueID 1108430058696 bookmarks tempScript prevHandler mouseMovescript-

on mouseUP

set the loc of grc "ball" to 200,100

set the width of grc "ball" to 25

set the height of grc "ball"to 25

repeat until the number of images is 0

delete image 1

end repeat

put (the thumbposition of scrollbar "diameter") into rMax

set the width of grc "ball" to 2*rMax

set the height of grc "ball" to 2*rMax

end mouseUP

 Diameteriqon scrollbardrag tValue set the width of grc "ball" to 2*tValue set the height of grc "ball" to 2*tValue end scrollbardrag  '550 cREVGeneralscriptChecksumba닋N'OHP revUniqueID 1108498536155 bookmarks handlerList scrollbardrag tempScript prevHandler scrollbardragscriptSelectionchar 103 to 102script?

on scrollbardrag tValue

set the width of grc "ball" to 2*tValue

set the height of grc "ball" to 2*tValue

end scrollbardrag

)J cREVGeneral revUniqueID 1108498536156  DiameterPen UpEpon mouseUP if the penState of grc "ball" is true then set the penState of grc "ball" to false set the name of me to "Pen Up" else set the penState of grc "ball" to true set the name of me to "Pen Down" end if end mouseUP %F" cREVGeneralscriptChecksumմ߽P7S revUniqueID 1108506874770 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelectionchar 231 to 230scriptc

on mouseUP

if the penState of grc "ball" is true then

set the penState of grc "ball" to false

set the name of me to "Pen Up"

else

set the penState of grc "ball" to true

set the name of me to "Pen Down"

end if

end mouseUP

 Instructions)`Hp cREVGeneral revUniqueID 1108511492272  uIn the previous card the confining polygon was everywhere concave, i.e. all apex angles were less than 180 degrees. @t @ :In the figure below, the polygon is convex at one vertex. @9 @ If you start the ball in motion in any one of the three sectors, you will notice that it confines itself to that sector, even though there is not apparent barrier between them; the only constraint is that the ball remain within the bounding polygram. @ @ ?The reason for this behavior is that the constraint is that the ball be reflected when its DISTANCE from a line is less than the radius of the ball. But the perpDist function measures the distance from the line as if it were a line in Euclidean geometry, that is, a line which extends to infinity in both directions. @> @ sSo you see, if you extend the two lines at the top of the polygon, they subdivide the polygon into three sectors. @r @ To solve this problem and allow the ball access to the entire polygon, it is necessary to examine not only the distance of the ball from the line but also whether the ball will strike the line BETWEEN its end points. @ @ pThe ball must find another test of the line to see if it will strike between the end points. See the next card. @o  `n ConfinedAreaKBblack<$!^`,<,\^ cREVGeneral revUniqueID 1108899014881myPolyK black:)'!+__+<++ cREVGeneral revUniqueID 1108498307386 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0scriptmyPolyK blackN! zSggP  cREVGeneral revUniqueID 1108928443754 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0scriptPen UpEpon mouseUP if the penState of grc "ball" is true then set the penState of grc "ball" to false set the name of me to "Pen Up" else set the penState of grc "ball" to true set the name of me to "Pen Down" end if end mouseUP F` cREVGeneralscriptChecksumմ߽P7S bookmarks revUniqueID 1108932040072 handlerListmouseUPscriptSelectionchar 231 to 230 prevHandlermouseUP tempScriptscriptc

on mouseUP

if the penState of grc "ball" is true then

set the penState of grc "ball" to false

set the name of me to "Pen Up"

else

set the penState of grc "ball" to true

set the name of me to "Pen Down"

end if

end mouseUP

Field 1)\+< cREVGeneral revUniqueID 1108942420955  II  Field 1)66 cREVGeneral revUniqueID 1108942503466  III  Field 1)2= cREVGeneral revUniqueID 1108942517596  I ballKT local vx,vy,rMax,tFlex,tSpeed,theLines,penDown,myName on mouseUP repeat until the number of images is 0 delete image 1 end repeat put the thumbposition of scrollbar "diameter" into rMax set the endvalue of scrollbar "flex" to rMax -4 put the thumbposition of scrollbar "flex" into tFlex put the penState of me into penDown set the width of me to 2*rMax set the height of me to 2*rMax put the thumbposition of scrollbar "speed" into tspeed put the endvalue of scrollbar "speed" - tSpeed into tSpeed put 4 into vx--or whatever put 4 into vy--or whatever put the loc of me into tLoc --Separate the polygon into a collection of individual lines --See the card script put thePolyLines(the points of grc "myPoly") into theLines put item 1 of the loc of me into x put item 2 of the loc of me into y if pendown then choose the pencil tool set the cursor to watch MoveBall x,y end mouseUp on moveBall x,y put the loc of me into tOldPt--Used for dragging the pencil set the loc of me to round(x),round(y) put x,y into tNewPT--Used for dragging the pencil if penDown then drag from tOldPt to tNewPt--Draw a line from the CENTER of the ball. repeat for each line theLine in theLines--with i = 1 to the number of lines in theLines put x,y into tPoint put Abs(perpDist(tPoint,theLine))into tDist if tDist+tFlex < rMax then subtract vx from x subtract vy from y set the loc of me to x,y--backup to keep from getting trapped on the line if char 1 of the systemversion is 1 then beep changeToReflectedVel theLine--Set the vel components to their reflected values add vx to x; add vy to y end if end repeat setDiameter tPoint--Adjust the diameter for the flex if the optionkey is down then wait until the optionkey is up if the ShiftKey is down then choose the browse tool set the cursor to hand exit to top else send "moveBall x+vx,y+vy" to me in tSpeed millisec end moveBall on changeToReflectedVel tLine --This handler used to get the direction of the reflected ball after collision put aTan2(item 4 of tLine-item 2 of tLine,item 3 of tLine - item 1 of tLine) into angleL put aTan2(vy,vx) into angleV put sqrt(vx*vx+vy*vy) into v put v * cos(2*angleL-angleV) into vx--A lettle geometry here. put v * sin (2*angleL - angleV) into vy end changeToReflectedVel on setDiameter pt repeat with i = 1 to the number of lines in theLines put line i of theLines into tLine put abs(perpDist(pt,tLine)) into d if d < rMax then set the width of me to 2*d set the height of me to 2*d exit "setDiameter" -- Don't worry about corners end if end repeat set the width of me to 2*rMax set the height of me to 2*rMax end setDiameter function perpDist tP,tLine put item 1 of tLine into x2 put item 2 of tLine into y2 put item 3 of tLine into x3 put item 4 of tLine into y3 put item 1 of tP into x1 put item 2 of tP into y1 if x3-x2 is 0 then return (x1-x2) else put (y3-y2)/(x3-x2) into m -- The slope return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m) end if end perpDist on mouseDown grab me end mouseDown  bluez penStatefalseh cREVGeneral scriptChecksumiV2S! breakPoints7 handlerListDmouseUP moveBall changeToReflectedVel setDiameter perpDist mouseDownscriptSelectionchar 345 to 344 bookmarks revUniqueID 1107870321097 prevHandlerchangeToReflectedVel tempScriptscript

local vx,vy,rMax,tFlex,tSpeed,theLines,penDown,myName

on mouseUP

repeat until the number of images is 0

delete image 1

end repeat

put the thumbposition of scrollbar "diameter" into rMax

set the endvalue of scrollbar "flex" to rMax -4

put the thumbposition of scrollbar "flex" into tFlex

put the penState of me into penDown

set the width of me to 2*rMax

set the height of me to 2*rMax

put the thumbposition of scrollbar "speed" into tspeed

put the endvalue of scrollbar "speed" - tSpeed into tSpeed

put 4 into vx--or whatever

put 4 into vy--or whatever

put the loc of me into tLoc

--Separate the polygon into a collection of individual lines

--See the card script

put thePolyLines(the points of grc "myPoly") into theLines

put item 1 of the loc of me into x

put item 2 of the loc of me into y

if pendown then choose the pencil tool

set the cursor to watch

MoveBall x,y

end mouseUp

on moveBall x,y

put the loc of me into tOldPt--Used for dragging the pencil

set the loc of me to round(x),round(y)

put x,y into tNewPT--Used for dragging the pencil

if penDown then drag from tOldPt to tNewPt--Draw a line from the CENTER of the ball.

repeat for each line theLine in theLines--with i = 1 to the number of lines in theLines

put x,y into tPoint

put Abs(perpDist(tPoint,theLine))into tDist

if tDist+tFlex < rMax then

subtract vx from x

subtract vy from y

set the loc of me to x,y--backup to keep from getting trapped on the line

if char 1 of the systemversion is 1 then beep

changeToReflectedVel theLine--Set the vel components to their reflected values

add vx to x; add vy to y

end if

end repeat

setDiameter tPoint--Adjust the diameter for the flex

if the optionkey is down then wait until the optionkey is up

if the ShiftKey is down then

choose the browse tool

set the cursor to hand

exit to top

else send "moveBall x+vx,y+vy" to me in tSpeed millisec

end moveBall

on changeToReflectedVel tLine

--This handler used to get the direction of the reflected ball after collision

put aTan2(item 4 of tLine-item 2 of tLine,item 3 of tLine - item 1 of tLine) into angleL

put aTan2(vy,vx) into angleV

put sqrt(vx*vx+vy*vy) into v

put v * cos(2*angleL-angleV) into vx--A lettle geometry here.

put v * sin (2*angleL - angleV) into vy

end changeToReflectedVel

on setDiameter pt

repeat with i = 1 to the number of lines in theLines

put line i of theLines into tLine

put abs(perpDist(pt,tLine)) into d

if d < rMax then

set the width of me to 2*d

set the height of me to 2*d

exit "setDiameter" -- Don't worry about corners

end if

end repeat

set the width of me to 2*rMax

set the height of me to 2*rMax

end setDiameter

function perpDist tP,tLine

put item 1 of tLine into x2

put item 2 of tLine into y2

put item 3 of tLine into x3

put item 4 of tLine into y3

put item 1 of tP into x1

put item 2 of tP into y1

if x3-x2 is 0 then

return (x1-x2)

else

put (y3-y2)/(x3-x2) into m -- The slope

return (m*(x1-x2)-(y1-Y2))/sqrt(1+m*m)

end if

end perpDist

on mouseDown

grab me

end mouseDown

ballKTlocal L, vx,vy,rMax,tFlex,tSpeed,tLines on mouseDown grab me end mouseDown on mouseUP put the width of this stack into L set the height of this stack to L put the thumbposition of scrollbar "diameter" into rMax set the endvalue of scrollbar "flex" to rMax put the thumbposition of scrollbar "flex" into tFlex put rMax - tFlex into tFlex set the width of me to 2*rMax set the height of me to 2*rMax put the thumbposition of scrollbar "speed" into tspeed put the endvalue of scrollbar "speed" - tSpeed into tSpeed put 3 into vx put 5 into vy put the loc of me into tLoc put item 1 of tLoc into x put item 2 of tLoc into y put 0,0,0,L & cr & 0,0,L,0 & cr & 0,L,L,L & cr & L,0,L,L into tLines MoveBall x,y end mouseUp on moveBall x,y switch case y + tFlex > L multiply vy by -1 break case y - tFlex < 0 multiply vy by -1 break case x - tFlex < 0 multiply vx by -1 break case x + tFlex > L multiply vx by -1 break end switch set the loc of me to x,y put x,y into tPoint setDiameter tPoint if the ShiftKey is down then exit to top else send "moveBall x+vx,y+vy" to me in tSpeed millisec end moveBall on setDiameter pt repeat for each line tLine in tLines put perpDist(pt,tLine) into d if d < rMax then if Horizontal(tLine)then set the width of me to 2*rMax + (rMax-d) set the height of me to 2*d exit "setDiameter" -- Don't worry about corners else set the height of me to 2*rMax+ (rMax-d) set the width of me to 2*d exit "setDiameter" -- Don't worry about corners end if end if end repeat set the width of me to 2*rMax set the height of me to 2*rMax end setDiameter function Horizontal tLine --Determine whether the boundary wall is horizontal or not if item 2 of tLine = item 4 of tLine then return true if item 1 of tLine = item 3 of tLine then return false exit to top end Horizontal  blueRdd25Box/0,0,0,479 0,0,479,0 0,479,479,479 479,0,479,479vx32525vy1h cREVGeneral scriptChecksumEف.Q|}V}%F{, breakPoints51 72 handlerList1mouseDown mouseUP moveBall setDiameter HorizontalscriptSelectionchar 742 to 741 bookmarks revUniqueID 1107870321097 prevHandler Horizontal tempScriptscript'

local L, vx,vy,rMax,tFlex,tSpeed,tLines

on mouseDown

grab me

end mouseDown

on mouseUP

put the width of this stack into L

set the height of this stack to L

put the thumbposition of scrollbar "diameter" into rMax

set the endvalue of scrollbar "flex" to rMax

put the thumbposition of scrollbar "flex" into tFlex

put rMax - tFlex into tFlex

set the width of me to 2*rMax

set the height of me to 2*rMax

put the thumbposition of scrollbar "speed" into tspeed

put the endvalue of scrollbar "speed" - tSpeed into tSpeed

put 3 into vx

put 5 into vy

put the loc of me into tLoc

put item 1 of tLoc into x

put item 2 of tLoc into y

put 0,0,0,L & cr & 0,0,L,0 & cr & 0,L,L,L & cr & L,0,L,L into tLines

MoveBall x,y

end mouseUp

on moveBall x,y

switch

case y + tFlex > L

multiply vy by -1

break

case y - tFlex < 0

multiply vy by -1

break

case x - tFlex < 0

multiply vx by -1

break

case x + tFlex > L

multiply vx by -1

break

end switch

set the loc of me to x,y

put x,y into tPoint

setDiameter tPoint

if the ShiftKey is down then exit to top

else send "moveBall x+vx,y+vy" to me in tSpeed millisec

end moveBall

on setDiameter pt

repeat for each line tLine in tLines

put perpDist(pt,tLine) into d

if d < rMax then

if Horizontal(tLine)then

set the width of me to 2*rMax + (rMax-d)

set the height of me to 2*d

exit "setDiameter" -- Don't worry about corners

else

set the height of me to 2*rMax+ (rMax-d)

set the width of me to 2*d

exit "setDiameter" -- Don't worry about corners

end if

end if

end repeat

set the width of me to 2*rMax

set the height of me to 2*rMax

end setDiameter

function Horizontal tLine

--Determine whether the boundary wall is horizontal or not

if item 2 of tLine = item 4 of tLine then return true

if item 1 of tLine = item 3 of tLine then return false

exit to top

end Horizontal

speedia  p240 cREVGeneral revUniqueID 1108340866467 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script Field 1)D2 cREVGeneral revUniqueID 1108342523075  Speed Success) Tg& cREVGeneral revUniqueID 1108342633221  Reset the ballEpe on mouseUP set the loc of grc "ball" to 200,100 set the width of grc "ball" to 25 set the height of grc "ball"to 25 repeat until the number of images is 0 delete image 1 end repeat put (the thumbposition of scrollbar "diameter") into rMax set the width of grc "ball" to 2*rMax set the height of grc "ball" to 2*rMax end mouseUP h f cREVGeneral scriptChecksumeF a+]h: handlerListmouseUP breakPoints10scriptSelectionchar 318 to 317 revUniqueID 1108430058696 bookmarks tempScript prevHandler mouseMovescript-

on mouseUP

set the loc of grc "ball" to 200,100

set the width of grc "ball" to 25

set the height of grc "ball"to 25

repeat until the number of images is 0

delete image 1

end repeat

put (the thumbposition of scrollbar "diameter") into rMax

set the width of grc "ball" to 2*rMax

set the height of grc "ball" to 2*rMax

end mouseUP

 Diameteraqon scrollbardrag tValue set the width of grc "ball" to 2*tValue set the height of grc "ball" to 2*tValue end scrollbardrag  Z550 cREVGeneralscriptChecksumba닋N'OHP revUniqueID 1108498536155 bookmarks handlerList scrollbardrag tempScript prevHandler scrollbardragscriptSelectionchar 103 to 102script?

on scrollbardrag tValue

set the width of grc "ball" to 2*tValue

set the height of grc "ball" to 2*tValue

end scrollbardrag

 Instructions)`v cREVGeneral revUniqueID 1108511492272  It is possible to all for collisions with individual lines not connected in a polygon. But it is FRAUGHT with difficulties. It is very troublesome dealing with the end points. I tried making the end points into small elastic spheres and that works up to a point. @ @ But the real problem come in when the ball comes to a point of intersection between two lines which intersect when extended. Never mind. Trust me this is hard stuff. @ @ BYour task here in, should you choose to waste your time doing it: @A @ Drag the blue ball to position and release. It must first strike the thick red line and eventually strikes the green button. Hit the shift key to stop and start over. @ @ Not very exciting. But.... @ @ jSince this ball-on-line example is so limited, I wanted to try ball-on-ball collisions. But with a twist. @i @ The simplest way to approach this problem is to let the "cue" ball move in small steps proportional to the velocity. And then check to see if it has hit anything. I'm sure many of you have done this, and it works reasonably well. @ @ %But there are a couple of problems: @$ 91) I have experienced a screen-refresh problem in OS X. @8 52) Since the cue ball doesn't detect a collision until after it has penetrated the target, there are problems in getting reproducible, accurate results, and, as you will see, collisions between balls is VERY sensitive to the position of the collision site--a problem not encountered in collisions with walls. @4 @ 4These issues are fleshed out on the next few cards. @3  `t Graphic 2K blackoh! cREVGeneral revUniqueID 1108655076163  velocity!`$= cREVGeneral revUniqueID 1108655182496  -3,0 #P$ cREVGeneral revUniqueID 1108674937012  Velocity components Graphic 3KF/d40 cREVGeneral revUniqueID 1108758068601ballKTlocal vx,vy,rMax,tSpeed,theLines,L,W,H,x,y on mouseUp repeat until the number of images is 0 delete image 1 end repeat put "" into field "success" put (the width of me)/2 into rMax put the thumbposition of scrollbar "speed" into tspeed put the endvalue of scrollbar "speed" - tSpeed into tSpeed if tSpeed =0 then put 1 into tSpeed put "" into theLines --Take the line apart so that they may be treated separately. repeat with i = 1 to the number of graphics --First lines. if the style of grc i is "line" then put the points of grc i into tPoints put line 1 of tPoints into end1 put line 2 of tPoints into end2 put end1,end2 & return after theLines end if --Next polygons. It would be easy to include rectangles if the style of grc i is "polygon" then put the points of grc i into tPoints put thePolyLines(tPoints) after theLines end if end repeat put item 1 of the loc of me into x put item 2 of the loc of me into y put item 1 of field "velocity" into vx put item 2 of field "velocity" into vy put (the width of this window) into W put the Height of this window into H choose the pencil tool moveBall x,y end mouseUp on moveBall x,y put the loc of me into tOldPt set the loc of me to x,y put x,y into tNewPt drag from tOldPt to tNewPt put the loc of me into tLoc if y + rMax > H then multiply vy by -1 if y -rMax < 0 then multiply vy by -1 if x - rMax < 0 then multiply vx by -1 if x + rMax > W then multiply vx by -1 repeat for each line tLine in theLines put abs(perpDist(the loc of me, tLine)) into tDistToLine put perpProjPt(the loc of me, tLine) into tProjPoint put item 1 to 2 of tLine into p1 put item 3 to 4 of tLine into p2 put dist(tLoc,p1) into d1 put dist(tLoc,p2) into d2 put ProjPointLiesWithinEndPts(tProjPoint,tLine)into liesWithTemp --Check for collisions with the end points. if tDistToLine < rMax and not ProjPointLiesWithinEndPts(tProjPoint,tLine)then if d1 < rMax or d2 < rMax then switch case d1< rMax put p1 into tCollEnd break case d2< rMax put p2 into tCollEnd break end switch put tLoc,tCollEnd into tLine --This line above (tLine) is a radial line from the center of the ball (tLoc) --to the nearest collision end point (tCollEnd). --Assume that this collision is --elastic and the end point is a small sphere of negligible radius. --The ball is then effectively colliding with a line tangent to the --to the surface of the ball at the point of impact. That line --will be perpendicular to the radial line (tLine), --hence the addition of pi/2 below. if char 1 of the systemVersion is 1 then beep changeToReflectedVel tLine, pi/2 exit repeat end if end if --Next check conllisions with lines. if tDistToLine < rMax and ProjPointLiesWithinEndPts(tProjPoint,tLine) then set the loc of me to x-vx,y-vy--backup to keep from getting trapped on the line if char 1 to 2 of the systemversion is 10 then beep changeToReflectedVel tLine,0--Set the vel components to their reflected values exit repeat end if end repeat if dist(the loc of me, the loc of button "target") < 5 then beep choose the browse tool put "Success" into field "success" exit to top end if if the optionkey is down then wait until the optionkey is up if the ShiftKey is down then choose the browse tool set the cursor to hand exit to top else send "moveBall x+vx,y+vy" to me in tSpeed millisec end if end moveBall on changeToReflectedVel tLine , additionalRotation put item 1 to 2 of tLine into p1 put item 3 to 4 of tLine into p2 put item 2 of p2 - item 2 of p1 into dy put item 1 of p2 - item 1 of p1 into dx put aTan2(dy,dx) into angleL put aTan2(vy,vx) into angleV add additionalRotation to angleL put sqrt(vx*vx+vy*vy) into v put v * cos(2*angleL-angleV) into vx--A little geometry here. put v * sin (2*angleL - angleV) into vy--And here. end changeToReflectedVel on mouseDown put "" into field "success" grab me end mouseDown &N)) penStatetrueh cREVGeneral scriptChecksumcQux\ԫ breakPoints53 69 77 handlerList/mouseUp moveBall changeToReflectedVel mouseDownscriptSelectionchar 3788 to 4279 bookmarks revUniqueID 1107870321097 prevHandlerchangeToReflectedVel tempScriptscript)

local vx,vy,rMax,tSpeed,theLines,L,W,H,x,y

on mouseUp

repeat until the number of images is 0

delete image 1

end repeat

put "" into field "success"

put (the width of me)/2 into rMax

put the thumbposition of scrollbar "speed" into tspeed

put the endvalue of scrollbar "speed" - tSpeed into tSpeed

if tSpeed =0 then put 1 into tSpeed

put "" into theLines

--Take the line apart so that they may be treated separately.

repeat with i = 1 to the number of graphics

--First lines.

if the style of grc i is "line" then

put the points of grc i into tPoints

put line 1 of tPoints into end1

put line 2 of tPoints into end2

put end1,end2 & return after theLines

end if

--Next polygons. It would be easy to include rectangles

if the style of grc i is "polygon" then

put the points of grc i into tPoints

put thePolyLines(tPoints) after theLines

end if

end repeat

put item 1 of the loc of me into x

put item 2 of the loc of me into y

put item 1 of field "velocity" into vx

put item 2 of field "velocity" into vy

put (the width of this window) into W

put the Height of this window into H

choose the pencil tool

moveBall x,y

end mouseUp

on moveBall x,y

put the loc of me into tOldPt

set the loc of me to x,y

put x,y into tNewPt

drag from tOldPt to tNewPt

put the loc of me into tLoc

if y + rMax > H then multiply vy by -1

if y -rMax < 0 then multiply vy by -1

if x - rMax < 0 then multiply vx by -1

if x + rMax > W then multiply vx by -1

repeat for each line tLine in theLines

put abs(perpDist(the loc of me, tLine)) into tDistToLine

put perpProjPt(the loc of me, tLine) into tProjPoint

put item 1 to 2 of tLine into p1

put item 3 to 4 of tLine into p2

put dist(tLoc,p1) into d1

put dist(tLoc,p2) into d2

put ProjPointLiesWithinEndPts(tProjPoint,tLine)into liesWithTemp

--Check for collisions with the end points.

if tDistToLine < rMax and not ProjPointLiesWithinEndPts(tProjPoint,tLine)then

if d1 < rMax or d2 < rMax then

switch

case d1< rMax

put p1 into tCollEnd

break

case d2< rMax

put p2 into tCollEnd

break

end switch

put tLoc,tCollEnd into tLine

--This line above (tLine) is a radial line from the center of the ball (tLoc)

--to the nearest collision end point (tCollEnd).

--Assume that this collision is

--elastic and the end point is a small sphere of negligible radius.

--The ball is then effectively colliding with a line tangent to the

--to the surface of the ball at the point of impact. That line

--will be perpendicular to the radial line (tLine),

--hence the addition of pi/2 below.

if char 1 of the systemVersion is 1 then beep

changeToReflectedVel tLine, pi/2

exit repeat

end if

end if

--Next check conllisions with lines.

if tDistToLine < rMax and ProjPointLiesWithinEndPts(tProjPoint,tLine) then

set the loc of me to x-vx,y-vy--backup to keep from getting trapped on the line

if char 1 to 2 of the systemversion is 10 then beep

changeToReflectedVel tLine,0--Set the vel components to their reflected values

exit repeat

end if

end repeat

if dist(the loc of me, the loc of button "target") < 5 then

beep

choose the browse tool

put "Success" into field "success"

exit to top

end if

if the optionkey is down then wait until the optionkey is up

if the ShiftKey is down then

choose the browse tool

set the cursor to hand

exit to top

else

send "moveBall x+vx,y+vy" to me in tSpeed millisec

end if

end moveBall

on changeToReflectedVel tLine , additionalRotation

put item 1 to 2 of tLine into p1

put item 3 to 4 of tLine into p2

put item 2 of p2 - item 2 of p1 into dy

put item 1 of p2 - item 1 of p1 into dx

put aTan2(dy,dx) into angleL

put aTan2(vy,vx) into angleV

add additionalRotation to angleL

put sqrt(vx*vx+vy*vy) into v

put v * cos(2*angleL-angleV) into vx--A little geometry here.

put v * sin (2*angleL - angleV) into vy--And here.

end changeToReflectedVel

on mouseDown

put "" into field "success"

grab me

end mouseDown

 Graphic 4KFJjsK cREVGeneral revUniqueID 1108758072710 Graphic 3KF3}T.4~ cREVGeneral revUniqueID 1108775704639target@+a@D cREVGeneral revUniqueID 1108993693560  StartLineKF:j< cREVGeneral revUniqueID 1108995439960 Field 1+ H cREVGeneral revUniqueID 1109348597700  *Confine a ball within any convex polygon.  )! Next cardEp*on mouseUP go to next card end mouseUP R  cREVGeneralscriptChecksum7Q]1ˋ revUniqueID 1109349981985 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 29 to 28script=

on mouseUP

go to next card

end mouseUP

" Next cardEp*on mouseUP go to next card end mouseUP R  cREVGeneralscriptChecksum7Q]1ˋ revUniqueID 1109350108503 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 29 to 28script=

on mouseUP

go to next card

end mouseUP

# Next cardEp*on mouseUP go to next card end mouseUP R  cREVGeneralscriptChecksum7Q]1ˋ revUniqueID 1109350115241 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 29 to 28script=

on mouseUP

go to next card

end mouseUP

$ Next cardEp*on mouseUP go to next card end mouseUP R  cREVGeneralscriptChecksum7Q]1ˋ revUniqueID 1109350121084 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 29 to 28script=

on mouseUP

go to next card

end mouseUP

% Next cardEp*on mouseUP go to next card end mouseUP R  cREVGeneralscriptChecksum7Q]1ˋ revUniqueID 1109350126647 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 29 to 28script=

on mouseUP

go to next card

end mouseUP

& Next cardEp*on mouseUP go to next card end mouseUP |R cREVGeneralscriptChecksum7Q]1ˋ revUniqueID 1109350133151 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 29 to 28script=

on mouseUP

go to next card

end mouseUP

)CircleKTon mouseDown grab me end mouseDown on mouseUP put the id of me into tID put the short Name of me & tID into tName if there is no grc tName then set the style of the templategraphic to "oval" set the opaque of the templateGraphic to false create grc tName end if put the width of me + the width of grc "ball" into W set the width of grc tName to W set the height of grc tName to W set the loc of grc tName to the loc of me end mouseUP vg<<h cREVGeneralscriptChecksums"  bookmarks revUniqueID 1109033759789 handlerListmouseDown mouseUPscriptSelectionchar 468 to 467 prevHandlermouseU tempScriptscripti

on mouseDown

grab me

end mouseDown

on mouseUP

put the id of me into tID

put the short Name of me & tID into tName

if there is no grc tName then

set the style of the templategraphic to "oval"

set the opaque of the templateGraphic to false

create grc tName

end if

put the width of me + the width of grc "ball" into W

set the width of grc tName to W

set the height of grc tName to W

set the loc of grc tName to the loc of me

end mouseUP

*CircleKTon mouseDown grab me end mouseDown on mouseUP put the id of me into tID put the short Name of me & tID into tName if there is no grc tName then set the style of the templategraphic to "oval" set the opaque of the templateGraphic to false create grc tName end if put the width of me + the width of grc "ball" into W set the width of grc tName to W set the height of grc tName to W set the loc of grc tName to the loc of me end mouseUP <<h cREVGeneral scriptChecksum%TE㙟&F handlerListmouseDown mouseUP breakPoints6scriptSelectionchar 354 to 353 revUniqueID 1109109886658 bookmarks tempScript prevHandler mouseDownscript_

on mouseDown

grab me

end mouseDown

on mouseUP

put the id of me into tID

put the short Name of me & tID into tName

if there is no grc tName then

set the style of the templategraphic to "oval"

set the opaque of the templateGraphic to false

create grc tName

end if

put the width of me + the width of grc "ball" into W

set the width of grc tName to W

set the height of grc tName to W

set the loc of grc tName to the loc of me

end mouseUP

+ Pen downEplocal vx,vy on mouseUP if "down" is in the short name of me then set the penState of grc "Ball" to false set the name of me to "Pen up" else set the penState of grc "Ball" to true set the name of me to "Pen down" end if end mouseUP f  cREVGeneral scriptChecksum/^T*vS%i breakPoints47 handlerListmouseUPscriptSelectionchar 175 to 174 bookmarks revUniqueID 1109112863600 prevHandlerchangeToReflectedVel tempScriptscript

local vx,vy

on mouseUP

if "down" is in the short name of me then

set the penState of grc "Ball" to false

set the name of me to "Pen up"

else

set the penState of grc "Ball" to true

set the name of me to "Pen down"

end if

end mouseUP

-v@KF/tO> cREVGeneral revUniqueID 1109115161603 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script.CircleKTon mouseDown grab me end mouseDown on mouseUP put the id of me into tID put the short Name of me & tID into tName if there is no grc tName then set the style of the templategraphic to "oval" set the opaque of the templateGraphic to false create grc tName end if put the width of me + the width of grc "ball" into W set the width of grc tName to W set the height of grc tName to W set the loc of grc tName to the loc of me end mouseUP ;@<<h cREVGeneralscriptChecksumS@* revUniqueID 1109282519719 bookmarks handlerListmouseDown mouseUP tempScript prevHandlermouseUscriptSelectionchar 343 to 342scriptq

on mouseDown

grab me

end mouseDown

on mouseUP

put the id of me into tID

put the short Name of me & tID into tName

if there is no grc tName then

set the style of the templategraphic to "oval"

set the opaque of the templateGraphic to false

create grc tName

end if

put the width of me + the width of grc "ball" into W

set the width of grc tName to W

set the height of grc tName to W

set the loc of grc tName to the loc of me

end mouseUP

2Field 1)<,f cREVGeneral revUniqueID 1109284290642 : Speed 3Field 1)4f cREVGeneral revUniqueID 1109284313341 : Draw or not 4Field 1)^6f cREVGeneral revUniqueID 1109284325808 : Clean drawing5CleanEp] on mouseUP repeat until the number of images is 0 delete image 1 end repeat end mouseUP `f  cREVGeneral scriptChecksum7֦2ӯ`a¡~ handlerListmouseUP breakPoints47scriptSelection char 69 to 68 revUniqueID 1109284404625 bookmarks tempScript prevHandlerchangeToReflectedVelscript

on mouseUP

repeat until the number of images is 0

delete image 1

end repeat

end mouseUP

6 InstructionsEp5 on mouseUP show field "instructions" end mouseUP f cREVGeneral scriptChecksum&M@XV?8*Hg Q breakPoints47 handlerListmouseUPscriptSelection char 40 to 39 bookmarks revUniqueID 1109284615761 prevHandlerchangeToReflectedVel tempScriptscriptY

on mouseUP

show field "instructions"

end mouseUP

8ballK\(local x,y,vx,vy,v,penDown,r,tTargetList,tVelVector,tBndryLines,tSpeed,tStartLoc,myName local tCorners,W,H on mouseDown put the loc of grc "ball" into tLoc --put the loc of me into tEnd if there is no grc "v" then set the style of the templateGraphic to "line" create grc "v" end if if the optionkey is not down then grab me else put the name of me into myName end mouseDown on mouseUP -- Ignore these first few lines. They were used to set --the walls as a custom property. put the width me /2 into r put "" into tBndryLines put the width of this stack into W put the height of this stack into H put r,r,W-r,r & return after tBndryLines put W-r,r,W-r,H-r & return after tBndryLines put r,r,r,H-r & return after tBndryLines put r,H-r,W-r,H-r after tBndryLines --set the innerBoundary of this card to tBndryLines --put r,r&cr&W-r,r&cr&W-r,H-r&cr&r,H-r into tCorners put "" into myName --set the points of grc "v" to "" if the optionkey is down then doInit end mouseUP on mouseLeave mouseUP end mouseLeave on mouseMove u,v if myName is empty then exit mouseMOve doInit end if set the points of grc "v" to the loc of grc "ball" & cr& u,v end mouseMove on doInit put "" into myName --Delete the tracing repeat until the number of images is 0 delete image 1 end repeat put the thumbposition of scrollbar "speed" into tSpeed put the endValue of scrollbar "speed" - tSpeed into tSpeed --To draw or not to draw; that is the question. put the penState of me into pendown --The pencil tool is faster if penDown then choose the pencil tool --The radius of the cue ball is r. put the width of me /2 into r put the loc of me into tLoc put item 1 of tLoc into x put item 2 of tLoc into y --Get the components of the initial velocity from the --drawn out velocity line. --Use a constant v. Control the speed with the slider. put 5 into v put the points of grc "v" into tPoints --Hide the velocity line. set the points of grc "v" to "" put item 1 of line 2 of tPoints - item 1 of line 1 of tPoints into dx put item 2 of Line 2 of tPoints - item 2 of line 1 of tPoints into dy put atan2(dy,dx) into vAngle --put 180/pi*vAngle into vDegrees put v*cos(vANgle) into vx put v*sin(vAngle) into vy put "" into tTargetList repeat with i = 1 to the number of graphics put the name of grc i into tName if "Oval" is in the style of grc tName then if "Ball" is not in tName then if the opaque of grc tName is true then put the loc of grc i & comma & (the width of grc i)/2 & return after tTargetList end if end if end if end repeat --Start the iterated loop doMove end doInit on doMove put x,y,x+vx,y+vy into tVelVector put x,y into tBackEndOfVelVector put x,y into tLoc put x+vx,y+vy into tFrontEndOfVelVector --Check the target balls repeat for each line tLine in tTargetList --put theDist(item 1 of tLine,tVelVector) into s put item 1 to 2 of tLine into tTargetLoc put item 3 of tLine into tTargetRadius put PerpDist(tTargetLoc, tVelVector) into tImpactRadius if tImpactRadius < tTargetRadius +r then put theCollPt(tLine) into tCollLoc put theDist(tCollLoc,tLoc) into s put theDist(tBackEndOfVelVector,tTargetLoc) into sBI put theDist(tFrontEndOfVelVector,tTargetLoc) into sFI if sBI > sFI then --Get the radial line from the target to the cue ball. put tTargetLoc,tCollLoc into tRadialLine put tCollLoc & cr & tRadialLine& comma &pi/2 into tCollArray[s] put s & comma after tDistances end if end if end repeat --Now check the walls. if tDistances is empty then repeat for each line tLine in tBndryLines put intersection(tLine,tVelVector) into tIntersectionPt put theDist(tIntersectionPt,tBackEndOfVelVector) into sBI put theDist(tIntersectionPt,tFrontEndOfVelVector) into sFI put theDist(tFrontEndOfVelVector,tBackEndOfVelVector) into sV --Either the intersection point is in front of the velocity vector --or between the ends of the velocity vector. if sFI 1 then choose the browse tool exit to top else put asin(sinGamma) into gamma put pi - gamma into gamma put 180/pi*gamma into tempGamma if beta > pi/2 then put pi-alpha-gamma into beta put 180/pi*beta into tempBeta --put pi - beta into beta put 180/pi*beta into tempBeta put a*sin(beta)/sin(alpha) into b put b*vx/v into dBx put b*vy/v into dBy put the loc of me into tLoc put item 1 of tLoc into x put item 2 of tLoc into y put x+dBx,y+dBy into tCollLoc return tCollLoc end theCollPt function theNextTarget xx,yy --Examine the extended velocity line and --determine which target is first intersected. put xx,yy into tLoc --First the the end points of the velocity line. put item 1 to 2 of tVelVector into tBackOfVelVector put item 3 to 4 of tVelVector into tFrontOfVelVector --First look at the balls (red) only. --Do this by droping a perpendicular line from --each red ball onto the (extended) velociity line. --The nearest of these intersection points is the next target ball.) repeat for each line tLine in tTargetList put item 1 to 2 of tLine into tTargetPt put perpDist(tTargetPt,tVelVector) into d if d < (r + item 3 of tLine) then --Check to see if the target is in front of the cue ball --and not behind. Ignore if behind. if theDist(tFrontOfVelVector,tTargetPt)< theDist(tBackOfVelVector,tTargetPt) then put tLine & return after tTargets put theDist(tLoc,tTargetPt) & comma after tDistances end if end if end repeat if tDistances is not empty then --Get the minimum distance. put min(tDistances) into tMin put itemOffset(tMin,tDistances) into tTargetNum put line tTargetNum of tTargets into tTarget --If there is no target ball AHEAD of the cue ball then --look at the walls, boundary lines. else --Boundary intersection points. --put the innerBoundary of this card into tBndryLines repeat for each line tLine in tBndryLines put intersection(tVelVector,tLine) & return after tBndryPtList end repeat --Get the minimum target wall in FRONT of the cue ball's path. put "" into tDistances repeat for each line tPt in tBndryPtList put theDist(tLoc,tPt) & cr after tDistances end repeat put 10000 into tMin repeat with i = 1 to the number of lines in tDistances put line i of tDistances into tDist put line i of tBndryPtList into tTargetPt if tDist < tMin then if theDist(tFrontOfVelVector,tTargetPt)\ < theDist(tBackOfVelVector,tTargetPt) then put i into tMinNum put tDist into tMin end if end if end repeat put line tMinNum of tBndryLines into tTarget end if return tTarget end theNextTarget function theDist p1,p2 --Square root of the sum of the squares. put item 1 of p1 - item 1 of p2 into dx put item 2 of p1 - item 2 of p2 into dy return sqrt(dx*dx+dy*dy) end theDist function theLineAngle p1,p2 --Angle of line defined by the two points p1 and p2 put item 1 of p2 - item 1 of p1 into dx put item 2 of p2 - item 2 of p1 into dy put atan2(dy,dx) into tAngle return tAngle end theLineAngle function theNewVel tLine --This is a generic fuction which determines the --spectral angle of reflection; work for collisions with both --target ball or walls. put item 1 to 2 of tLine into p1 put item 3 to 4 of tLine into p2 put item 5 of tLine into tAddedAngle put item 2 of p2 - item 2 of p1 into dy put item 1 of p2 - item 1 of p1 into dx --Angle of the line being intersected. --This line could be a wall or --a line tangent to a target ball at the --the point of impact. That tangent line --will be perpendicular to the radial line. --Thus add 90 degrees to the radial line. put aTan2(dy,dx) into angleL put aTan2(vy,vx) into angleV add tAddedAngle to angleL put v * cos(2*angleL-angleV) into tVx--A little geometry here. put v * sin (2*angleL - angleV) into tVy--And here. return tVx,tVy end theNewVel function theRound tLine --Utility function to round the two --items in a line. put round(item 1 of tLine) into item 1 of tLine put round(item 2 of tLine) into item 2 of tLine return tLine end theRound 9((pendowntrue startLoc155,86 penStatetrueh cREVGeneral scriptChecksum, .=%3Qִ breakPoints 6 122 163 handlerListtmouseDown mouseUP mouseLeave mouseMove doInit doMove theCollPt theNextTarget theDist theLineAngle theNewVel theRoundscriptSelectionchar 4353 to 4353 bookmarks revUniqueID 1109033770805 prevHandlerdoMove tempScriptscript4

local x,y,vx,vy,v,penDown,r,tTargetList,tVelVector,tBndryLines,tSpeed,tStartLoc,myName

local tCorners,W,H

on mouseDown

put the loc of grc "ball" into tLoc

--put the loc of me into tEnd

if there is no grc "v" then

set the style of the templateGraphic to "line"

create grc "v"

end if

if the optionkey is not down then

grab me

else put the name of me into myName

end mouseDown

on mouseUP

-- Ignore these first few lines. They were used to set

--the walls as a custom property.

put the width me /2 into r

put "" into tBndryLines

put the width of this stack into W

put the height of this stack into H

put r,r,W-r,r & return after tBndryLines

put W-r,r,W-r,H-r & return after tBndryLines

put r,r,r,H-r & return after tBndryLines

put r,H-r,W-r,H-r after tBndryLines

--set the innerBoundary of this card to tBndryLines

--put r,r&cr&W-r,r&cr&W-r,H-r&cr&r,H-r into tCorners

put "" into myName

--set the points of grc "v" to ""

if the optionkey is down then doInit

end mouseUP

on mouseLeave

mouseUP

end mouseLeave

on mouseMove u,v

if myName is empty then

exit mouseMOve

doInit

end if

set the points of grc "v" to the loc of grc "ball" & cr& u,v

end mouseMove

on doInit

put "" into myName

--Delete the tracing

repeat until the number of images is 0

delete image 1

end repeat

put the thumbposition of scrollbar "speed" into tSpeed

put the endValue of scrollbar "speed" - tSpeed into tSpeed

--To draw or not to draw; that is the question.

put the penState of me into pendown

--The pencil tool is faster

if penDown then choose the pencil tool

--The radius of the cue ball is r.

put the width of me /2 into r

put the loc of me into tLoc

put item 1 of tLoc into x

put item 2 of tLoc into y

--Get the components of the initial velocity from the

--drawn out velocity line.

--Use a constant v. Control the speed with the slider.

put 5 into v

put the points of grc "v" into tPoints

--Hide the velocity line.

set the points of grc "v" to ""

put item 1 of line 2 of tPoints - item 1 of line 1 of tPoints into dx

put item 2 of Line 2 of tPoints - item 2 of line 1 of tPoints into dy

put atan2(dy,dx) into vAngle

--put 180/pi*vAngle into vDegrees

put v*cos(vANgle) into vx

put v*sin(vAngle) into vy

put "" into tTargetList

repeat with i = 1 to the number of graphics

put the name of grc i into tName

if "Oval" is in the style of grc tName then

if "Ball" is not in tName then

if the opaque of grc tName is true then

put the loc of grc i & comma & (the width of grc i)/2 & return after tTargetList

end if

end if

end if

end repeat

--Start the iterated loop

doMove

end doInit

on doMove

put x,y,x+vx,y+vy into tVelVector

put x,y into tBackEndOfVelVector

put x,y into tLoc

put x+vx,y+vy into tFrontEndOfVelVector

--Check the target balls

repeat for each line tLine in tTargetList

--put theDist(item 1 of tLine,tVelVector) into s

put item 1 to 2 of tLine into tTargetLoc

put item 3 of tLine into tTargetRadius

put PerpDist(tTargetLoc, tVelVector) into tImpactRadius

if tImpactRadius < tTargetRadius +r then

put theCollPt(tLine) into tCollLoc

put theDist(tCollLoc,tLoc) into s

put theDist(tBackEndOfVelVector,tTargetLoc) into sBI

put theDist(tFrontEndOfVelVector,tTargetLoc) into sFI

if sBI > sFI then

--Get the radial line from the target to the cue ball.

put tTargetLoc,tCollLoc into tRadialLine

put tCollLoc & cr & tRadialLine& comma &pi/2 into tCollArray[s]

put s & comma after tDistances

end if

end if

end repeat

--Now check the walls.

if tDistances is empty then

repeat for each line tLine in tBndryLines

put intersection(tLine,tVelVector) into tIntersectionPt

put theDist(tIntersectionPt,tBackEndOfVelVector) into sBI

put theDist(tIntersectionPt,tFrontEndOfVelVector) into sFI

put theDist(tFrontEndOfVelVector,tBackEndOfVelVector) into sV

--Either the intersection point is in front of the velocity vector

--or between the ends of the velocity vector.

if sFI<sBI or (sBI<sV and sFI<sV) then

put sBI into s

if s is not 0 then put tIntersectionPt& cr& tLine into tCollArray[s]

put s & comma after tDistances

end if

end repeat

end if

--Get the closest collision point.

put min(tDistances) into tMin

put tCollArray[tMin] into temp

put line 1 of temp into tCollLoc

put line 2 of temp into tTargetLine

if penDown then

drag from x,y to tCollLoc

end if

--At long last, do the move.

--I was worried about the time to execute these

--calculations above, but Run Rev came through

--like a champ.

--The move time is set to keep the speed constant,

--independent from the distance between collisions.

put theDist(tLoc,tCollLoc) into s

move me to theRound(tCollLoc) in s/v*tSpeed millisec

put item 1 of tCollLoc into x

put item 2 of tCollLoc into y

--Beeping works well in OS X, but not in Windows of OS 9.

if char 1 to 2 of the systemVersion is 10 then beep

--Now set the velocity for the next collion.

put theNewVel(tTargetLine)into tNewVel

put item 1 of tNewVel into vx

put item 2 of tNewVel into vy

if the shiftkey is down then

choose the browse tool

exit to top

end if

send "doMove" to me in 1 millisec

end doMove

function theCollPt tTarget

--This function determines where the cue ball

--will intersect the (expanded) target ball

--of radius r + a.

--Lots of geometry involved here.

put r+item 3 of tTarget into a

put theLineAngle(item 1 to 2 of tVelVector,item 3 to 4 of tVelVector) into angleV

put 180/pi*angleV into tempV

put item 1 to 2 of tTarget into tTargetLoc

put theLineAngle(the loc of me,tTargetLoc ) into angleC

put 180/pi*angleC into tempC

put angleV - angleC into alpha

if alpha is 0 then add .0001 to alpha

put theDist(the loc of me,tTargetLoc) into c

put c*sin(alpha)/a into sinGamma

if abs(sinGamma) > 1 then

choose the browse tool

exit to top

else put asin(sinGamma) into gamma

put pi - gamma into gamma

put 180/pi*gamma into tempGamma

if beta > pi/2 then put pi-alpha-gamma into beta

put 180/pi*beta into tempBeta

--put pi - beta into beta

put 180/pi*beta into tempBeta

put a*sin(beta)/sin(alpha) into b

put b*vx/v into dBx

put b*vy/v into dBy

put the loc of me into tLoc

put item 1 of tLoc into x

put item 2 of tLoc into y

put x+dBx,y+dBy into tCollLoc

return tCollLoc

end theCollPt

function theNextTarget xx,yy

--Examine the extended velocity line and

--determine which target is first intersected.

put xx,yy into tLoc

--First the the end points of the velocity line.

put item 1 to 2 of tVelVector into tBackOfVelVector

put item 3 to 4 of tVelVector into tFrontOfVelVector

--First look at the balls (red) only.

--Do this by droping a perpendicular line from

--each red ball onto the (extended) velociity line.

--The nearest of these intersection points is the next target ball.)

repeat for each line tLine in tTargetList

put item 1 to 2 of tLine into tTargetPt

put perpDist(tTargetPt,tVelVector) into d

if d < (r + item 3 of tLine) then

--Check to see if the target is in front of the cue ball

--and not behind. Ignore if behind.

if theDist(tFrontOfVelVector,tTargetPt)< theDist(tBackOfVelVector,tTargetPt) then

put tLine & return after tTargets

put theDist(tLoc,tTargetPt) & comma after tDistances

end if

end if

end repeat

if tDistances is not empty then

--Get the minimum distance.

put min(tDistances) into tMin

put itemOffset(tMin,tDistances) into tTargetNum

put line tTargetNum of tTargets into tTarget

--If there is no target ball AHEAD of the cue ball then

--look at the walls, boundary lines.

else

--Boundary intersection points.

--put the innerBoundary of this card into tBndryLines

repeat for each line tLine in tBndryLines

put intersection(tVelVector,tLine) & return after tBndryPtList

end repeat

--Get the minimum target wall in FRONT of the cue ball's path.

put "" into tDistances

repeat for each line tPt in tBndryPtList

put theDist(tLoc,tPt) & cr after tDistances

end repeat

put 10000 into tMin

repeat with i = 1 to the number of lines in tDistances

put line i of tDistances into tDist

put line i of tBndryPtList into tTargetPt

if tDist < tMin then

if theDist(tFrontOfVelVector,tTargetPt)\

< theDist(tBackOfVelVector,tTargetPt) then

put i into tMinNum

put tDist into tMin

end if

end if

end repeat

put line tMinNum of tBndryLines into tTarget

end if

return tTarget

end theNextTarget

function theDist p1,p2

--Square root of the sum of the squares.

put item 1 of p1 - item 1 of p2 into dx

put item 2 of p1 - item 2 of p2 into dy

return sqrt(dx*dx+dy*dy)

end theDist

function theLineAngle p1,p2

--Angle of line defined by the two points p1 and p2

put item 1 of p2 - item 1 of p1 into dx

put item 2 of p2 - item 2 of p1 into dy

put atan2(dy,dx) into tAngle

return tAngle

end theLineAngle

function theNewVel tLine

--This is a generic fuction which determines the

--spectral angle of reflection; work for collisions with both

--target ball or walls.

put item 1 to 2 of tLine into p1

put item 3 to 4 of tLine into p2

put item 5 of tLine into tAddedAngle

put item 2 of p2 - item 2 of p1 into dy

put item 1 of p2 - item 1 of p1 into dx

--Angle of the line being intersected.

--This line could be a wall or

--a line tangent to a target ball at the

--the point of impact. That tangent line

--will be perpendicular to the radial line.

--Thus add 90 degrees to the radial line.

put aTan2(dy,dx) into angleL

put aTan2(vy,vx) into angleV

add tAddedAngle to angleL

put v * cos(2*angleL-angleV) into tVx--A little geometry here.

put v * sin (2*angleL - angleV) into tVy--And here.

return tVx,tVy

end theNewVel

function theRound tLine

--Utility function to round the two

--items in a line.

put round(item 1 of tLine) into item 1 of tLine

put round(item 2 of tLine) into item 2 of tLine

return tLine

end theRound

9 Next cardEp) on mouseUP go to next card end mouseUP 4f  cREVGeneral scriptChecksum H8|@k:1 handlerListmouseUP breakPoints47scriptSelection char 28 to 27 revUniqueID 1109343215595 bookmarks tempScript prevHandlerchangeToReflectedVelscriptC

on mouseUP

go to next card

end mouseUP

<Field 2)`@ cREVGeneral revUniqueID 1109289526235 N Drag the cue ball to a point inside this field. Set the direction (shift/drag) to put the cue ball in the pocket (upper left.) (Hint: go slow, and use the pen down mode. @ Notice how precisely the cue ball must be directed to made a *direct* hit on the pocket. Even harder is it to strike both red balls before going in the pocket. @ =CircleKT on mouseDown grab me put the id of me into tID end mouseDown on mouseUP put the id of me into tID put the short Name of me & tID into tName if there is no grc tName then set the style of the templategraphic to "oval" set the opaque of the templateGraphic to false create grc tName end if put the width of me + the width of grc "ball" into W set the width of grc tName to W set the height of grc tName to W set the loc of grc tName to the loc of me end mouseUP 2<<h cREVGeneralscriptChecksum8up5E revUniqueID 1109033759789 bookmarks handlerListmouseDown mouseUP tempScript prevHandlermouseUscriptSelection char 3 to 2script

on mouseDown

grab me

put the id of me into tID

end mouseDown

on mouseUP

put the id of me into tID

put the short Name of me & tID into tName

if there is no grc tName then

set the style of the templategraphic to "oval"

set the opaque of the templateGraphic to false

create grc tName

end if

put the width of me + the width of grc "ball" into W

set the width of grc tName to W

set the height of grc tName to W

set the loc of grc tName to the loc of me

end mouseUP

ACircleKTon mouseDown grab me end mouseDown on mouseUP put the id of me into tID put the short Name of me & tID into tName if there is no grc tName then set the style of the templategraphic to "oval" set the opaque of the templateGraphic to false create grc tName end if put the width of me + the width of grc "ball" into W set the width of grc tName to W set the height of grc tName to W set the loc of grc tName to the loc of me end mouseUP 8{<<h cREVGeneralscriptChecksums"  bookmarks revUniqueID 1109282519719 handlerListmouseDown mouseUPscriptSelectionchar 468 to 467 prevHandlermouseU tempScriptscripti

on mouseDown

grab me

end mouseDown

on mouseUP

put the id of me into tID

put the short Name of me & tID into tName

if there is no grc tName then

set the style of the templategraphic to "oval"

set the opaque of the templateGraphic to false

create grc tName

end if

put the width of me + the width of grc "ball" into W

set the width of grc tName to W

set the height of grc tName to W

set the loc of grc tName to the loc of me

end mouseUP

BField 1)<,f cREVGeneral revUniqueID 1109284290642 N Speed CField 1)4f cREVGeneral revUniqueID 1109284313341 N Draw or not DField 1)^6f cREVGeneral revUniqueID 1109284325808 N Clean drawingF InstructionsEp5 on mouseUP show field "instructions" end mouseUP fo cREVGeneral scriptChecksum&M@XV?8*Hg Q handlerListmouseUP breakPoints47scriptSelection char 40 to 39 revUniqueID 1109284615761 bookmarks tempScript prevHandlerchangeToReflectedVelscriptY

on mouseUP

show field "instructions"

end mouseUP

JPocket`da64POCKET cREVGeneral revUniqueID 1109288373256 NLGo backEp) on mouseUP go to next card end mouseUP 4fm cREVGeneral scriptChecksum H8|@k:1 handlerListmouseUP breakPoints47scriptSelection char 28 to 27 revUniqueID 1109343305467 bookmarks tempScript prevHandlerchangeToReflectedVelscriptC

on mouseUP

go to next card

end mouseUP

P Next cardEp*on mouseUP go to next card end mouseUP Ri cREVGeneralscriptChecksum7Q]1ˋ revUniqueID 1109350437569 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 29 to 28script=

on mouseUP

go to next card

end mouseUP

QSpeedia  80100 cREVGeneral bookmarks revUniqueID 1109350482391 handlerListscriptSelection char 1 to 0 prevHandler tempScriptscriptR Pen downEp$local vx,vy on mouseUP set the loc of grc "ball" to 200,200 if "down" is in the short name of me then set the penState of grc "Ball" to false set the name of me to "Pen up" else set the penState of grc "Ball" to true set the name of me to "Pen down" end if end mouseUP fk cREVGeneral scriptChecksumx5D؎ handlerListmouseUP breakPoints47scriptSelection char 63 to 62 revUniqueID 1109350482392 bookmarks tempScript prevHandlerchangeToReflectedVelscript

local vx,vy

on mouseUP

set the loc of grc "ball" to 200,200

if "down" is in the short name of me then

set the penState of grc "Ball" to false

set the name of me to "Pen up"

else

set the penState of grc "Ball" to true

set the name of me to "Pen down"

end if

end mouseUP

SCleanEp] on mouseUP repeat until the number of images is 0 delete image 1 end repeat end mouseUP DZk cREVGeneral scriptChecksum7֦2ӯ`a¡~ breakPoints47 handlerListmouseUPscriptSelection char 69 to 68 bookmarks revUniqueID 1109350482393 prevHandlerchangeToReflectedVel tempScriptscript

on mouseUP

repeat until the number of images is 0

delete image 1

end repeat

end mouseUP

T InstructionsEp5 on mouseUP show field "instructions" end mouseUP fm cREVGeneral scriptChecksum&M@XV?8*Hg Q handlerListmouseUP breakPoints47scriptSelection char 40 to 39 revUniqueID 1109350482394 bookmarks tempScript prevHandlerchangeToReflectedVelscriptY

on mouseUP

show field "instructions"

end mouseUP

UField 1)Df cREVGeneral revUniqueID 1109350482395 : Clean drawing VField 1)f cREVGeneral revUniqueID 1109350482396 : Draw or not WField 1)Jf cREVGeneral revUniqueID 1109350482397 : SpeedXSpeedia  80100 cREVGeneral bookmarks revUniqueID 1109350779771 handlerListscriptSelection char 1 to 0 prevHandler tempScriptscriptYv@KFW\> cREVGeneral revUniqueID 1109350779772 bookmarks handlerList tempScript prevHandlerscriptSelection char 1 to 0script ZField 1)\f cREVGeneral revUniqueID 1109350779773 N Speed[ Pen downEplocal vx,vy on mouseUP if "down" is in the short name of me then set the penState of grc "Ball" to false set the name of me to "Pen up" else set the penState of grc "Ball" to true set the name of me to "Pen down" end if end mouseUP fk cREVGeneral scriptChecksum/^T*vS%i handlerListmouseUP breakPoints47scriptSelectionchar 175 to 174 revUniqueID 1109350779774 bookmarks tempScript prevHandlerchangeToReflectedVelscript

local vx,vy

on mouseUP

if "down" is in the short name of me then

set the penState of grc "Ball" to false

set the name of me to "Pen up"

else

set the penState of grc "Ball" to true

set the name of me to "Pen down"

end if

end mouseUP

\Field 1)V cREVGeneral revUniqueID 1109350779775 N Draw or not]CleanEp] on mouseUP repeat until the number of images is 0 delete image 1 end repeat end mouseUP DZm cREVGeneral scriptChecksum7֦2ӯ`a¡~ breakPoints47 handlerListmouseUPscriptSelection char 69 to 68 bookmarks revUniqueID 1109350779776 prevHandlerchangeToReflectedVel tempScriptscript

on mouseUP

repeat until the number of images is 0

delete image 1

end repeat

end mouseUP

^Field 1)Bf cREVGeneral revUniqueID 1109350779777 N Clean drawing` First cardEp*on mouseUP go to next card end mouseUP RI cREVGeneralscriptChecksum7Q]1ˋ revUniqueID 1109350779779 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 29 to 28script=

on mouseUP

go to next card

end mouseUP

a Circle6185KbSddh cREVGeneral revUniqueID 1109350793365b Circle6190K',ddh cREVGeneral revUniqueID 1109350795813c Circle6186Kmddh cREVGeneral revUniqueID 1109350797157 iField 1+, cREVGeneral revUniqueID 1109351597389 : Option drag and release  Hold the shift key  to stop the action j Circle6205Kddh cREVGeneral revUniqueID 1109351703401k Circle6209K$gddh cREVGeneral revUniqueID 1109351706087 7 Instructions!p"on mouseUP hide me end mouseUP P cREVGeneralscriptChecksumo'՝'P revUniqueID 1109284671922 bookmarks handlerListmouseUP tempScript prevHandlerscriptSelection char 21 to 20script5

on mouseUP

hide me

end mouseUP

: "(Click on this field to hide it.) @! @ How to set the action: @  @ QDrag the blue ball (hereafter referred to as the cue ball) to any position and release. Next shift-drag on the cue ball to determine the direction on the initial velocity of the cue ball. (This determines only the direction. The speed is controlled by the slider. Drag as far as you like; the effect is the same for a given direction.) @P @ OVERY IMPORTANT: Be sure to release the mouse before you release the shift key. @N @ `To stop the action, hold the OPTION key (not the shift key as before) UNTIL THE NEXT COLLISION. @_ @ What you should see: @  @ The cue ball should "bounce" off of the red (target) balls and the walls. (The purpose of the larger, transparent circles is to define the effective cross-section for the collision. The radius of this circle is the radius of the target ball + the radius of the cue ball. In performing all the calculations, it is easiest to imagine the cue ball to be a point object and the targets amplified by the size of the blue ball. This applies to the walls as well as the targets. To see this effect, turn on the drawing mode--use the pen down mode. You will see a tracing of the CENTER of the blue ball. This tracing remains outside the cross-section circles, and, of course, the walls as well.) @ @ The tracing is prescient; it precedes the advance of the cue ball. This is easy to change. Just move the "drag" command in the cue ball script to a position after the "drag" command. @ @ @ How does it work? @  @ Rather than move the cue (blue) ball incrementally and then test whether it is within collision distance of the targets (red balls or one of the four walls) the cue ball examines its future trajectory and determines which target it would intersect first and then computes the point of intersection. It then moves to this point (using the RunRev "move" command for smoother motion and fewer display problems in OS X). The move in completed in a time equal to the distance to the intersection divided by the fixed velocity--distance divided by velocity is time. In this way, the speed of the cue ball is constant throughout the motion independant of the distance between targets. @ @ When it arrives at the target it calculates the angle for specular reflection (equal angles of incidence and reflection). It then heads the cue ball in this direction ready for the next cycle. This sequence is iterated until the handler (doMove) is stopped with the Option key. @ @ The disadvantage of this method is that it is complex. The advantage is the level of precision and the smooth motion. If one uses incremental motions (move forward in small steps proportional to the velocity and pollling the targets), the problem is that the cue ball must advance to a point INSIDE the target. The distance of intrusion will be somewhere between 0 and V, the length of the velocity step. @ @ 4The need for precision depends on the use. For just banging around, use the step method. But if one wanted to play bumper pool, the trajectory is very sensitive to the point of intersection (see practice chalenge on the next card) and this method of predestination (to put it in biblical terms) is better. @3 @ RI will not brag about this interface. Hopefully, you will discover a better way. @Q @ FScripts can be found in the cue ball, the target balls, and the card. @E; `NballK\)Slocal x,y,vx,vy,v,penDown,r,tTargetList,tVelVector,tBndryLines,tSpeed,tStartLoc,myName local tCorners,W,H on mouseDown put the loc of grc "ball" into tLoc --put the loc of me into tEnd if there is no grc "v" then set the style of the templateGraphic to "line" create grc "v" end if if the optionkey is not down then grab me else put the name of me into myName end mouseDown on mouseUP -- Ignore these first few lines. They were used to set --the walls as a custom property. put the width me /2 into r put "" into tBndryLines put the width of this stack into W put the height of this stack into H put r,r,W-r,r & return after tBndryLines put W-r,r,W-r,H-r & return after tBndryLines put r,r,r,H-r & return after tBndryLines put r,H-r,W-r,H-r after tBndryLines --set the innerBoundary of this card to tBndryLines --put r,r&cr&W-r,r&cr&W-r,H-r&cr&r,H-r into tCorners put "" into myName --set the points of grc "v" to "" if the optionkey is down then doInit end mouseUP on mouseLeave mouseUP end mouseLeave on mouseMove u,v if myName is empty then exit mouseMOve doInit end if set the points of grc "v" to the loc of grc "ball" & cr& u,v end mouseMove on doInit put "" into myName --Delete the tracing repeat until the number of images is 0 delete image 1 end repeat put the thumbposition of scrollbar "speed" into tSpeed put the endValue of scrollbar "speed" - tSpeed into tSpeed --To draw or not to draw; that is the question. put the penState of me into pendown --The pencil tool is faster if penDown then choose the pencil tool --The radius of the cue ball is r. put the width of me /2 into r put the loc of me into tLoc put item 1 of tLoc into x put item 2 of tLoc into y --Get the components of the initial velocity from the --drawn out velocity line. --Use a constant v. Control the speed with the slider. put 5 into v put the points of grc "v" into tPoints --Hide the velocity line. set the points of grc "v" to "" put item 1 of line 2 of tPoints - item 1 of line 1 of tPoints into dx put item 2 of Line 2 of tPoints - item 2 of line 1 of tPoints into dy put atan2(dy,dx) into vAngle --put 180/pi*vAngle into vDegrees put v*cos(vANgle) into vx put v*sin(vAngle) into vy put "" into tTargetList repeat with i = 1 to the number of graphics put the name of grc i into tName if "Oval" is in the style of grc tName then if "Ball" is not in tName then if the opaque of grc tName is true then put the loc of grc i & comma & (the width of grc i)/2 & return after tTargetList end if end if end if end repeat --Start the iterated loop doMove end doInit on doMove put x,y,x+vx,y+vy into tVelVector put x,y into tBackEndOfVelVector put x,y into tLoc put x+vx,y+vy into tFrontEndOfVelVector --Check the target balls repeat for each line tLine in tTargetList --put theDist(item 1 of tLine,tVelVector) into s put item 1 to 2 of tLine into tTargetLoc put item 3 of tLine into tTargetRadius put PerpDist(tTargetLoc, tVelVector) into tImpactRadius if tImpactRadius < tTargetRadius +r then put theCollPt(tLine) into tCollLoc put theDist(tCollLoc,tLoc) into s put theDist(tBackEndOfVelVector,tTargetLoc) into sBI put theDist(tFrontEndOfVelVector,tTargetLoc) into sFI if sBI > sFI then --Get the radial line from the target to the cue ball. put tTargetLoc,tCollLoc into tRadialLine put tCollLoc & cr & tRadialLine& comma &pi/2 into tCollArray[s] put s & comma after tDistances end if end if end repeat --Now check the walls. if tDistances is empty then repeat for each line tLine in tBndryLines put intersection(tLine,tVelVector) into tIntersectionPt put theDist(tIntersectionPt,tBackEndOfVelVector) into sBI put theDist(tIntersectionPt,tFrontEndOfVelVector) into sFI put theDist(tFrontEndOfVelVector,tBackEndOfVelVector) into sV --Either the intersection point is in front of the velocity vector --or between the ends of the velocity vector. if sFI 1 then choose the browse tool exit to top else put asin(sinGamma) into gamma put pi - gamma into gamma put 180/pi*gamma into tempGamma if beta > pi/2 then put pi-alpha-gamma into beta put 180/pi*beta into tempBeta --put pi - beta into beta put 180/pi*beta into tempBeta put a*sin(beta)/sin(alpha) into b put b*vx/v into dBx put b*vy/v into dBy put the loc of me into tLoc put item 1 of tLoc into x put item 2 of tLoc into y put x+dBx,y+dBy into tCollLoc return tCollLoc end theCollPt function theNextTarget xx,yy --Examine the extended velocity line and --determine which target is first intersected. put xx,yy into tLoc --First the the end points of the velocity line. put item 1 to 2 of tVelVector into tBackOfVelVector put item 3 to 4 of tVelVector into tFrontOfVelVector --First look at the balls (red) only. --Do this by droping a perpendicular line from --each red ball onto the (extended) velociity line. --The nearest of these intersection points is the next target ball.) repeat for each line tLine in tTargetList put item 1 to 2 of tLine into tTargetPt put perpDist(tTargetPt,tVelVector) into d if d < (r + item 3 of tLine) then --Check to see if the target is in front of the cue ball --and not behind. Ignore if behind. if theDist(tFrontOfVelVector,tTargetPt)< theDist(tBackOfVelVector,tTargetPt) then put tLine & return after tTargets put theDist(tLoc,tTargetPt) & comma after tDistances end if end if end repeat if tDistances is not empty then --Get the minimum distance. put min(tDistances) into tMin put itemOffset(tMin,tDistances) into tTargetNum put line tTargetNum of tTargets into tTarget --If there is no target ball AHEAD of the cue ball then --look at the walls, boundary lines. else --Boundary intersection points. --put the innerBoundary of this card into tBndryLines repeat for each line tLine in tBndryLines put intersection(tVelVector,tLine) & return after tBndryPtList end repeat --Get the minimum target wall in FRONT of the cue ball's path. put "" into tDistances repeat for each line tPt in tBndryPtList put theDist(tLoc,tPt) & cr after tDistances end repeat put 10000 into tMin repeat with i = 1 to the number of lines in tDistances put line i of tDistances into tDist put line i of tBndryPtList into tTargetPt if tDist < tMin then if theDist(tFrontOfVelVector,tTargetPt)\ < theDist(tBackOfVelVector,tTargetPt) then put i into tMinNum put tDist into tMin end if end if end repeat put line tMinNum of tBndryLines into tTarget end if return tTarget end theNextTarget function theDist p1,p2 --Square root of the sum of the squares. put item 1 of p1 - item 1 of p2 into dx put item 2 of p1 - item 2 of p2 into dy return sqrt(dx*dx+dy*dy) end theDist function theLineAngle p1,p2 --Angle of line defined by the two points p1 and p2 put item 1 of p2 - item 1 of p1 into dx put item 2 of p2 - item 2 of p1 into dy put atan2(dy,dx) into tAngle return tAngle end theLineAngle function theNewVel tLine --This is a generic fuction which determines the --spectral angle of reflection; work for collisions with both --target ball or walls. put item 1 to 2 of tLine into p1 put item 3 to 4 of tLine into p2 put item 5 of tLine into tAddedAngle put item 2 of p2 - item 2 of p1 into dy put item 1 of p2 - item 1 of p1 into dx --Angle of the line being intersected. --This line could be a wall or --a line tangent to a target ball at the --the point of impact. That tangent line --will be perpendicular to the radial line. --Thus add 90 degrees to the radial line. put aTan2(dy,dx) into angleL put aTan2(vy,vx) into angleV add tAddedAngle to angleL put v * cos(2*angleL-angleV) into tVx--A little geometry here. put v * sin (2*angleL - angleV) into tVy--And here. return tVx,tVy end theNewVel function theRound tLine --Utility function to round the two --items in a line. put round(item 1 of tLine) into item 1 of tLine put round(item 2 of tLine) into item 2 of tLine return tLine end theRound c((pendowntrue startLoc155,86 penStatetrueh cREVGeneral scriptChecksum ]C+ĚT* breakPoints107 126 135 152 248 250 handlerListtmouseDown mouseUP mouseLeave mouseMove doInit doMove theCollPt theNextTarget theDist theLineAngle theNewVel theRoundscriptSelectionchar 5141 to 5140 bookmarks revUniqueID 1109437899599 prevHandlerdoMove tempScriptscript5^

local x,y,vx,vy,v,penDown,r,tTargetList,tVelVector,tBndryLines,tSpeed,tStartLoc,myName

local tCorners,W,H

on mouseDown

put the loc of grc "ball" into tLoc

--put the loc of me into tEnd

if there is no grc "v" then

set the style of the templateGraphic to "line"

create grc "v"

end if

if the optionkey is not down then

grab me

else put the name of me into myName

end mouseDown

on mouseUP

-- Ignore these first few lines. They were used to set

--the walls as a custom property.

put the width me /2 into r

put "" into tBndryLines

put the width of this stack into W

put the height of this stack into H

put r,r,W-r,r & return after tBndryLines

put W-r,r,W-r,H-r & return after tBndryLines

put r,r,r,H-r & return after tBndryLines

put r,H-r,W-r,H-r after tBndryLines

--set the innerBoundary of this card to tBndryLines

--put r,r&cr&W-r,r&cr&W-r,H-r&cr&r,H-r into tCorners

put "" into myName

--set the points of grc "v" to ""

if the optionkey is down then doInit

end mouseUP

on mouseLeave

mouseUP

end mouseLeave

on mouseMove u,v

if myName is empty then

exit mouseMOve

doInit

end if

set the points of grc "v" to the loc of grc "ball" & cr& u,v

end mouseMove

on doInit

put "" into myName

--Delete the tracing

repeat until the number of images is 0

delete image 1

end repeat

put the thumbposition of scrollbar "speed" into tSpeed

put the endValue of scrollbar "speed" - tSpeed into tSpeed

--To draw or not to draw; that is the question.

put the penState of me into pendown

--The pencil tool is faster

if penDown then choose the pencil tool

--The radius of the cue ball is r.

put the width of me /2 into r

put the loc of me into tLoc

put item 1 of tLoc into x

put item 2 of tLoc into y

--Get the components of the initial velocity from the

--drawn out velocity line.

--Use a constant v. Control the speed with the slider.

put 5 into v

put the points of grc "v" into tPoints

--Hide the velocity line.

set the points of grc "v" to ""

put item 1 of line 2 of tPoints - item 1 of line 1 of tPoints into dx

put item 2 of Line 2 of tPoints - item 2 of line 1 of tPoints into dy

put atan2(dy,dx) into vAngle

--put 180/pi*vAngle into vDegrees

put v*cos(vANgle) into vx

put v*sin(vAngle) into vy

put "" into tTargetList

repeat with i = 1 to the number of graphics

put the name of grc i into tName

if "Oval" is in the style of grc tName then

if "Ball" is not in tName then

if the opaque of grc tName is true then

put the loc of grc i & comma & (the width of grc i)/2 & return after tTargetList

end if

end if

end if

end repeat

--Start the iterated loop

doMove

end doInit

on doMove

put x,y,x+vx,y+vy into tVelVector

put x,y into tBackEndOfVelVector

put x,y into tLoc

put x+vx,y+vy into tFrontEndOfVelVector

--Check the target balls

repeat for each line tLine in tTargetList

--put theDist(item 1 of tLine,tVelVector) into s

put item 1 to 2 of tLine into tTargetLoc

put item 3 of tLine into tTargetRadius

put PerpDist(tTargetLoc, tVelVector) into tImpactRadius

if tImpactRadius < tTargetRadius +r then

put theCollPt(tLine) into tCollLoc

put theDist(tCollLoc,tLoc) into s

put theDist(tBackEndOfVelVector,tTargetLoc) into sBI

put theDist(tFrontEndOfVelVector,tTargetLoc) into sFI

if sBI > sFI then

--Get the radial line from the target to the cue ball.

put tTargetLoc,tCollLoc into tRadialLine

put tCollLoc & cr & tRadialLine& comma &pi/2 into tCollArray[s]

put s & comma after tDistances

end if

end if

end repeat

--Now check the walls.

if tDistances is empty then

repeat for each line tLine in tBndryLines

put intersection(tLine,tVelVector) into tIntersectionPt

put theDist(tIntersectionPt,tBackEndOfVelVector) into sBI

put theDist(tIntersectionPt,tFrontEndOfVelVector) into sFI

put theDist(tFrontEndOfVelVector,tBackEndOfVelVector) into sV

--Either the intersection point is in front of the velocity vector

--or between the ends of the velocity vector.

if sFI<sBI or (sBI<sV and sFI<sV) then

put sBI into s

if s is not 0 then put tIntersectionPt& cr& tLine into tCollArray[s]

put s & comma after tDistances

end if

end repeat

end if

--Get the closest collision point.

put min(tDistances) into tMin

put tCollArray[tMin] into temp

put line 1 of temp into tCollLoc

put line 2 of temp into tTargetLine

if penDown then

drag from x,y to tCollLoc

end if

--At long last, do the move.

--I was worried about the time to execute these

--calculations above, but Run Rev came through

--like a champ.

--The move time is set to keep the speed constant,

--independent from the distance between collisions.

put theDist(tLoc,tCollLoc) into s

move me to theRound(tCollLoc) in s/v*tSpeed millisec

if the loc of me is within the rect of button "pocket" then

put "Success" into msg box

choose the browse tool

exit to top

end if

put item 1 of tCollLoc into x

put item 2 of tCollLoc into y

--Beeping works well in OS X, but not in Windows of OS 9.

if char 1 to 2 of the systemVersion is 10 then beep

--Now set the velocity for the next collion.

put theNewVel(tTargetLine)into tNewVel

put item 1 of tNewVel into vx

put item 2 of tNewVel into vy

if the shiftkey is down then

choose the browse tool

exit to top

end if

send "doMove" to me in 1 millisec

end doMove

function theCollPt tTarget

--This function determines where the cue ball

--will intersect the (expanded) target ball

--of radius r + a.

--Lots of geometry involved here.

put r+item 3 of tTarget into a

put theLineAngle(item 1 to 2 of tVelVector,item 3 to 4 of tVelVector) into angleV

put 180/pi*angleV into tempV

put item 1 to 2 of tTarget into tTargetLoc

put theLineAngle(the loc of me,tTargetLoc ) into angleC

put 180/pi*angleC into tempC

put angleV - angleC into alpha

if alpha is 0 then add .0001 to alpha

put theDist(the loc of me,tTargetLoc) into c

put c*sin(alpha)/a into sinGamma

if abs(sinGamma) > 1 then

choose the browse tool

exit to top

else put asin(sinGamma) into gamma

put pi - gamma into gamma

put 180/pi*gamma into tempGamma

if beta > pi/2 then put pi-alpha-gamma into beta

put 180/pi*beta into tempBeta

--put pi - beta into beta

put 180/pi*beta into tempBeta

put a*sin(beta)/sin(alpha) into b

put b*vx/v into dBx

put b*vy/v into dBy

put the loc of me into tLoc

put item 1 of tLoc into x

put item 2 of tLoc into y

put x+dBx,y+dBy into tCollLoc

return tCollLoc

end theCollPt

function theNextTarget xx,yy

--Examine the extended velocity line and

--determine which target is first intersected.

put xx,yy into tLoc

--First the the end points of the velocity line.

put item 1 to 2 of tVelVector into tBackOfVelVector

put item 3 to 4 of tVelVector into tFrontOfVelVector

--First look at the balls (red) only.

--Do this by droping a perpendicular line from

--each red ball onto the (extended) velociity line.

--The nearest of these intersection points is the next target ball.)

repeat for each line tLine in tTargetList

put item 1 to 2 of tLine into tTargetPt

put perpDist(tTargetPt,tVelVector) into d

if d < (r + item 3 of tLine) then

--Check to see if the target is in front of the cue ball

--and not behind. Ignore if behind.

if theDist(tFrontOfVelVector,tTargetPt)< theDist(tBackOfVelVector,tTargetPt) then

put tLine & return after tTargets

put theDist(tLoc,tTargetPt) & comma after tDistances

end if

end if

end repeat

if tDistances is not empty then

--Get the minimum distance.

put min(tDistances) into tMin

put itemOffset(tMin,tDistances) into tTargetNum

put line tTargetNum of tTargets into tTarget

--If there is no target ball AHEAD of the cue ball then

--look at the walls, boundary lines.

else

--Boundary intersection points.

--put the innerBoundary of this card into tBndryLines

repeat for each line tLine in tBndryLines

put intersection(tVelVector,tLine) & return after tBndryPtList

end repeat

--Get the minimum target wall in FRONT of the cue ball's path.

put "" into tDistances

repeat for each line tPt in tBndryPtList

put theDist(tLoc,tPt) & cr after tDistances

end repeat

put 10000 into tMin

repeat with i = 1 to the number of lines in tDistances

put line i of tDistances into tDist

put line i of tBndryPtList into tTargetPt

if tDist < tMin then

if theDist(tFrontOfVelVector,tTargetPt)\

< theDist(tBackOfVelVector,tTargetPt) then

put i into tMinNum

put tDist into tMin

end if

end if

end repeat

put line tMinNum of tBndryLines into tTarget

end if

return tTarget

end theNextTarget

function theDist p1,p2

--Square root of the sum of the squares.

put item 1 of p1 - item 1 of p2 into dx

put item 2 of p1 - item 2 of p2 into dy

return sqrt(dx*dx+dy*dy)

end theDist

function theLineAngle p1,p2

--Angle of line defined by the two points p1 and p2

put item 1 of p2 - item 1 of p1 into dx

put item 2 of p2 - item 2 of p1 into dy

put atan2(dy,dx) into tAngle

return tAngle

end theLineAngle

function theNewVel tLine

--This is a generic fuction which determines the

--spectral angle of reflection; work for collisions with both

--target ball or walls.

put item 1 to 2 of tLine into p1

put item 3 to 4 of tLine into p2

put item 5 of tLine into tAddedAngle

put item 2 of p2 - item 2 of p1 into dy

put item 1 of p2 - item 1 of p1 into dx

--Angle of the line being intersected.

--This line could be a wall or

--a line tangent to a target ball at the

--the point of impact. That tangent line

--will be perpendicular to the radial line.

--Thus add 90 degrees to the radial line.

put aTan2(dy,dx) into angleL

put aTan2(vy,vx) into angleV

add tAddedAngle to angleL

put v * cos(2*angleL-angleV) into tVx--A little geometry here.

put v * sin (2*angleL - angleV) into tVy--And here.

return tVx,tVy

end theNewVel

function theRound tLine

--Utility function to round the two

--items in a line.

put round(item 1 of tLine) into item 1 of tLine

put round(item 2 of tLine) into item 2 of tLine

return tLine

end theRound

7 Reset ballEp?on mouseUP set the loc of grc "ball" to 200,200 end mouseUP f cREVGeneral scriptChecksum}o52ȝt;( breakPoints47 handlerListmouseUPscriptSelection char 50 to 49 bookmarks revUniqueID 1109530155673 prevHandlerchangeToReflectedVel tempScriptscript\

on mouseUP

set the loc of grc "ball" to 200,200

end mouseUP

e DPNG  IHDRQ:LgAMA=-fPLTEٟtRNS0JIDATxұ 0iv22}AfL؍x*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR JAk)UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UPTAR J*(UP UUlxvIENDB` cREVGeneral revUniqueID 1109696953464