Map

From Director Online Wiki
Jump to: navigation, search

The map() function scales and stretches a source rect so that it fits exactly over a target rect. The position (and dimensions) of a given point or rect are then calculated with respect to the new shape, size and position of the target rect.

Like all rect methods, map() produces an output in integers. If the target rect is smaller than the source rect, precision is irrevocably lost. If you need to be able to inverse the mapping operation, you need to use a method which produces an output in floating point numbers:

on mMap(aPointOrRect, aSourceRect, aTargetRect) ----------------------
  -- INPUT: <aPointOrRect> must be a point or a rect
  --        <aSourceRect> must be a rect
  --        <aTargetRect> must be a rect
  -- OUTPUT: Returns a point or rect with floating point values, which
  --         has the same relative position with respect to
  --         aTargetRect as aPointOrRect has to aSourceRect:
  --
  --         ------     -------------------
  --         |   x|     |                 |
  --         ------     |              X  |
  --         source     |                 |
  --                    -------------------
  --                               target
  --
  --         x = input aPointOrRect
  --         X = output
  --
  -- NOTE:   The built-in map() function returns values rounded to the
  --         nearest integer, so the output will not necessarily map
  --         back to the input.  This method is much more accurate.
  --------------------------------------------------------------------
 
  vHScale = aTargetRect.width / float(aSourceRect.width)
  vVScale = aTargetRect.height / float(aSourceRect.height)
 
  case ilk(aPointOrRect) of
   #point:
      vHLoc = aPointOrRect.locH - aSourceRect.left
      vHLoc = (vHLoc * vHScale) + aTargetRect.left
     
      vVLoc = aPointOrRect.locV - aSourceRect.top
      vVLoc = (vVLoc * vVScale) + aTargetRect.top
     
      aPointOrRect = point(vHLoc, vVLoc)
     
    #rect:
      vSourceLeft = aSourceRect.left
      vTargetLeft = aTargetRect.left
      vSourceTop  = aSourceRect.top
      vTargetTop  = aTargetRect.top
     
      vLeft   = aPointOrRect.left - vSourceLeft
      vLeft   = (vLeft * vHScale) + vTargetLeft
     
      vRight  = aPointOrRect.right - vSourceLeft
      vRight  = (vRight * vHScale) + vTargetLeft
     
      vTop    = aPointOrRect.top - vSourceTop
      vTop    = (vTop * vVScale) + vTargetTop
     
      vBottom = aPointOrRect.bottom - vSourceTop
      vBottom = (vBottom * vVScale) + vTargetTop
 
      aPointOrRect = rect(vLeft, vTop, vRight, vBottom)
  end case
 
  return aPointOrRect
end mMap