Чтобы перевести исходный алгоритм на английский: вы определяете, является ли количество сегментов многоугольника справа от вашей точки четным или нечетным. Если она четная (включая ноль), ваша точка находится снаружи, если она нечетная, ваша точка находится внутри. Это означает, что если есть два сегмента справа, а также два сегмента слева, точка считается , а не внутри многоугольника.
Вам нужно изменить алгоритм так, чтобы он проверял сегменты с обеих сторон; если по обе стороны от точки есть отрезок, то точка находится внутри многоугольника.
int CGlEngineFunctions::PointInPoly(int npts, float *xp, float *yp, float x, float y)
{
int i, j;
bool hasSegmentLeft = false;
bool hasSegmentRight = false;
for (i = 0, j = npts-1; i < npts; j = i++) {
if ((((yp[i] <= y) && (y < yp[j])) ||
((yp[j] <= y) && (y < yp[i]))))
{
if (x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i])
{
hasSegmentRight = true;
if (hasSegmentLeft) // short circuit early return
return true;
}
else
{
hasSegmentLeft = true;
if (hasSegmentRight) // short circuit early return
return true;
}
}
return hasSegmentLeft && hasSegmentRight;
}
P.S. эта конструкция оператора for
является очень умным способом работы с циклическим списком, который переносится в начало; Я никогда не видел этого раньше.