Основы компьютерной графики для программистов 18
____________________________________________________________________________________________________________________
http://www.ksu.ru/persons/9134.ru.html
оказалась бы выше или ниже оси ox, в зависимости от выбранного направления обхода
вершин треугольника.
Рассмотрим версию функции
InTri, в которой реализуется данный метод для
целочисленных координат треугольника
A=(AX,AY), B=(BX,BY), C=(CX,CY) и
проверяемой точки
X=(x,y). Функция выдает результат TRUE, если точка находится
внутри или на границе треугольника (граница, таким образом, считается
принадлежащей внутренней области треугольника), или FALSE, если точка находится
за его пределами. Этой функцией удобно пользоваться если точки находятся на
растровой сетке монитора, где координаты являются целыми числами.
function InTriI(x,y,AX,AY,BX,BY,CX,CY: Integer): boolean;
var
Res1,Res2: Integer;
begin
Res1:= (y-ay)*(cx-ax)-(x-ax)*(cy-ay);
Res2:= (y-cy)*(bx-cx)-(x-cx)*(by-cy);
// if (Res1>0)and(Res2<0)or(Res1<0)and(Res2>0) then
if Res1 XOR Res2 < 0 then
Result:= false //дальше не вычисляем
else
begin
Res2:= (y-by)*(ax-bx)-(x-bx)*(ay-by);
// if (Res1>0)and(Res2<0)or(Res1<0)and(Res2>0) then
if Res1 XOR Res2 < 0 then
Result:= false
else
Result:= true;
end;
end;
Обратите внимание на пару строк, которые дважды встречаются в тексте функции.
// if (Res1>0)and(Res2<0)or(Res1<0)and(Res2>0) then
if Res1 XOR Res2 < 0 then
Первая из двух строк специально закомментирована, так как вторая представляет собой
ее оптимизированный вариант. Изначально в методе требуются действия, записанные в
первой строке, где производится проверка на совпадение или несовпадение знаков
вычисленных углов, что определяется переменными Res1 и Res2. Поскольку знак
целого числа определяется его левым битом, точнее число считается отрицательным,
если самый
старший его бит равен 1, то он всегда будет равен единице при умножении
двух чисел разного знака. Операцией целочисленного умножения здесь можно было бы
воспользоваться, если бы операция XOR не давала аналогичный результат значительно
быстрее. Код ассемблера, который генерирует Delpi, в случае использования операции
XOR, примерно в 4 раза короче чем тот, что получается при
использовании первой из
двух рассмотренных нами строк на Паскале. Точнее, при включенной опции
оптимизации компиляции в Delphi, вторая строка реализуется всего двумя
инструкциями ассемблера, включая команду условного перехода. Но самое интересное,
что аналогичный программный трюк можно применить и для вещественных входных
параметров функции – типов Single и Double. Я не буду более вдаваться в
технические
тонкости, просто посмотрите текст функций. В случае вещественных входных
параметров в них появляются небольшие отличия от целочисленного варианта.
Версия функции
InTri для входных параметров типа Single.