666. Треугольник и точка
Определите,
лежит ли заданная точка внутри заданного треугольника.
Вход. Первые 3 строки содержат координаты
вершин треугольника (в каждой строке по 2 целых числа). Четвертая строка
содержит координаты точки, в таком же формате. Все числа – целые, по модулю не
превосходящие 10000. Гарантируется, что вершины треугольника не лежат на одной
прямой.
Выход. Вывести
слово “In”, если точка
лежит внутри треугольника, “On”, если
точка лежит на границе треугольника (вершине или стороне), “Out” если точка
лежит вне треугольника.
Пример входа |
Пример выхода |
-2 -2 3 1 0 1 0 0 |
In |
геометрия
Точка O лежит
внутри треугольника ABC тогда и только тогда, когда все три поворота OAB, OBC и
OCA правые (треугольник ABC ориентирован
по часовой стрелке) или левые (треугольник ABC ориентирован против часовой
стрелки). То есть все выражения OA ´ AB, OB ´ BC, OC ´ CA имеют одинаковый знак (через ´ здесь обозначено псевдоскалярное
произведение).
Пусть a(x1,
y1) и b(x2, y2) – координаты векторов. Тогда
a ´ b = = x1y2
– x2y1
Точка O лежит на
границе треугольника, если все выражения OA ´ AB, OB ´ BC, OC ´ CA либо неотрицательны, либо
неположительны, но одно из них обязательно равно 0. Например, если O лежит на
стороне BC, то OB ´ BC = 0.
Реализация алгоритма
Читаем
координаты вершин треугольника A, B, C и точки О. Вычисляем требуемые векторные
произведения.
scanf("%d %d %d %d %d %d %d %d",&xA,&yA,&xB,&yB,&xC,&yC,&xO,&yO);
//
OA = (xA - xO,yA - yO)
//
AB = (xB - xA,yB - yA)
OAxAB = (xA -
xO)*(yB - yA) - (xB - xA)*(yA - yO);
//
OB = (xB - xO,yB - yO)
//
BC = (xC - xB,yC - yB)
OBxBC = (xB -
xO)*(yC - yB) - (xC - xB)*(yB - yO);
//
OC = (xC - xO,yC - yO)
//
CA = (xA - xC,yA - yC)
OCxCA = (xC -
xO)*(yA - yC) - (xA - xC)*(yC - yO);
Если все
вычисленные произведения одного знака, точка О лежит внутри треугольника ABC.
Если одно из произведений равно нулю, точка О лежит на границе треугольника.
Иначе точка О находится вне треугольника.
if (((OAxAB > 0) &&
(OBxBC > 0) && (OCxCA > 0)) ||
((OAxAB < 0)
&& (OBxBC < 0) && (OCxCA < 0))) printf("In\n");
else
if (((OAxAB >= 0) &&
(OBxBC >= 0) && (OCxCA >= 0)) ||
((OAxAB <= 0)
&& (OBxBC <= 0) && (OCxCA <= 0))) printf("On\n");
else printf("Out\n");