Auto-translated
A bit about floating-point errors...
Let's consider two lines of attack in the figure: blue (1) and red (2). Both segments intersect the vicinity of the sixth tower section at a single point, but in the first case, there is no penalty, while in the second, there is. What's the reason? An incorrect method? No, I am 100% confident in the method, otherwise I wouldn't have published it. It's all about floating-point errors. The slope of the blue line of attack is k1 = 2/3 = 0.(6) — a recurring decimal, which, when placed in a four-byte variable, becomes 0.66666668653... > 2/3. Furthermore, the line of attack is not a continuous segment. To avoid getting bogged down in general reasoning, let's look at segment №1. The length of the projection of this segment onto the abscissa axis (6) is greater than the length of its projection onto the ordinate axis (4). With a step of 0.1 along the length of the larger projection, the game constructs a "discrete" line of attack. The equation of the line in question is y = 2/3 * x, where x takes the values 0; 0.1; 0.2; ... Then y(2.9) = 0.66666668653... * 2.9 < 2, and at the point of the assumed intersection with the vicinity of the section (blue square), y(3) = 0.66666668653... * 3 > 2! (see screenshot №1). Therefore, due to floating-point errors, the actual "discrete" line of attack does not intersect the vicinity of the section under consideration.
For those who missed the above, or read it but didn't fully understand:
1) If the intersection of the line of attack with the vicinity of the section is a single point, then the section DOES NOT block the line of attack if its slope is a recurring decimal (due to floating-point errors).
In the figure, the line of attack (1) is NOT blocked by the sixth tower section despite the fact that the line intersects the section, because the slope of this line k1 = 2/3 = 0.(6) is a recurring decimal. However, the line of attack (2) is blocked by the same section (the slope of this line k2 = 1/2 = 0.5 is a non-recurring decimal).
2) If the intersection of the line of attack and the vicinity of the section is empty (lines 3 and 4) or does not consist of a single point, then the slope plays no role.
I apologize for paying attention to such trifles, which will 100% not be encountered in practice, but I want to present everything as strictly as possible to minimize misunderstandings.
The described method is a graphical interpretation of the algorithm the game uses to determine whether a shooter incurs a penalty when firing through fortress walls. It is possible that a similar algorithm is implemented in the third part.
III Penalties for shooting units of the besieging side
Continuation
Analytical conditions for the absence of a penalty when firing through fortress walls
Let the coordinates of the attacking shooter be (Xa, Ya),
the coordinates of the attacked enemy unit hidden behind a fortress wall be (Xd, Yd),
Xd > Xa (otherwise, there is no need to discuss penalties),
k = (Yd - Ya) / (Xd - Xa) — the slope of the line of attack.
(If k is a recurring decimal, keep the floating-point error in mind),
then the section (Xw, Yw) of the fortress wall blocks the shooter's line of attack if at least one of the following two conditions is met:
When 0 <= |k| <= 1 (firing angle is not more than 45 degrees):
1) Condition for the line of attack to intersect the left side of the section's vicinity:
Yd - Yw - 1 < k * (Xd - Xw) <= Yd - Yw;
2) Condition for the line of attack to intersect the right side of the section's vicinity:
Yd - Yw - 1 < k * (Xd - Xw - 1) < Yd - Yw.
Note: additionally, when k = -1, due to the specific geometry of the section's vicinity, the section blocks the line of attack if
Xd - Xw = Yw - Yd + 1.
When |k| > 1 (firing angle is more than 45 degrees):
1) Condition for the line of attack to intersect the top side of the section's vicinity:
Xd - Xw - 1 < 1/k * (Yd - Yw) <= Xd - Xw;
2) Condition for the line of attack to intersect the bottom side of the section's vicinity:
Xd - Xw - 1 < 1/k * (Yd - Yw - 1) < Xd - Xw.
Next time, I will describe in detail the process of destroying fortress walls with a catapult (probability of a miss, sequence of section destruction, etc.)
To be continued...
Let's consider two lines of attack in the figure: blue (1) and red (2). Both segments intersect the vicinity of the sixth tower section at a single point, but in the first case, there is no penalty, while in the second, there is. What's the reason? An incorrect method? No, I am 100% confident in the method, otherwise I wouldn't have published it. It's all about floating-point errors. The slope of the blue line of attack is k1 = 2/3 = 0.(6) — a recurring decimal, which, when placed in a four-byte variable, becomes 0.66666668653... > 2/3. Furthermore, the line of attack is not a continuous segment. To avoid getting bogged down in general reasoning, let's look at segment №1. The length of the projection of this segment onto the abscissa axis (6) is greater than the length of its projection onto the ordinate axis (4). With a step of 0.1 along the length of the larger projection, the game constructs a "discrete" line of attack. The equation of the line in question is y = 2/3 * x, where x takes the values 0; 0.1; 0.2; ... Then y(2.9) = 0.66666668653... * 2.9 < 2, and at the point of the assumed intersection with the vicinity of the section (blue square), y(3) = 0.66666668653... * 3 > 2! (see screenshot №1). Therefore, due to floating-point errors, the actual "discrete" line of attack does not intersect the vicinity of the section under consideration.
For those who missed the above, or read it but didn't fully understand:
1) If the intersection of the line of attack with the vicinity of the section is a single point, then the section DOES NOT block the line of attack if its slope is a recurring decimal (due to floating-point errors).
In the figure, the line of attack (1) is NOT blocked by the sixth tower section despite the fact that the line intersects the section, because the slope of this line k1 = 2/3 = 0.(6) is a recurring decimal. However, the line of attack (2) is blocked by the same section (the slope of this line k2 = 1/2 = 0.5 is a non-recurring decimal).
2) If the intersection of the line of attack and the vicinity of the section is empty (lines 3 and 4) or does not consist of a single point, then the slope plays no role.
I apologize for paying attention to such trifles, which will 100% not be encountered in practice, but I want to present everything as strictly as possible to minimize misunderstandings.
The described method is a graphical interpretation of the algorithm the game uses to determine whether a shooter incurs a penalty when firing through fortress walls. It is possible that a similar algorithm is implemented in the third part.
III Penalties for shooting units of the besieging side
Continuation
Analytical conditions for the absence of a penalty when firing through fortress walls
Let the coordinates of the attacking shooter be (Xa, Ya),
the coordinates of the attacked enemy unit hidden behind a fortress wall be (Xd, Yd),
Xd > Xa (otherwise, there is no need to discuss penalties),
k = (Yd - Ya) / (Xd - Xa) — the slope of the line of attack.
(If k is a recurring decimal, keep the floating-point error in mind),
then the section (Xw, Yw) of the fortress wall blocks the shooter's line of attack if at least one of the following two conditions is met:
When 0 <= |k| <= 1 (firing angle is not more than 45 degrees):
1) Condition for the line of attack to intersect the left side of the section's vicinity:
Yd - Yw - 1 < k * (Xd - Xw) <= Yd - Yw;
2) Condition for the line of attack to intersect the right side of the section's vicinity:
Yd - Yw - 1 < k * (Xd - Xw - 1) < Yd - Yw.
Note: additionally, when k = -1, due to the specific geometry of the section's vicinity, the section blocks the line of attack if
Xd - Xw = Yw - Yd + 1.
When |k| > 1 (firing angle is more than 45 degrees):
1) Condition for the line of attack to intersect the top side of the section's vicinity:
Xd - Xw - 1 < 1/k * (Yd - Yw) <= Xd - Xw;
2) Condition for the line of attack to intersect the bottom side of the section's vicinity:
Xd - Xw - 1 < 1/k * (Yd - Yw - 1) < Xd - Xw.
Next time, I will describe in detail the process of destroying fortress walls with a catapult (probability of a miss, sequence of section destruction, etc.)
To be continued...