Я пришел к решению, которое соответствует требованиям, и все еще хотел бы услышать, есть ли лучший способ сделать это.Мой подход заключается в следующем: выполнить проверку попадания с помощью ограничивающего прямоугольника, а затем проверку геометрического попадания на основе типа геометрии.
Для полигонов я адаптировал упомянутый код C http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes /pnpoly.html для работы в C #.
int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy)
{
int i, j, c = 0;
for (i = 0, j = nvert-1; i < nvert; j = i++) {
if ( ((verty[i]>testy) != (verty[j]>testy)) &&
(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
c = !c;
}
return c;
}
Для эллипсов я адаптировал этот код: http://msdn.microsoft.com/en-us/library/aa231172%28v=vs.60%29.aspx
BOOL CCircCtrl::InCircle(CPoint& point)
{
CRect rc;
GetClientRect(rc);
GetDrawRect(&rc);
// Determine radii
double a = (rc.right - rc.left) / 2;
double b = (rc.bottom - rc.top) / 2;
// Determine x, y
double x = point.x - (rc.left + rc.right) / 2;
double y = point.y - (rc.top + rc.bottom) / 2;
// Apply ellipse formula
return ((x * x) / (a * a) + (y * y) / (b * b) <= 1);
}