![]() dialing for behaviors code snippet | show it | return | |
-- dial behavior
-- creates a rotating needle that can sweep continuus full circles,
-- arc lengths, random movements, or move to amounts as sent from
-- other handlers
-----------------------------------------------------------------
-- alan <alan.levine@domail.maricopa.edu>
-- assumes quadrant states of
-- v
-- |
-- 2 | 1 > 0 degrees is the positive h axis
-- --------- h > angles are positive in the counter
-- 3 | 4 clockwise direction
-- | > v axis is positive upward
-----------------------------------------------------------------
property myOriginLoc, myOrigin, myVertex, myTheta, myRadius, myMode, ¬
myMin, myMax, myDelay, myClock, myDirection, myIncrement, myTrails, ¬
myState, theRadtoDeg
-- myOriginLoc : symbol param for which corner of the
-- starting sprte is the axis of rotation;
-- [#topLeft,#bottomRight,#topRight,#bottomLeft]
-- myOrigin : point location of the origin
-- myVertex : point location of the end of the needle
-- myTheta : angle of rotation measured counter
-- colckwise from positive h axis
-- myRadius : radius of circle of rotation
-- myMode : symbol representing the type of dial
-- [#arcSweep,#fullSweep,#randomSweep,#externalTrigger]
-- myMin : starting angle location for arcSweep or range for
-- randomSweep
-- myMax : ending angle location for arcSweep or range for
-- randomSweep
-- myDelay : number of ticks between updates
-- myClock : runing time in ticks since last update
-- myDirection : clockwise or counter-clockwise
-- myIncrement : number of degrees to move between updates
-- myTrails : boolean flag for drawing with trails
-- myState : flag to indicate whether we have finished for an arc
-- theRadtoDeg : constant for converting between radians and degrees
-----------------------------------------------------------------
on beginSprite me
-- initialize the constant for angle conversion
set theRadToDeg = 180.0 / pi()
-- initialize state to active
set myState = #go
-- initialize clock
set myClock = the ticks
-- set increment to negative for clockwise sweeps
if myDirection = "Clockwise" then set myIncrement = - myIncrement
-- initialize trails state
set the trails of sprite the spriteNum of me = myTrails
-- find the vertex and the points according to the initial sprite and
-- flag sent from BH dialog box
if myOriginLoc = #topLeft then
-- sprite with origin at top left of rect ( member "line24" in quadrant 4)
set myOrigin = point( getAt( the rect of sprite the spriteNum of me,1),¬
getAt( the rect of sprite the spriteNum of me,2) )
set myVertex = point( getAt( the rect of sprite the spriteNum of me,3),¬
getAt( the rect of sprite the spriteNum of me,4) )
else if myOriginLoc = #bottomRight then
-- sprite with origin at bottom right of rect ( member "line24" in quadrant 2)
set myOrigin = point( getAt( the rect of sprite the spriteNum of me,3),¬
getAt( the rect of sprite the spriteNum of me,4) )
set myVertex = point( getAt( the rect of sprite the spriteNum of me,1),¬
getAt( the rect of sprite the spriteNum of me,2) )
else if myOriginLoc = #topRight then
-- sprite with origin at top right of rect ( member "line13" in quadrant 3)
set myOrigin = point( getAt( the rect of sprite the spriteNum of me,3),¬
getAt( the rect of sprite the spriteNum of me,2) )
set myVertex = point( getAt( the rect of sprite the spriteNum of me,1),¬
getAt( the rect of sprite the spriteNum of me,4) )
else
-- sprite with origin at bottom left of rect ( member "line13" in quadrant 1)
set myOrigin = point( getAt( the rect of sprite the spriteNum of me,1),¬
getAt( the rect of sprite the spriteNum of me,4) )
set myVertex = point( getAt( the rect of sprite the spriteNum of me,3),¬
getAt( the rect of sprite the spriteNum of me,2) )
end if
-- determine the initial angle of the vertex
if the locV of myOrigin = the locV of myVertex then
-- case where the line is horizontal
if the locH of myOrigin > the locH of myVertex then
set myTheta = 0
else
set myTheta = 180
end if
set myRadius = abs( the locH of myOrigin - the locH of myVertex )
else if the locH of myOrigin = the locH of myVertex then
-- case where the line is vertical
if the locV of myOrigin > the locV of myVertex then
set myTheta = 270
else
set myTheta = 90
end if
set myRadius = abs( the locV of myOrigin - the locV of myVertex )
else
-- all other cases, need to determine angle with arctangent
set myTheta = theRadToDeg * atan ( 1.0 * (the locV of myOrigin - ¬
the locV of myVertex) / (the locH of myVertex - the locH of myOrigin))
-- determines quadrant of vertex point
-- 1 = NE, 2 = NW, 3=SW, 4=SE
if the locV of myVertex < the locV of myOrigin then
-- we are in quads 1 or 2
if the locH of myVertex < the locH of myOrigin then
-- quad 2
set myTheta = 180 + myTheta
else
-- quad 1, no adjustment
end if
else
-- we are in quads 3 or 4
if the locH of myVertex < the locH of myOrigin then
-- quad 3
set myTheta = 180 + myTheta
else
-- quad 4
set myTheta = 360 + myTheta
end if
end if
-- keep track of the starting angle
set myMin = myTheta
-- calculate radius with distance formula
set myRadius = sqrt ( power( the locH of myVertex - the locH of myOrigin , 2) + ¬
power( the locV of myVertex - the locV of myOrigin , 2) )
end if
end
on prepareFrame me
-- called on every frame update to generate new locations
-- First check if this motion is active
if myState = #go then
-- only update if we have passed our delay interval
if the ticks - myClock > myDelay then
if myMode = #arcSweep then
-- update to new value
set myTheta = myTheta + myIncrement
-- need two tests for ending condition
if myIncrement > 0 then
-- test for counter-clockwise movement
if myTheta < myMin + myMax then
move( me, myTheta)
else
set myState = #stop
end if
else
-- test for clockwise movement
if myTheta > myMin - myMax then
move(me, myTheta)
else
set myState = #stop
end if
end if
else if myMode = #fullSweep then
-- full sweeps, just increment and draw
set myTheta = myTheta + myIncrement
move(me, myTheta)
else if myMode = #randomSweep then
-- random sweeps, calculate for range withing specified
-- inputs, in appropriate direction from starting point
if myIncrement > 0 then
set myTheta = myMin + random(myMax)
else
set myTheta = myMin - random(myMax)
end if
move(me, myTheta)
end if
-- update the clock
set myClock = the ticks
end if
updateStage
end if
end
on move me, newTheta
-- general purpose call to move the needle to the new value (degrees)
set myTheta = newTheta
-- correct for angles that go negative
if myTheta < 0 then set myTheta = 360 + myTheta
-- we need to work off of a local variable so we can test quadrants
set localTheta = myTheta
-- reduce the local theta to less than 360
repeat while localTheta >= 360
set localTheta = localTheta - 360
end repeat
-- 0 degree angle special case
if localTheta = 0 then
-- update new vertex point
set myVertex = myOrigin + point(integer( myradius),0)
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line13"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = ¬
rect(the locH of myOrigin, the locV of myVertex, the locH of myVertex, ¬
the locV of myOrigin + the lineSize of sprite (the spriteNum of me) )
else if localTheta < 90 then
-- quadrant 1
-- update new vertex point
set myVertex = myOrigin + point( integer(myRadius * ¬
cos (localTheta / theRadToDeg )), - integer(myRadius * ¬
sin (localTheta / theRadToDeg)))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line13"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = ¬
rect(the locH of myOrigin, the locV of myVertex, ¬
the locH of myVertex, the locV of myOrigin)
else if localTheta = 90 then
-- 90 degree angle special case
-- update new vertex point
set myVertex = myOrigin - point( 0, integer( myradius))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line24"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = ¬
rect(the locH of myVertex - the lineSize of sprite (the spriteNum of me), ¬
the locV of myVertex, the locH of myOrigin, the locV of myOrigin)
else if localTheta < 180 then
-- quadrant 2
-- update new vertex point
set myVertex = myOrigin + point( integer(myRadius * ¬
cos (localTheta / theRadToDeg )), - integer(myRadius * ¬
sin (localTheta / theRadToDeg)))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line24"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = ¬
rect(the locH of myVertex, the locV of myVertex, ¬
the locH of myOrigin, the locV of myOrigin)
else if localTheta = 180 then
-- 180 degree angle special case
-- update new vertex point
set myVertex = myOrigin - point(integer( myradius),0)
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line13"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = ¬
rect(the locH of myVertex, the locV of myOrigin - ¬
the lineSize of sprite (the spriteNum of me), ¬
the locH of myOrigin, the locV of myVertex)
else if localTheta < 270 then
-- quadrant 3
-- update new vertex point
set myVertex = myOrigin + point( integer(myRadius * ¬
cos (localTheta / theRadToDeg )), - integer(myRadius * ¬
sin (localTheta / theRadToDeg)))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line13"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = ¬
rect(the locH of myVertex, the locV of myOrigin, ¬
the locH of myOrigin, the locV of myVertex)
else if localTheta = 270 then
-- 270 degree angle special case
-- update new vertex point
set myVertex = myOrigin + point( 0, integer( myradius))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line24"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = ¬
rect(the locH of myVertex, the locV of myVertex, ¬
the locH of myOrigin + the lineSize of sprite (the spriteNum of me), ¬
the locV of myOrigin)
else
-- quadrant 4
-- update new vertex point
set myVertex = myOrigin + point( integer(myRadius * ¬
cos (localTheta / theRadToDeg )), - integer(myRadius * ¬
sin (localTheta / theRadToDeg)))
-- set appropriate line sprite
set the memberNum of sprite (the spriteNum of me) = the number of member "line24"
-- scale the sprite by its rect
set the rect of sprite (the spriteNum of me) = ¬
rect(the locH of myVertex, the locV of myVertex, ¬
the locH of myOrigin, the locV of myOrigin)
end if
end
on getPropertyDescriptionList
set p_list = [ #myOriginLoc:
[ #comment:"Origin Location:", ¬
#format: #string, #default:1, ¬
#range:[#topLeft,#bottomRight,#topRight,#bottomLeft] ], ¬
#myMode: ¬
[ #comment: "Type of Dial:",¬
#format: #symbol, #default: 1, ¬
#range: [#arcSweep,#fullSweep,#randomSweep,#externalTrigger ]] ]
addProp p_list, #myMax, [#comment: "arc sweep (deg)", ¬
#format: #integer, #default:360, #range:[#min:1,#max:360] ]
addProp p_list, #myIncrement, [#comment: "increment per move (deg)", ¬
#format: #integer, #default:10]
addProp p_list, #myDirection, [#comment: "direction", ¬
#format: #symbol, #default:1, #range:["Counter-Clockwise", "Clockwise"] ]
addProp p_list, #myDelay, [#comment: "delay time (ticks)", ¬
#format: #integer, #default:60]
addProp p_list, #myTrails, [#comment: "trails", ¬
#format: #boolean, #default:0]
return p_list
end
|
| This is the entire behavior, minus get PropertyDescription. It must deal with all 4 quadrants to handle the trig functions.
lingo era = v6 |