top of script window
maricopa-a sketch code snippet | show it | return |
------------------------------------
-- HANDLER on turnKnob
--
-- used to rotate the pairs of sprites for the knobs- 
-- smaller "bump" is circularly contrained
-- lots of lingo to locate the quadrant
-- and it still is a bit quirky near the crossing of quadrants

-- assumes the drawing sprite is in sprite 10 and its
-- trails properties are set to TRUE

-- In this application, each call to draw is in horizontal
-- or vertical direction

on turnKnob bumpSprite, knobSprite, horizvert
  -- circular contraint after tip posted to direct-l
  -- Date: Wed, 12 Jul 1995 19:53:37 GMT
  -- From: "Glenn M. Picher" 
  -- Subject: Re: Constraining to a circle  
  
  --  knobsprite = the big button knob
  --  bumpsprite = a small sprite that represents that control knob position
  --  horizvert = symbol flag, values are #horiz or #vert
  
  -- "jiggle" the knobs location  to let user know they are activated
  set the loc of sprite knobSprite = the loc of sprite knobSprite + point(2,1)
  set the loc of sprite bumpSprite = the loc of sprite bumpSprite + point(2,1)
  updateStage
  
  -- calculate center of rotation
  set centerPoint = the loc of sprite knobsprite
  
  -- set up variable to hold preceding point and quadrant 
  -- (1=NE, 2=NW, 3=SW, 4=SE)
  set lastpoint = the loc of sprite bumpSprite
  set lastQuad = whatQuadrant(centerPoint,lastPoint)
  
  -- continue drawing as long as mouse is held
  repeat while the stillDown
    
    -- calculate offsets
    put the mouseH into mx
    put the mouseV into my
    put mx - the locH of centerPoint into xAtMouse
    put my - the locV of centerPoint into yAtMouse
    
    if xAtMouse <> 0 then
      -- there's a valid "triangle" to figure out the 
      --  angle using arctangent
      put atan(float(abs(yAtMouse))/float(abs(xAtMouse))) into angleAtMouse
      
      if angleAtMouse = 0 then
        --it's a horizontal line
        set yAtCircle to 0
        set xAtCircle to radius * (xAtMouse/abs(xAtMouse)) --set proper direction
      else
        --it's a true triangle
        set yAtCircle to sin(angleAtMouse) * radius * (yAtMouse/abs(yAtMouse))
        set xAtCircle to cos(angleAtMouse) * radius * (xAtMouse/abs(xAtMouse))
      end if
    else
      --it's a vertical line
      put 0 into xAtCircle
      if yAtMouse <> 0 then
        set yAtCircle to radius * (yAtMouse/abs(yAtMouse))
      else
        --brute force to avoid divide by zero error
        put radius into yAtCircle
      end if
    end if
    
    -- update position
    set the loc of sprite bumpSprite to centerPoint + ¬
         point(integer(xAtCircle), integer(yAtCircle))
    updateStage
    
    -- determine quadrant of new point and direction of rotation
    -- from previous position:
    --   clockwise        -> direction = -1
    --   counterclockwise -> direction = 1
    
    set newQuad = whatQuadrant(the loc of sprite bumpSprite, centerPoint)
    
    -- no offset if the drawing point has not moved
    if the loc of sprite bumpSprite = lastPoint then
      set direction = 0
      
    else  if newQuad = lastQuad then        
      -- same quadrant
      if the locV of sprite bumpSprite < the locV of centerPoint then
        -- Quadrant 1 or 2
        if the locH of sprite bumpSprite < the locH of lastpoint then
          set direction = 1
        else
          set direction = -1
        end if
      else
        -- Quadrant 3 or 4
        if the locH of sprite bumpSprite > the locH of lastpoint then
          set direction = 1
        else
          set direction = -1
        end if
      end if
      
      -- check for crossover quadrants
    else if  newQuad = 4 and lastQuad = 1 then
      set direction = -1
    else if  newQuad = 1 and lastQuad = 4 then
      set direction = 1
      
    else if newQuad > lastQuad then
      set direction = 1
    else
      set direction = -1
    end if
    
    -- update the drawing of the drawing sprite (10) to the previous position
    set the loc of sprite 11 = the loc of sprite 10
    if horizvert = #horiz then
      set the locH of sprite 10 = the locH of sprite 10 + direction
    else
      set the locV of sprite 10 = the locV of sprite 10 + direction
    end if
    
    set lastPoint = the loc of sprite bumpSprite
    set lastQuad = newQuad
    
    puppetSound "swish"
    updatestage
  end repeat
  
  -- "un-jiggle" the button sprites
  set the loc of sprite knobSprite = the loc of sprite knobSprite + point(-2,-1)
  set the loc of sprite bumpSprite = the loc of sprite bumpSprite + point(-2,-1)
  updateStage
  
end
The turnKnob handler rotates one sprite around the circle defined by the rect of another sprite, using inverse trig functions and testing for different quadrants.

lingo era = v5 The sprite numbers here are hardwired and this handler is also written to do the drawing routine as part of the "sketching"