Разбить задачу на под-тесты более простых форм - вот путь.
Проблемы с краями: "внешний" тест с использованием !inside()
является проблемой, когда точка находится на краю формы.
Чтобы использовать тест в форме формы как "внутри", так и "снаружи", верните 1 из 3 значений
int test_rectangle(double x0, double y0, double x1, double y1, double px, double py) {
if (x1 < x0) {
double t = x1; x1 = x0; x0 = t;
}
if (y1 < y0) {
double t = y1; y1 = y0; y0 = t;
}
if (px < x0 || px > x1 || py < y0 || py > y1) return 1; // outside
if (px > x0 && px < x1 && py > y0 && py < y1) return -1; // inside
return 0; // edge
}
Тест по кругу более сложный. Хотя стандартная функция hypot()
может обеспечить более точные результаты, чем sqrt(x*x + y*y)
, вычитания и hypot()
могут вызвать ошибку округления, при которой вопросы выбирают результаты случая ребра.
int test_circle(double x, double y, double radius, double px, double py) {
double hyp = hypot(x - px, y - py);
if (hyp > radius) return 1; // outside
if (hyp < radius) return -1; // inside
return 0; // edge
}