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 110834370561957301108342523075572811084241659445747110842415071157461109349981985617711083426332215729110834086646757271108343966445573111078703210971003cREVGeometrycacheordertotal9cREVGeneralscriptChecksumh)ژ@ح\@ bookmarkshandlerListbreakPointstempScriptprevHandlerperpDistscriptSelectionchar 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 cREVGeometryCacheIDs1108343705619573611083950067105744110851149227258031109350108503617811083426332215735110850687477057681108343966445573711084985361555755110834252307557341108498536156575611084983073865754110843005869657481107870321097573211083408664675733cREVGeometryCacheordertotal14cREVGeneralscriptChecksum*ˎ$)R饍 bookmarksbreakPointshandlerListthePolyLines perpDistscriptSelection char 1 to 256prevHandlerthePolyLinestempScriptscriptfunction 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 cREVGeometryCacheIDs110834370561960361108395006710603811085114922726043110834396644560371108506874770604211084985361556040110935011524161791108498536156604111088990148816044110849830738660461108942517596609711084300586966039110787032109760451108942420955609511083426332216035110834252307560341108942503466609611083408664676033cREVGeometryCachetotal18ordercREVGeneralscriptChecksum*ˎ$)R饍 bookmarkshandlerListthePolyLines perpDistbreakPointstempScriptprevHandlerthePolyLinesscriptSelection char 1 to 256scriptfunction 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 d1put 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 110867926750658681108511492272585711087035660605873110843005869658541109350126647618111086765534345865110859777103458581107870321097585011086775044295866cREVGeometryCacheordertotal9cREVGeneralscriptChecksuml?c%Eput 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 d1function 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,533cREVGeometryCacheIDs1109350482393622711093504823946228110935048239562291109350482396623011093504823976231110935043756962241109033759789618511092843133416195110928461576161981109284671922619911090337708056200110928440462561971109284290642619411093432155956201110928432580861961109350795813624211093515973896249110911286360061871109109886658618611093507971576243110911516160361891109350793365624111095301556736455110935048239162251109282519719619011093504823926226cREVGeometrycacheordertotal26cREVGeneralscriptChecksumm:*z bookmarkshandlerListclean perpDist intersectionbreakPointsscriptSelectionchar 463 to 462prevHandler theNewVeltempScriptscriptjon 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,533cREVGeometryCacheIDs110955488096064941109350779779624011094378995996295110928952623562041109033759789620511092843133416211110928461576162141109343305467622011092883732566218110928429064262101109351706087625111092843258086212110935077977162321109350779772623311093507797736234110935170340162501109350779774623511093507797756236110935077977662371109350779777623811092825197196209cREVGeometrycacheordertotal21cREVGeneralscriptChecksumDpcuݹ bookmarkshandlerListclean perpDist intersectiontempScriptprevHandler theNewVelscriptSelectionchar 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 7040cREVGeneralrevUniqueID 1108340866467 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 1 to 0script `Field 1)}2cREVGeneralrevUniqueID 1108342523075Speed aField 1+QcREVGeneralrevUniqueID 11083426332219Drag 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 550cREVGeneralscriptChecksumba닋N'OHP bookmarksrevUniqueID 1108343705619handlerList scrollbardragscriptSelectionchar 103 to 102prevHandler scrollbardragtempScriptscript?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)52cREVGeneralrevUniqueID 1108343966445Flexespeedia T240cREVGeneral bookmarksrevUniqueID 1108340866467handlerListscriptSelectionchar 1 to 0prevHandlertempScriptscript fField 1)D2cREVGeneralrevUniqueID 1108342523075jSpeed gField 1+ HcREVGeneralrevUniqueID 1108342633221j+Confine a ball within any concave polygon. *hflexia0 24.908904cREVGeneralrevUniqueID 1108343705619 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 1 to 0script iField 1)F2cREVGeneralrevUniqueID 1108343966445jFlexpmyLineKblackpoitns 272.445501,144.300445!cREVGeneral bookmarksrevUniqueID 1108395006710handlerListscriptSelectionchar 1 to 0prevHandlertempScriptscriptrflexia 050cREVGeneralrevUniqueID 1108424150711 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 1 to 0script s)JcREVGeneralrevUniqueID 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 EcREVGeneral scriptChecksumeF a+]h:breakPoints10handlerListmouseUPscriptSelectionchar 318 to 317 bookmarksrevUniqueID 1108430058696prevHandler mouseMovetempScriptscript-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 ǂS550cREVGeneralscriptChecksumba닋N'OHP bookmarksrevUniqueID 1108498536155handlerList scrollbardragscriptSelectionchar 103 to 102prevHandler scrollbardragtempScriptscript?on scrollbardrag tValue

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

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

end scrollbardrag

|)JcREVGeneralrevUniqueID 1108498536156j 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 bookmarksrevUniqueID 1108506874770handlerListmouseUPscriptSelectionchar 231 to 230prevHandlertempScriptscriptcon 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)` 2cREVGeneralrevUniqueID 1108511492272jWhat 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. `3ballKTQlocal 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--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

speedia7240cREVGeneralrevUniqueID 1108340866467 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 1 to 0script Field 1)F2cREVGeneralrevUniqueID 1108342523075Speed Field 1)jcREVGeneralrevUniqueID 1108342633221Shift 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:handlerListmouseUPbreakPoints10scriptSelectionchar 318 to 317revUniqueID 1108430058696 bookmarkstempScriptprevHandler 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 550cREVGeneralscriptChecksumba닋N'OHPrevUniqueID 1108498536155 bookmarkshandlerList scrollbardragtempScriptprevHandler 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

)JcREVGeneralrevUniqueID 1108498536156 Diameter Instructions)`(cREVGeneralrevUniqueID 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)`$=cREVGeneralrevUniqueID 11086551824960,3 +i!cREVGeneralrevUniqueID 1108674937012Starting velocitycomponentsReset 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 gcREVGeneral scriptChecksumh?4ߵװbreakPoints10handlerListmouseUPscriptSelectionchar 123 to 122 bookmarksrevUniqueID 1108430058696prevHandlermouseUPtempScriptscript)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)hcREVGeneralrevUniqueID 1108511492272How 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) thenQwhere 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 0cREVGeneralscriptChecksum{zSQl bookmarksrevUniqueID 1108597771034handlerList mouseDownscriptSelection char 23 to 22prevHandlertempScriptscript9on mouseDown

grab me

end mouseDown

projLineKV&on mouseDown grab me end mouseDown #$6$XcREVGeneralscriptChecksum{zSQlrevUniqueID 1108676553434 bookmarkshandlerList mouseDowntempScriptprevHandlerscriptSelection char 23 to 22script9on mouseDown

grab me

end mouseDown

data*cb&cREVGeneralrevUniqueID 1108677504429Between end pointsballKTlocal 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 penStatetruehcREVGeneral scriptChecksum3ZP³W=/:handlerListmouseDown mouseUP mouseMovebreakPoints17 63scriptSelectionchar 140 to 139revUniqueID 1107870321097 bookmarkstempScriptprevHandlerProjPointLiesWithinEndPtsscriptlocal 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&cREVGeneralrevUniqueID 1108679267506 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 1 to 0scriptDistance to line is 62ReturnEp.on mouseUP go to previous card end mouseUP NAcREVGeneralscriptChecksum~aȣzg,revUniqueID 1108703566060 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection char 33 to 32scriptAon mouseUP

go to previous card

end mouseUP

dballKTplocal 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 penStatefalsehcREVGeneral scriptChecksumD^,uth":handlerListDmouseUP moveBall changeToReflectedVel setDiameter perpDist mouseDownbreakPoints35 102scriptSelectionchar 847 to 846revUniqueID 1107870321097 bookmarkstempScriptprevHandlermoveBallscript2local 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^^+;+uWcREVGeneral bookmarksrevUniqueID 1108498307386handlerListscriptSelectionchar 1 to 0prevHandlertempScriptscriptspeedia 240cREVGeneralrevUniqueID 1108340866467 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 1 to 0script Field 1)D2cREVGeneralrevUniqueID 1108342523075Speed Field 1)jcREVGeneralrevUniqueID 1108342633221Shift key to stopflexia 7.953672cREVGeneral bookmarksrevUniqueID 1108343705619handlerListscriptSelectionchar 1 to 0prevHandlertempScriptscript Field 1)F2cREVGeneralrevUniqueID 1108343966445FlexmyLineKblackpoitns 272.445501,144.300445!cREVGeneralrevUniqueID 1108395006710 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 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:handlerListmouseUPbreakPoints10scriptSelectionchar 318 to 317revUniqueID 1108430058696 bookmarkstempScriptprevHandler 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 '550cREVGeneralscriptChecksumba닋N'OHPrevUniqueID 1108498536155 bookmarkshandlerList scrollbardragtempScriptprevHandler 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

)JcREVGeneralrevUniqueID 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մ߽P7SrevUniqueID 1108506874770 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelectionchar 231 to 230scriptcon 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)`HpcREVGeneralrevUniqueID 1108511492272uIn 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<$!^`,<,\^cREVGeneralrevUniqueID 1108899014881myPolyK black:)'!+__+<++cREVGeneralrevUniqueID 1108498307386 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 1 to 0scriptmyPolyK blackN! zSggP cREVGeneralrevUniqueID 1108928443754 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 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 bookmarksrevUniqueID 1108932040072handlerListmouseUPscriptSelectionchar 231 to 230prevHandlermouseUPtempScriptscriptcon 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)\+<cREVGeneralrevUniqueID 1108942420955II Field 1)66cREVGeneralrevUniqueID 1108942503466III Field 1)2=cREVGeneralrevUniqueID 1108942517596I ballKTlocal 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 penStatefalsehcREVGeneral scriptChecksumiV2S!breakPoints7handlerListDmouseUP moveBall changeToReflectedVel setDiameter perpDist mouseDownscriptSelectionchar 345 to 344 bookmarksrevUniqueID 1107870321097prevHandlerchangeToReflectedVeltempScriptscriptlocal 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,479vx32525vy1hcREVGeneral scriptChecksumEف.Q|}V}%F{,breakPoints51 72handlerList1mouseDown mouseUP moveBall setDiameter HorizontalscriptSelectionchar 742 to 741 bookmarksrevUniqueID 1107870321097prevHandler HorizontaltempScriptscript'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 p240cREVGeneralrevUniqueID 1108340866467 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 1 to 0script Field 1)D2cREVGeneralrevUniqueID 1108342523075Speed Success) Tg&cREVGeneralrevUniqueID 1108342633221Reset 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 fcREVGeneral scriptChecksumeF a+]h:handlerListmouseUPbreakPoints10scriptSelectionchar 318 to 317revUniqueID 1108430058696 bookmarkstempScriptprevHandler 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 Z550cREVGeneralscriptChecksumba닋N'OHPrevUniqueID 1108498536155 bookmarkshandlerList scrollbardragtempScriptprevHandler 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)`vcREVGeneralrevUniqueID 1108511492272It 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. @852) 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 2Kblackoh!cREVGeneralrevUniqueID 1108655076163 velocity!`$=cREVGeneralrevUniqueID 1108655182496-3,0 #P$cREVGeneralrevUniqueID 1108674937012 Velocitycomponents Graphic 3KF/d40cREVGeneralrevUniqueID 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)) penStatetruehcREVGeneral scriptChecksumcQux\ԫbreakPoints53 69 77handlerList/mouseUp moveBall changeToReflectedVel mouseDownscriptSelectionchar 3788 to 4279 bookmarksrevUniqueID 1107870321097prevHandlerchangeToReflectedVeltempScriptscript)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 4KFJjsKcREVGeneralrevUniqueID 1108758072710 Graphic 3KF3}T.4~cREVGeneralrevUniqueID 1108775704639target@+a@DcREVGeneralrevUniqueID 1108993693560 StartLineKF:j<cREVGeneralrevUniqueID 1108995439960 Field 1+ HcREVGeneralrevUniqueID 1109348597700*Confine a ball within any convex polygon. )! Next cardEp*on mouseUP go to next card end mouseUP R cREVGeneralscriptChecksum7Q]1ˋrevUniqueID 1109349981985 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection char 29 to 28script=on mouseUP

go to next card

end mouseUP

" Next cardEp*on mouseUP go to next card end mouseUP RcREVGeneralscriptChecksum7Q]1ˋrevUniqueID 1109350108503 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection char 29 to 28script=on mouseUP

go to next card

end mouseUP

# Next cardEp*on mouseUP go to next card end mouseUP RcREVGeneralscriptChecksum7Q]1ˋrevUniqueID 1109350115241 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection 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 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection 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 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection char 29 to 28script=on mouseUP

go to next card

end mouseUP

& Next cardEp*on mouseUP go to next card end mouseUP |RcREVGeneralscriptChecksum7Q]1ˋrevUniqueID 1109350133151 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection 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<<hcREVGeneralscriptChecksums" bookmarksrevUniqueID 1109033759789handlerListmouseDown mouseUPscriptSelectionchar 468 to 467prevHandlermouseUtempScriptscription 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 <<hcREVGeneral scriptChecksum%TE㙟&FhandlerListmouseDown mouseUPbreakPoints6scriptSelectionchar 354 to 353revUniqueID 1109109886658 bookmarkstempScriptprevHandler 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 fcREVGeneral scriptChecksum/^T*vS%ibreakPoints47handlerListmouseUPscriptSelectionchar 175 to 174 bookmarksrevUniqueID 1109112863600prevHandlerchangeToReflectedVeltempScriptscriptlocal 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>cREVGeneralrevUniqueID 1109115161603 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 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 ;@<<hcREVGeneralscriptChecksumS@*revUniqueID 1109282519719 bookmarkshandlerListmouseDown mouseUPtempScriptprevHandlermouseUscriptSelectionchar 343 to 342scriptqon 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)<,fcREVGeneralrevUniqueID 1109284290642:Speed 3Field 1)4fcREVGeneralrevUniqueID 1109284313341:Draw or not 4Field 1)^6fcREVGeneralrevUniqueID 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¡~handlerListmouseUPbreakPoints47scriptSelection char 69 to 68revUniqueID 1109284404625 bookmarkstempScriptprevHandlerchangeToReflectedVelscripton 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 fcREVGeneral scriptChecksum&M@XV?8*Hg QbreakPoints47handlerListmouseUPscriptSelection char 40 to 39 bookmarksrevUniqueID 1109284615761prevHandlerchangeToReflectedVeltempScriptscriptYon 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 sFIlocal 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 scriptChecksumH8|@k:1handlerListmouseUPbreakPoints47scriptSelection char 28 to 27revUniqueID 1109343215595 bookmarkstempScriptprevHandlerchangeToReflectedVelscriptCon mouseUP

go to next card

end mouseUP

<Field 2)`@cREVGeneralrevUniqueID 1109289526235NDrag 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<<hcREVGeneralscriptChecksum8up5ErevUniqueID 1109033759789 bookmarkshandlerListmouseDown mouseUPtempScriptprevHandlermouseUscriptSelectionchar 3 to 2scripton 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{<<hcREVGeneralscriptChecksums" bookmarksrevUniqueID 1109282519719handlerListmouseDown mouseUPscriptSelectionchar 468 to 467prevHandlermouseUtempScriptscription 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)<,fcREVGeneralrevUniqueID 1109284290642NSpeed CField 1)4fcREVGeneralrevUniqueID 1109284313341NDraw or not DField 1)^6fcREVGeneralrevUniqueID 1109284325808NClean drawingF InstructionsEp5 on mouseUP show field "instructions" end mouseUP focREVGeneral scriptChecksum&M@XV?8*Hg QhandlerListmouseUPbreakPoints47scriptSelection char 40 to 39revUniqueID 1109284615761 bookmarkstempScriptprevHandlerchangeToReflectedVelscriptYon mouseUP

show field "instructions"

end mouseUP

JPocket`da64POCKETcREVGeneralrevUniqueID 1109288373256 NLGo backEp) on mouseUP go to next card end mouseUP 4fmcREVGeneral scriptChecksumH8|@k:1handlerListmouseUPbreakPoints47scriptSelection char 28 to 27revUniqueID 1109343305467 bookmarkstempScriptprevHandlerchangeToReflectedVelscriptCon mouseUP

go to next card

end mouseUP

P Next cardEp*on mouseUP go to next card end mouseUP RicREVGeneralscriptChecksum7Q]1ˋrevUniqueID 1109350437569 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection char 29 to 28script=on mouseUP

go to next card

end mouseUP

QSpeedia 80100cREVGeneral bookmarksrevUniqueID 1109350482391handlerListscriptSelectionchar 1 to 0prevHandlertempScriptscriptR 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 fkcREVGeneral scriptChecksumx5D؎handlerListmouseUPbreakPoints47scriptSelection char 63 to 62revUniqueID 1109350482392 bookmarkstempScriptprevHandlerchangeToReflectedVelscriptlocal 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 DZkcREVGeneral scriptChecksum7֦2ӯ`a¡~breakPoints47handlerListmouseUPscriptSelection char 69 to 68 bookmarksrevUniqueID 1109350482393prevHandlerchangeToReflectedVeltempScriptscripton 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 fmcREVGeneral scriptChecksum&M@XV?8*Hg QhandlerListmouseUPbreakPoints47scriptSelection char 40 to 39revUniqueID 1109350482394 bookmarkstempScriptprevHandlerchangeToReflectedVelscriptYon mouseUP

show field "instructions"

end mouseUP

UField 1)DfcREVGeneralrevUniqueID 1109350482395:Clean drawing VField 1)fcREVGeneralrevUniqueID 1109350482396:Draw or not WField 1)JfcREVGeneralrevUniqueID 1109350482397:SpeedXSpeedia 80100cREVGeneral bookmarksrevUniqueID 1109350779771handlerListscriptSelectionchar 1 to 0prevHandlertempScriptscriptYv@KFW\>cREVGeneralrevUniqueID 1109350779772 bookmarkshandlerListtempScriptprevHandlerscriptSelectionchar 1 to 0script ZField 1)\fcREVGeneralrevUniqueID 1109350779773NSpeed[ 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 fkcREVGeneral scriptChecksum/^T*vS%ihandlerListmouseUPbreakPoints47scriptSelectionchar 175 to 174revUniqueID 1109350779774 bookmarkstempScriptprevHandlerchangeToReflectedVelscriptlocal 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)VcREVGeneralrevUniqueID 1109350779775NDraw or not]CleanEp] on mouseUP repeat until the number of images is 0 delete image 1 end repeat end mouseUP DZmcREVGeneral scriptChecksum7֦2ӯ`a¡~breakPoints47handlerListmouseUPscriptSelection char 69 to 68 bookmarksrevUniqueID 1109350779776prevHandlerchangeToReflectedVeltempScriptscripton mouseUP

repeat until the number of images is 0

delete image 1

end repeat

end mouseUP

^Field 1)BfcREVGeneralrevUniqueID 1109350779777NClean drawing`First cardEp*on mouseUP go to next card end mouseUP RIcREVGeneralscriptChecksum7Q]1ˋrevUniqueID 1109350779779 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection char 29 to 28script=on mouseUP

go to next card

end mouseUP

aCircle6185KbSddhcREVGeneralrevUniqueID 1109350793365bCircle6190K',ddhcREVGeneralrevUniqueID 1109350795813cCircle6186KmddhcREVGeneralrevUniqueID 1109350797157 iField 1+,cREVGeneralrevUniqueID 1109351597389:Option drag and release Hold the shift key to stop the action jCircle6205KddhcREVGeneralrevUniqueID 1109351703401kCircle6209K$gddhcREVGeneralrevUniqueID 1109351706087 7 Instructions!p"on mouseUP hide me end mouseUP PcREVGeneralscriptChecksumo'՝'PrevUniqueID 1109284671922 bookmarkshandlerListmouseUPtempScriptprevHandlerscriptSelection char 21 to 20script5on 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 sFIlocal 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

7Reset ballEp?on mouseUP set the loc of grc "ball" to 200,200 end mouseUP fcREVGeneral scriptChecksum}o52ȝt;(breakPoints47handlerListmouseUPscriptSelection char 50 to 49 bookmarksrevUniqueID 1109530155673prevHandlerchangeToReflectedVeltempScriptscript\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*(UPUUlxvIENDB`cREVGeneralrevUniqueID 1109696953464