• MacTech Network:
  • Tech Support
  • |
  • MacForge.net
  • |
  • Apple News
  • |
  • Register Domains
  • |
  • SSL Certificates
  • |
  • iPod Deals
  • |
  • Mac Deals
  • |
  • Mac Book Shelf

MAC TECH

  • Home
  • Magazine
    • About MacTech in Print
    • Issue Table of Contents
    • Subscribe
    • Risk Free Sample
    • Back Issues
    • MacTech DVD
  • Archives
    • MacTech Print Archives
    • MacMod
    • MacTutor
    • FrameWorks
    • develop
  • Forums
  • News
    • MacTech News
    • MacTech Blog
    • MacTech Reviews and KoolTools
    • Whitepapers, Screencasts, Videos and Books
    • News Scanner
    • Rumors Scanner
    • Documentation Scanner
    • Submit News or PR
    • MacTech News List
  • Store
  • Apple Expo
    • by Category
    • by Company
    • by Product
  • Job Board
  • Editorial
    • Submit News or PR
    • Writer's Kit
    • Editorial Staff
    • Editorial Calendar
  • Advertising
    • Benefits of MacTech
    • Mechanicals and Submission
    • Dates and Deadlines
    • Submit Apple Expo Entry
  • User
    • Register for Ongoing Raffles
    • Register new user
    • Edit User Settings
    • Logout
  • Contact
    • Customer Service
    • Webmaster Feedback
    • Submit News or PR
    • Suggest an article
  • Connect Tools
    • MacTech Live Podcast
    • RSS Feeds
    • Twitter

ADVERTISEMENT

Volume Number: 13 (1997)
Issue Number: 11
Column Tag: Tips & Tidbits

by Steve Sisak

Here is an easy technique for determining if a point lies within a given graphic object of arbitrary complexity: simply draw the object into an offscreen bitmap, then check if the desired pixel has been changed. In more detail, the steps are:

  • Create an offscreen black-and-white bitmap, one pixel high by 16 pixels wide (actually it only needs to be one pixel wide, but QuickDraw insists that you allocate an even number of bytes).
  • Erase this bitmap to white.
  • Draw the shape into the bitmap in solid black.
  • Test the desired pixel to see if it has been set to black.

Here is some actual code that shows you how to hit test a polygon in this way. First, an auxiliary routine to aid the setup of an offscreen black-and-white GrafPort (since GWorlds are overkill for this purpose):

PROCEDURE SetBitsTo
   (
    VAR TheBits : BitMap
   );
   (* sets the portBits of the current grafPort, also
    changing the portRect, clipRgn, visRgn to match
    the bounds of the bitmap. *)

    VAR
      CurPort : GrafPtr;

  BEGIN
    SetPortBits(TheBits);
    MovePortTo(0, 0);
    SetOrigin(TheBits.bounds.left, TheBits.bounds.top);
    PortSize
     (
      TheBits.bounds.right - TheBits.bounds.left,
      TheBits.bounds.bottom - TheBits.bounds.top
     );
    GetPort(CurPort);
    ClipRect(CurPort^.portRect);
    CopyRgn(CurPort^.clipRgn, CurPort^.visRgn)
  END SetBitsTo;

Then, the actual routine that hit tests a point against a polygon:

  PROCEDURE PtInPoly
   (
    pt : Point;
    poly : PolyHandle
   ) : BOOLEAN;
   (* is the specified point within the given polygon. *)

    VAR
      PreviousPort : GrafPtr;
      TempPort : GrafPort;
      TempBits : BitMap;
      TempBitsWord : ShortCard; (* a 1-by-16 offscreen bitmap *)

  BEGIN
    GetPort(PreviousPort);
    OpenPort(ADR(TempPort));
    TempBits.bounds.top := pt.v;
    TempBits.bounds.bottom := pt.v + 1;
    TempBits.bounds.left := pt.h - 15;
      (* so desired pixel is in bit 0 *)
    TempBits.bounds.right := pt.h + 1;
    TempBits.rowBytes := 2;
    TempBits.baseAddr := ADR(TempBitsWord);
    TempBitsWord := 0; (* set all pixels to white *)
    SetBitsTo(TempBits);
    PaintPoly(poly); (* draw polygon in black *)
    ClosePort(ADR(TempPort));
    SetPort(PreviousPort);
    RETURN
      ODD(TempBitsWord)
  END PtInPoly;

It shouldn't be hard to see how to adapt the basic idea to other sorts of graphic objects, or even to other graphics architectures besides QuickDraw.

Lawrence D'Oliveiro
ldo@geek-central.gen.nz

 
MacTech Only Search:
Community Search:

 
 
 

 
 
 
 
 
  • SPREAD THE WORD:
  • Slashdot
  • Digg
  • Del.icio.us
  • Reddit
  • Newsvine
  • Generate a short URL for this page:



MacTech Magazine. www.mactech.com
Toll Free 877-MACTECH, Outside US/Canada: 805-494-9797
MacTech is a registered trademark of Xplain Corporation. Xplain, "The journal of Apple technology", Apple Expo, Explain It, MacDev, MacDev-1, THINK Reference, NetProfessional, Apple Expo, MacTech Central, MacTech Domains, MacNews, MacForge, and the MacTutorMan are trademarks or service marks of Xplain Corporation. Sprocket is a registered trademark of eSprocket Corporation. Other trademarks and copyrights appearing in this printing or software remain the property of their respective holders.
All contents are Copyright 1984-2010 by Xplain Corporation. All rights reserved. Theme designed by Icreon.
 
Nov. 20: Take Control of Syncing Data in Sow Leopard' released
Nov. 19: Cocktail 4.5 (Leopard Edition) released
Nov. 19: macProVideo offers new Cubase tutorials
Nov. 18: S Stardom anounces Safe Capsule, a companion piece for Apple's
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live