INTELLIGENT WORK FORUMS FOR COMPUTER PROFESSIONALS
Log In
Come Join Us!
Are you a Computer / IT professional? Join TekTips Forums!
 Talk With Other Members
 Be Notified Of Responses
To Your Posts
 Keyword Search
 OneClick Access To Your
Favorite Forums
 Automated Signatures
On Your Posts
 Best Of All, It's Free!
*TekTips's functionality depends on members receiving email. By joining you are opting in to receive email.
Posting Guidelines
Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Microsoft: Visual FoxPro FAQ
Graphics
How to determine whether a clicked point is inside an irregular polygon outlining an ImageMap? by wgcs
Posted: 26 Sep 02

It's easy to tell if someone clicked on a convex shape (rectangle, circle) particularly because it's "Click" event get's fired!
However, if you use an ImageMaplike outline that surrounds a concave / irregular polygon outlining a feature on a graphic image, it gets a whole lot more complicated to determine whether that click was inside or outside the polygon.
Here's code that works (with a test sample) (this was converted by me into VFP from the noted code that was written in C++):
******************************************************************************** * The following routines are used to determine whether a point that is clicked * is inside an imagemap polygon. The original source was borrowed: *!* // Copyright 2001, softSurfer (www.softsurfer.com) *!* // This code may be freely used and modified for any purpose *!* // providing that this copyright notice is included with it. *!* // SoftSurfer makes no warranty for this code, and cannot be held *!* // liable for any real or imagined damage resulting from its use. *!* // Users of this code must verify correctness for their application. * *// a Point is defined by its coordinates {int x, y;} *//===================================================================
*!* // cn_PnPoly(): crossing number test for a point in a polygon *!* // Input: P = a point, *!* // V[] = vertex points of a polygon V[n+1] with V[n]=V[0] *!* // Return: 0 = outside, 1 = inside *!* // This code is patterned after [Franklin, 2000] FUNCTION InPoly( P_X, P_Y, V ) EXTERNAL ARRAY V LOCAL cn, lnI, lnALen, vt lnALen = ALEN( V, 1 ) && Number of Vertices cn = 0 && // the crossing number counter * // loop through all edges of the polygon for lnI = 1 TO lnALen1 && (int i=0; i<n; i++) { // edge from V[i] to V[i+1] ** if (((V[i,2] <= P_y) && (V[i+1].y > P.y)) // an upward crossing **  ((V[i].y > P.y) && (V[i+1].y <= P.y))) { // a downward crossing if (((V[lnI,2] <= P_y) AND (V[lnI+1,2] > P_y)) ; OR ((V[lnI,2] > P_y) AND (V[lnI+1,2] <= P_y))) ** // compute the actual edgeray intersect xcoordinate **float vt = (float)(P.y  V[i].y) / (V[i+1].y  V[i].y) vt = (P_y  V[lnI,2]) / (V[lnI+1,2]  V[lnI,2]) **if (P.x < V[i].x + vt * (V[i+1].x  V[i].x)) // P.x < intersect if (P_x < V[lnI,1] + vt * (V[lnI+1,1]  V[lnI,1])) && // P.x < intersect cn = cn + 1 && ++cn; // a valid crossing of y=P.y right of P.x ENDIF ENDIF ENDFOR RETURN cn=1 && // 0 if even (out), and 1 if odd (in)
PROCEDURE TestPoly * This routine tests the above routines that calculate whether * a point is within a polygon. * Vertices: * (these vertices define a convex, irregular polygon * that looks somewhat like: * /\ * / \ * \/\/ * and the test case runs horizontally * through it's "legs" )
DIMENSION aPoly[6,2] aPoly[1,1]=66 aPoly[1,2]=121 aPoly[2,1]=129 aPoly[2,2]=52 aPoly[3,1]=237 aPoly[3,2]=105 aPoly[4,1]=205 aPoly[4,2]=227 aPoly[5,1]=148 aPoly[5,2]=136 aPoly[6,1]=98 aPoly[6,2]=223
SET PROCEDURE TO AhRooming ?InPoly( 20, 140, @aPoly) && Out ?InPoly(104, 130, @aPoly) && in ?InPoly(147, 174, @aPoly) && Out ?InPoly(194, 130, @aPoly) && In ?InPoly(267, 140, @aPoly) && Out
RETURN

Back to Microsoft: Visual FoxPro FAQ Index
Back to Microsoft: Visual FoxPro Forum 


