Немного о машинных погрешностях...
Рассмотрим две линии атаки на рисунке: синюю (1) и красную (2). Оба отрезка пересекают окрестность шестой секции-башни в одной единственной точке, но в первом случае штраф отсутствует, а во втором - нет. В чём дело? Неправильный метод? Нет, в методе я уверен на 100%, иначе не стал бы его опубликовывать. Всё дело в машинных погрешностях. Угловой коэффициент синей линии атаки k1 = 2/3 = 0,(6) - периодическая дробь, которая, будучи помещена в четырёхбайтовую переменную, превращается в 0,66666668653... > 2/3. Далее, линия атаки не есть непрерывный отрезок. Чтобы не увязнуть в общих рассуждениях, рассмотрим отрезок №1. Длина проекции данного отрезка на ось абсцисс (6) больше его длины проекции на ось ординат (4). С шагом 0,1 по длине большей проекции игра строит "дискретную" линию атаки. Уравнение рассматриваемой линии y = 2/3 * x, где x принимает значения 0; 0,1; 0,2; ... Тогда y(2,9) = 0,66666668653... * 2,9 < 2, а в точке предполагаемого пересечения с окрестностью секции (синий квадрат) y(3) = 0,66666668653... * 3 > 2! (см. скриншот №1). Поэтому из-за машинных погрешностей реальная "дискретная" линия атаки не пересекает окрестность рассматриваемой секции.
Для тех, кто пропустил вышенаписанное, или читал, но не всё понял:
1) Если пересечением линии атаки с окрестностью секции является одна единственная точка, то секция НЕ блокирует линию атаки, если её угловой коэффициент - периодическая дробь (из-за машинных погрешностей).
На рисунке линия атаки (1) НЕ блокирована шестой секцией-башней несмотря на то, что линия пересекает секцию, т.к. угловой коэффициент этой линии k1 = 2/3 = 0,(6) - периодическая дробь. А вот линия атаки (2) блокирована этой же секцией (угловой коэффициент этой линии k2 = 1/2 = 0.5 - непериодическая дробь).
2) Если пересечение линии атаки и окрестности секции пусто (линии 3 и 4) или не состоит из одной единственной точки, то угловой коэффициент никакой роли не играет.
Извиняюсь, что уделяю внимание таким мелочам, которые на практике не встретятся 100%, но хочется изложить всё как можно строже, чтобы свести к минимуму недоразумения.
Описанный метод есть графическая интерпретация алгоритма, с помощью которого игра определяет, имеет ли стрелок штраф при стрельбе через крепостные стены. Возможно, что в третьей части реализован подобный алгоритм.
III Штрафы для стреляющих отрядов осаждающей стороны
Продолжение
Аналитические условия отсутствия штрафа при стрельбе через крепостные стены
Пусть координаты атакующего стрелка (Xa, Ya),
координаты атакуемого отряда противника, укрывшегося за крепостной стеной, (Xd, Yd),
Xd > Xa (иначе о штрафах говорить не приходится),
k = (Yd - Ya) / (Xd - Xa) - угловой коэффициент линии атаки.
(Если k - периодическая дробь, помним про машинную погрешность),
тогда секция (Xw, Yw) крепостной стены блокирует линию атаки стрелка, если выполняется хотя бы одно из следующих двух условий:
При 0 <= |k| <= 1 (угол стрельбы не больше 45 градусов):
1) Условие пересечения линии атаки с левой стороной окрестности секции:
Yd - Yw - 1 < k * (Xd - Xw) <= Yd - Yw;
2) Условие пересечения линии атаки с правой сторой окрестности секции:
Yd - Yw - 1 < k * (Xd - Xw - 1) < Yd - Yw.
Примечание: дополнительно, при k = -1, в силу особенности геометрии окрестности секции, секция блокирует линию атаки, если
Xd - Xw = Yw - Yd + 1.
При |k| > 1 (угол стрельбы больше 45 градусов):
1) Условие пересечения линии атаки с верхней стороной окрестности секции:
Xd - Xw - 1 < 1/k * (Yd - Yw) <= Xd - Xw;
2) Условие пересечения линии атаки с нижней сторой окрестности секции:
Xd - Xw - 1 < 1/k * (Yd - Yw - 1) < Xd - Xw.
В следующий раз я подробно опишу процесс разрушения катапультой крепостных стен (вероятность промаха, последовательность разрушения секций и т.п.)
Продолжение следует...