Hit testing of lines/paths can basically be done in two ways:

a) mathematically, in that you determine whether a given point is close to a 
given line by calculation
b) graphically, in that you draw the line into some image and test the pixel 
drawn.

I've done quite a bit of work on this in the past in my DrawKit framework, and 
without a doubt approach (b) is by far the most versatile. For one thing it can 
deal with varying transparency, line widths, antialiasing and other stylistic 
variations you might dream up.

The general approach, which is due to Ken Ferry, is to create a bitmap just 1 
pixel by 1 pixel, having only an alpha channel. Using a suitable transform, you 
translate this bitmap (within a suitable context) to the point you're 
hit-testing, and draw the path you're testing into the context. If the path 
draws a non-tranparent pixel at the hit-test location, the 1-byte backing store 
of the bitmap will be changed. If it was not hit, it won't. This is very 
efficient as the graphics system doesn't waste time rendering to a bitmap that 
doesn't exist, and it uses a tiny amount of memory. It's easily fast enough for 
real-time hit testing (and it's also easy to refine such that when you are 
hit-testing as opposed to drawing the real path, you can take shortcuts such as 
using a coarser flatness value, rendering just one of several strokes, etc. You 
can also set up the test context/bitmap just once and reuse it for all tests so 
avoiding the overhead of creating this set of objects each time - you just need 
to clear the single alpha byte.).

Highly recommended.

--Graham







On 23/11/2010, at 3:12 AM, Cody Garvin wrote:

> Hi all,
> 
> I searched back through 2005 in the Cocoa Mailing List and didn't see any 
> requests for this.
> 
> We need all the points on a line / arc / path on the screen. We need to do 
> hit detection on stroked line, so we must know if the point is valid or not. 
> 
> I thought using CGPathContainsPoint would work, but it must be done on a 
> closed path or it returns true on all points in the test area. 
> 
> I also tried NSBezierPath containsPath: and , but it returned the exact same 
> things as the CGPath functions. 
> 
> Another idea I have, though not sure if it will work, is converting the 
> drawing to NSBitmapImageRep and using colorAtX:y to test for a specific color 
> to test for a point.
> 
> The downside of this approach is you must test all the points in a bounding 
> box, and could get quite large if our line segment is complicated.
> 
> I'm surprised I haven't found a convenience method to return all the points 
> in an outline.
> 
> Any help would be greatly appreciated.

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to