# Is a removal plan within the bounds and below the standard everywhere?
is_feasible(r) = all(from_stack * r .>= required .- 1e-6) &&
all(-1e-9 .<= r .<= 1 + 1e-9)
# Every boundary as (a1, a2, rhs) for a1 R1 + a2 R2 = rhs:
# the receptor constraints C1 to C3, then the four bounds
boundaries = [[(from_stack[j, 1], from_stack[j, 2], required[j]) for j in 1:n_receptors];
[(1, 0, 0), (1, 0, 1), (0, 1, 0), (0, 1, 1)]]
function crossing(l1, l2)
determinant = l1[1] * l2[2] - l1[2] * l2[1]
if abs(determinant) < 1e-9
return [NaN, NaN] # parallel boundaries never meet
end
return [(l1[3] * l2[2] - l1[2] * l2[3]) / determinant,
(l1[1] * l2[3] - l1[3] * l2[1]) / determinant]
end
# Corners: crossings of two boundaries that satisfy every constraint
n_boundaries = length(boundaries)
crossings = [crossing(boundaries[i], boundaries[k]) for i in 1:n_boundaries for k in (i+1):n_boundaries]
corners = unique(p -> round.(p; digits=6), filter(p -> !any(isnan, p) && is_feasible(p), crossings))
centre = sum(corners) / length(corners)
corners = sort(corners, by=p -> atan(p[2] - centre[2], p[1] - centre[1]))
line_style = [:solid, :dash, :dashdot]
function draw_region(r1_max=1.04)
p = plot(Shape(first.(corners), last.(corners)), color=cb_blue, alpha=0.25,
linewidth=0, xlims=(0.5, r1_max), ylims=(0.375, 1.05), xlabel=L"R_1",
ylabel=L"R_2")
for j in 1:n_receptors
a1, a2, rhs = boundaries[j]
# Label each line at a point where it is inside the axes
if abs(a2) < 1e-3
vline!(p, [rhs / a1], color=:gray30, linestyle=line_style[j], linewidth=2.5)
label_at = (rhs / a1 - 0.028, 0.425)
else
r1 = 0.5:0.01:r1_max
plot!(p, r1, (rhs .- a1 .* r1) ./ a2, color=:gray30, linestyle=line_style[j],
linewidth=2.5)
r1_at_09 = (rhs - a2 * 0.9) / a1
label_at = 0.54 <= r1_at_09 <= 0.96 ? (r1_at_09 + 0.048, 0.915) : (0.54, (rhs - a1 * 0.54) / a2 + 0.065)
end
annotate!(p, label_at..., text("C$(j)", 20, :gray20, plot_font))
end
plot!(p, [0, 1, 1], [1, 1, 0], color=:black, linewidth=2)
return p
end
p_region = draw_region()
plot!(p_region, size=(900, 380), left_margin=12mm, bottom_margin=12mm)