 |
 |
Points in Rectangles/Regions
|
 |
|
 |
|
Junior Member
Join Date: Nov 2001
Location: Seattle
Status:
Offline
|
|
I'm rather new to Cocoa programming.. is there a call to see if a point is inside a given rectangle? (There's PtInRect, but that appears to be part of the Carbon library and uses Point rather than NSPoint.) Also, is there a way to see if a point is in an arbitrary region? I'll soon be wanting to check if a user tried to click on lines and ovals as well as rectangles.
Making my own "point in rectangle" routine would be pretty easy, but checking point-line and point-oval intersection is less trivial and I'd prefer to use a built-in call if possible.
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: Aug 2001
Status:
Offline
|
|
|
|
|
|
| |
|
|
|
 |
|
 |
|
Junior Member
Join Date: Nov 2001
Location: Seattle
Status:
Offline
|
|
Thanks, that works well. I'll probably end up just making my own point-line segment intersection routine.
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Nov 2001
Location: State of Denial
Status:
Offline
|
|
For the arbitrary region, there's always -[NSBezierPath containsPoint:] ...
|
|
[Wevah setPostCount:[Wevah postCount] + 1];
|
| |
|
|
|
 |
|
 |
|
Junior Member
Join Date: Nov 2001
Location: Seattle
Status:
Offline
|
|
Wevah, thanks. That's simple enough. I tried it for a line segment and I think it's too picky; you have to click *exactly* on the line--a bit annoying as a user. Changing the lineWidth didn't change this..
I ended up writing a routine to check point/line-segment intersection by hand (before you replied). Here it is, for posterity:
Code:
// Checks to see if point A is on a "thick" line segment PQ having width m.
// (that is, if the distance from A to PQ is at most m/2)
+ (BOOL) IsPoint: (NSPoint) a
onLineSegmentWithStart: (NSPoint) p
andSegmentEnd: (NSPoint) q
andWidth: (float) m
{
NSPoint aPrime;
NSPoint qPrime;
NSPoint aNew;
float pqDist;
float sinTheta;
float cosTheta;
// first, translate everything so that point P is at the origin
aPrime.x = a.x - p.x;
aPrime.y = a.y - p.y;
qPrime.x = q.x - p.x;
qPrime.y = q.y - p.y;
// compute the length of the segment PQ
pqDist = sqrt(qPrime.x*qPrime.x + qPrime.y*qPrime.y);
if (pqDist == 0)
{
return NO;
}
// rotate coordinates so that Q is at (pqDist, 0).
cosTheta = qPrime.x / pqDist;
sinTheta = qPrime.y / pqDist;
aNew.x = cosTheta*aPrime.x + sinTheta*aPrime.y;
aNew.y = -sinTheta*aPrime.x + cosTheta*aPrime.y;
// now see if A is on line PQ in these rotated coords
return ( ( 0 <= aNew.x) && (aNew.x <= pqDist) && // x coord
(-m <= aNew.y) && (aNew.y <= m) ); // y coord
}
(Why does the CODE tag always kill indentation? argh.)
Now that I've looked a bit more a the NSBezierPath class, I think I see some possibilities to (possibly) make this easier. One could make an NSBezierPath from a rectangle having the desired width m and having length of the distance between the two points. Then use transformUsingAffineTransform to move this rectangle so that it covers the line segment. Then the containsPoint method would return if a point is on (or nearby) the line segment as desired. Of course, computing some of the parameters for the affine tranformation would involve similar code to what I have here..
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Nov 2001
Location: State of Denial
Status:
Offline
|
|
Oh, poop. I didn't realize you wanted lines; I thought you were dealing with connected paths/shapes.
*Looks up.*
Oh, I see now that you want both. Yeah, it's probably not good for lines. :/
|
|
[Wevah setPostCount:[Wevah postCount] + 1];
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |