///|
fn target_distance(
target : HitTarget,
x : Double,
y : Double,
scale : Double,
) -> Double? {
match target.shape {
Point => {
let point = target.info.point
if !rect_contains(target.bounds, point.screen_x, point.screen_y) {
return None
}
let dx = (point.screen_x - x) * scale
let dy = (point.screen_y - y) * scale
if finite(dx) && finite(dy) {
Some(hit_distance(dx, dy))
} else {
None
}
}
Segment(x0, y0, x1, y1) =>
segment_distance(x0, y0, x1, y1, target.bounds, x, y).map(d => d * scale)
_ => None
}
}
///|
// An area covers earlier statistics, but it must not swallow later visible
// whiskers or outliers. A physical hit opens that overlay's selection; XNearest
// still chooses a real error-bar center, never a generated arm endpoint.
fn Drawing::statistical_overlay_hit(
self : Drawing,
area_index : Int32,
x : Double,
y : Double,
radius : Double,
scale : Double,
mode : HitMode,
) -> HitPoint? {
let mut best : HitPoint? = None
let mut best_distance = radius
let eligible_errors : Map[(Int32, Int32), Bool] = Map([])
for index in (area_index + 1).. radius || !finite(distance) {
continue
}
if mode == XNearest && target.info.kind == ErrorBar {
let identity = (point.panel_index, point.artist_index)
eligible_errors[identity] = true
} else if distance <= best_distance &&
(best is None || distance < best_distance) {
best = Some(point)
best_distance = distance
}
}
if best is Some(_) || mode == Nearest || eligible_errors.is_empty() {
return best
}
let mut best_dx = 0.0
let mut best_dy = 0.0
for index in (area_index + 1)..