lbf/opt/
loss.rs

1use std::cmp::Ordering;
2
3use jagua_rs::geometry::primitives::{Rect, SPolygon};
4
5const X_MULTIPLIER: f32 = 10.0;
6
7/// The loss LBF assigned to a placing option.
8/// Weighted sum of the x_max and y_max of the shape, with the horizontal dimension being more important.
9/// <br>
10/// A pure lexicographic comparison (always prioritizing x-axis) would lead to undesirable results due to the continuous nature of the values.
11#[derive(Copy, Clone, Debug, PartialEq)]
12pub struct LBFLoss {
13    x_max: f32,
14    y_max: f32,
15}
16
17impl LBFLoss {
18    pub fn from_bbox(bbox: Rect) -> Self {
19        Self {
20            x_max: bbox.x_max,
21            y_max: bbox.y_max,
22        }
23    }
24
25    pub fn from_shape(shape: &SPolygon) -> Self {
26        LBFLoss::from_bbox(shape.bbox)
27    }
28
29    pub fn cost(&self) -> f32 {
30        self.x_max * X_MULTIPLIER + self.y_max
31    }
32
33    /// Tightens a sampling `Rect` to eliminate regions which would never have a lower loss than `self`.
34    pub fn tighten_sample_bbox(&self, sample_bbox: Rect) -> Rect {
35        let cost = self.cost();
36        let x_max_bound = cost / X_MULTIPLIER;
37
38        let mut tightened_bbox = sample_bbox;
39        tightened_bbox.x_max = f32::min(sample_bbox.x_max, x_max_bound);
40
41        tightened_bbox
42    }
43}
44
45impl PartialOrd for LBFLoss {
46    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
47        let self_cost = self.cost();
48        let other_cost = other.cost();
49
50        self_cost.partial_cmp(&other_cost)
51    }
52}