chop the line at the "next" window border:

discard the "outside" part; II разделяем пряную у «следующей» границы окна: II отбрасываем «внешнюю» часть } while(l); Алгоритм прекращает работу, пройдя данный цикл не более четырех раз, так как в каждой итерации мы оставляем только ту часть отрезка, которая «выдержала» тестирование относительно предыдущей границы окна, а таких границ всего четыре. Поэтому после максимум четырех итераций обеспечивается тривиальный прием или тривиальное отклонение.

Как осуществляется разделение на каждой границе? На рис. 3.18 показан пример, относящийся к правой границе окна.

Френсис Хилл

(3.4)

Рис, 3.18. Отсечение отрезка относительно границы Положение точки А необходимо вычислить. Ее ^-координата равна, очевидно, W. right - координате правой границы окна. Для определения ее г/-координаты необходимо найти pl.y с помощью поправки d, как указано на рисунке. Однако из подобия треугольников

d _ е dely delx' где е равно pl.x - pi.right, а равенства

delx - р2.х - pl.x; dely - р2.у - pl.y: задают приращения координат для этой пары концевых точек. Следовательно, d легко определить н новое значение pl.y находится путем добавления приращения к старому значению:

pl.y +- (W. right - pl.x) * dely / delx (3.5)

Аналогичные рассуждения используются при отсечении на остальных трех границах окна.

В некоторых наших вычислениях встречается выражение delx/dely, а в других del у/delx. Следует всегда следить, чтобы не было деления на нуль, помня о том, что delx равен нулю для вертикальной прямой, a dely равен нулю для горизонтальной. Однако, как показано в упражнениях, при равенстве нулю знаменателя эти рискованные строки кода никогда не выполняются, и поэтому деление на нуль не производится.

Все высказанные ранее идеи собраны вместе в подпрограмме clipSegmentO, приведенной в листинге 3.5. Концевые точки отрезков передаются по ссылке, поскольку изменения в концевых точках, сделанные подпрограммой clipSegmentO, должны быть явными для вызывающей программы. (Тип Point2 содержит двумерную точку, а тип RealRect - выровненный прямоугольник. Оба этих типа полностью описаны в разделе «Разработка класса Canvas».)


⇐ Предыдущая| |Следующая ⇒