Определить: лежит точка в треугольнике - QBasic
Формулировка задачи:
Мне уже два или три раза попадались задачи, где прямо
или косвенно требовалось определить: лежит точка в
треугольнике или нет. Ответы были половинчатыми и
даже мой собственный ответ мне не понравился. И вот
здесь, я решил раз и навсегда дать четкий ответ на этот
вопрос. Итак нам задан треугольник с координатами
вершин (x1;y1), (x2;y2), (x3;y3) и точка (x4;y4).
Требуется определить положение точки относительно
треугольника.
Предположим, что точка лежит внутри треугольника.
Соединим эту точку с любой вершиной треугольника.
Тогда мы можем составить два уравнения прямой
1-я прямая проходит через вершину треугольника и
заданную точку. 2-я прямая сторона, которую пересекает
1-я прямая. Вот их уравнения:
(x - x1)/(x4 - x1) = (y - y1)/(y4 - y1)
(x - x2)/(x3 - x2) = (y - y2)/(y3 - y2)
Найдем точку пересечения этих прямых:
(дополнительно введем обозначения)
A = (y4 - y1)/(x4 - x1)
B = (y3 - y2)/(x3 - x2)
и далее имеем систему
y = A(x - x1) + y1
y = B(x - x2) + y2
решая ее получим
x = (A*x1 - B*x2 + y2 + y1)/(A - B)
y = A(x - x1) + y1
(пусть C - вершина треугольника, D - точка,
E - найденная нами точка пересечения)
Теперь надо убедиться, что выполняется равенство:
CD + DE = CE (!!!)
И САМОЕ ГЛАВНОЕ:
если вы думаете, что все уже сделано, то ошибаетесь
Надо ВСЕ вычисления провторить для КАЖДОЙ ВЕРШИНЫ !
Я привожу вам кристально чистое и логически корректное решение
Перед красотой этого кода вздрогнет сердце программиста
(если он настоящий программист (от бога !!))
P.S.
Дарю вам этот код и Радость грядущего лета впридачу!
P.P.S.
как я рад, что кому-то помог
Листинг программы
- DEFSNG A-D, R, X-Y
- DEFINT E
- DECLARE SUB TRI (c1!, d1!, c2!, d2!, c3!, d3!, c4!, d4!, e%)
- CLS
- RANDOMIZE TIMER
- x1 = 10 * RND
- x2 = 10 * RND
- x3 = 10 * RND
- x4 = 10 * RND
- y1 = 10 * RND
- y2 = 10 * RND
- y3 = 10 * RND
- y4 = 10 * RND
- e = 0
- IF (x3 - x1) * (y2 - y1) = (y3 - y1) * (x2 - x1) THEN
- PRINT "Line"
- GOTO 100
- END IF
- CALL TRI(x1, y1, x2, y2, x3, y3, x4, y4, e)
- CALL TRI(x2, y2, x1, y1, x3, y3, x4, y4, e)
- CALL TRI(x3, y3, x2, y2, x1, y1, x4, y4, e)
- IF e = 3 THEN
- PRINT "Yes"
- ELSE
- PRINT "No"
- END IF
- PRINT USING "#.##### "; x1; x2; x3; x4
- PRINT USING "#.##### "; y1; y2; y3; y4
- 100
- END
- SUB TRI (c1, d1, c2, d2, c3, d3, c4, d4, e)
- a = (d4 - d1) / (c4 - c1)
- b = (d3 - d2) / (c3 - c2)
- c5 = (a * c1 - b * c2 + d2 - d1) / (a - b)
- d5 = a * (c5 - c1) + d1
- r1 = SQR((c4 - c1) ^ 2 + (d4 - d1) ^ 2)
- r2 = SQR((c4 - c5) ^ 2 + (d4 - d5) ^ 2)
- r = SQR((c1 - c5) ^ 2 + (d1 - d5) ^ 2)
- IF ABS(r1 + r2 - r) < .0001 THEN e = e + 1
- END SUB
Решение задачи: «Определить: лежит точка в треугольнике»
textual
Листинг программы
- DECLARE FUNCTION s (x1, y1, x2, y2, x, y)
- INPUT "#1 - ", x1, y1
- INPUT "#2 - ", x2, y2
- INPUT "#3 - ", x3, y3
- INPUT "#4 - ", x4, y4
- side1=(s(x1, y1, x2, y2, x3, y3)=s(x1, y1, x2, y2, x4, y4)) 'проверка на одностороннее положение (относительно
- side2=(s(x2, y2, x3, y3, x1, y1)=s(x2, y2, x3, y3, x4, y4)) 'проверяемой стороны) данной точки и точек треугольника,
- side3=(s(x1, y1, x2, y2, x3, y3)=s(x1, y1, x2, y2, x4, y4)) 'не лежащих на проверяемой стороне
- IF side1 AND side2 AND side3 THEN PRINT "in the triangle" ELSE PRINT "not in triangle" 'если все всё по одну сторону, то true
- END
- FUNCTION s (x1, y1, x2, y2, x, y)
- k=(y2-y1)/(x2-x1) 'вычисление линейного уравнения стороны
- b=y1-k*x1
- s=x*k+b<y 'выше ли точка относительно стороны
- IF x2=x1 THEN s=x<x1 'если сторона вертикальна, то проверка: левее ли точка относительно стороны
- END FUNCTION
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д