Задача:
Даны действительные числа [latex]x_{1}[/latex], [latex]x_{2}[/latex], [latex]x_{3}[/latex], [latex]y_{1}[/latex],[latex]y_{2}[/latex], [latex]y_{3}[/latex].
Принадлежит ли начало координат треугольнику с вершинами [latex]\left( x_{1} ; y_{1} \right) [/latex], [latex]\left( x_{2} ; y_{2} \right) [/latex], [latex]\left( x_{3} ; y_{3} \right) [/latex]?
[latex] x_{1} [/latex] | [latex] y_{1} [/latex] | [latex] x_{2} [/latex] | [latex] y_{2} [/latex] | [latex] x_{3} [/latex] | [latex] y_{3} [/latex] | Предполагаемый результат | Вывод |
-400 | 0 | 240 | 1 | 210 | 1 | Не принадлежит | Тест пройден |
-400 | 0 | 240 | 1 | 210 | -1 | Принадлежит | Тест пройден |
0 | 0 | 240 | -1 | 2100 | -1 | Принадлежит | Тест пройден |
-2 | -2 | 5 | -2 | 1 | 10 | Принадлежит | Тест пройден |
3 | 0 | 40 | 0 | 15 | 10 | Не принадлежит | Тест пройден |
-24 | -2 | 29 | -2 | 29 | 10 | Принадлежит | Тест пройден |
-12 | -5 | 14 | -5 | 7 | -5 | Жаль вас расстраивать… | Тест пройден |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <iostream> using namespace std; int main() { double x1, x2, x3, y1, y2, y3; // double x=0, y=0; // Обьявление переменных, обозначающих координаты вершин треугольника и начала координат cin>> x1 >> y1; // cin>> x2 >> y2; // Ввод координат вершин треугольника cin>> x3 >> y3; // if((y2-y1)*(x3-x1)-(y3-y1)*(x2-x1)==0){ //Небольшая перестраховка cout<<"Жаль вас расстраивать, но это не треугольник."<<endl; } else{ double A, B, C, O1, O2, O3; //Обьявление вспомогательных переменных (нобязательные, но делают код понятнее) A=(y3-y2)*(x1-x2)-(y1-y2)*(x3-x2); B=(y1-y3)*(x2-x3)-(y2-y3)*(x1-x3); C=(y2-y1)*(x3-x1)-(y3-y1)*(x2-x1); O1=(y3-y2)*(x-x2)-(y-y2)*(x3-x2); O2=(y3-y1)*(x-x1)-(y-y1)*(x3-x1); O3=(y2-y1)*(x-x1)-(y-y1)*(x2-x1); if((O1*A>=0)&&(O2*B>=0)&&(O3*C>=0)){ // Главное услоие cout<<"Точка принадлежит треугольнику"<<endl; } else{ cout<<"Точка не принадлежит треугольнику"<<endl; } } return 0; //Конец } |
Описание:
Для решения задачи использовал общее уравнение прямой. Последовательно сравнивая расположение вершин треугольника относительно противоположных им сторон с расположением начала координат относительно тех же сторон, можно определить, находится ли точка внутри треугольника.
Краткий алгоритм:
- Объявление переменных, обозначающих координаты вершин треугольника.
- Ввод координат вершин треугольника.
- Небольшая проверка правильности ввода.
- С помощью общего уравнения прямой [latex]\frac{y-y_{1}}{y_{2}-y_{1}}=\frac{x-x_{1}}{x_{2}-x_{1}}[/latex], приведенного в вид :[latex]\left(y_{2}-y_{1} \right) \left(x-x_{1}\right)-\left(y-y_{1} \right) \left(x_{2}-x_{1}\right)=0[/latex],- определяем расположение вершин треугольника относительно противоположных им сторон (название переменной показывает, какую вершину проверяют), а также начала координат относительно тех же сторон, после чего следует умножение соответствующих величин. В случае, если произведение больше, либо равно нулю во всех трех случаях, можно сделать вывод о том, что точка находится внутри треугольника.
- Вывод вердикта и окончание работы.
Ссылка на Ideone.
Ваш метод с суммой площадей не очень подходит для компьютерной реализации. Вам приходится сравнивать действительные числа на равенство, а этого лучше избегать. Мы на лекции говорили о причинах.
А какой же алгоритм лучше?
Рассмотрим прямую AB. Если уравнение этой прямой подставить координаты точки не лежащей на ней, то уравнение превратится в неравенство. Знак неравенства будет отличаться в зависимости от того в какой полуплоскости лежит точка. Значит, если подставить координаты точки С и начала координат и получить одинаковый знак, то обе точки лежат по одну сторону от АВ. Проделав тоже самое с BC и CD мы сможем убедиться, что точке лежит внутри треугольника. Кстати, уравнение прямой лучше записать в виде (x — x1)(y2 -y1) — (y — y1)(x2 — x1) = 0. Если в эту формулу по очереди подставить координаты пары точек и перемножить полученные результаты, то значение >=0 будет означать, что точки лежат с одной стороны прямой. Вместо умножения возможно лучше сделать сложное логическое выражение с учётом теоретической возможности попадания точно в ноль, что подходит и для положительного и для отрицательного второго значения.
Кроме всего прочего программа будет работать значительно быстрее — меньше вычислений и нет трудоёмких функций вроде вычисления корня.
Если не переделывать всё, то нужно учесть такие замечания:
Кстати, Вы читали это?
Прочитав замечания, понял, что правильнее ( да и просто легче) переделать решение, с помощью метода, предложенного Вами.
P.S. Уже прочитал.
Зачёл на 8 баллов, т.к. задача ещё сентябрьская.
Только поставьте строки №19 и 20 как положено.