re_components/
rect.rs

1#![allow(clippy::upper_case_acronyms)]
2
3use arrow2_convert::{ArrowDeserialize, ArrowField, ArrowSerialize};
4
5use super::Vec4D;
6
7/// A rectangle in 2D space.
8///
9/// ## Example
10/// ```
11/// # use re_components::{Rect2D, Vec4D};
12/// # use arrow2_convert::field::ArrowField;
13/// # use arrow2::datatypes::{DataType, Field, UnionMode};
14/// assert_eq!(
15///     Rect2D::data_type(),
16///     DataType::Union(vec![
17///         Field::new("XYWH", Vec4D::data_type(), false),
18///         Field::new("YXHW", Vec4D::data_type(), false),
19///         Field::new("XYXY", Vec4D::data_type(), false),
20///         Field::new("YXYX", Vec4D::data_type(), false),
21///         Field::new("XCYCWH", Vec4D::data_type(), false),
22///         Field::new("XCYCW2H2", Vec4D::data_type(), false),
23///     ], None, UnionMode::Dense)
24/// );
25/// ```
26#[derive(Clone, Debug, ArrowField, ArrowSerialize, ArrowDeserialize, PartialEq)]
27#[arrow_field(type = "dense")]
28pub enum Rect2D {
29    /// \[x, y, w, h\], with x,y = left,top.
30    XYWH(Vec4D),
31
32    /// \[y, x, h, w\], with x,y = left,top.
33    YXHW(Vec4D),
34
35    /// \[x0, y0, x1, y1\], with x0,y0 = left,top and x1,y1 = right,bottom
36    XYXY(Vec4D),
37
38    /// \[y0, x0, y1, x1\], with x0,y0 = left,top and x1,y1 = right,bottom
39    YXYX(Vec4D),
40
41    /// \[x_center, y_center, width, height\]
42    XCYCWH(Vec4D),
43
44    /// \[x_center, y_center, width/2, height/2\]
45    XCYCW2H2(Vec4D),
46}
47
48impl Rect2D {
49    #[inline]
50    pub fn from_xywh(x: f32, y: f32, w: f32, h: f32) -> Self {
51        Self::XYWH(Vec4D([x, y, w, h]))
52    }
53
54    pub fn top_left_corner(&self) -> [f32; 2] {
55        match self {
56            Rect2D::XYWH(Vec4D([x, y, _, _])) => [*x, *y],
57            Rect2D::YXHW(Vec4D([y, x, _h, _w])) => [*x, *y],
58            Rect2D::XYXY(Vec4D([x0, y0, _x1, _y1])) => [*x0, *y0],
59            Rect2D::YXYX(Vec4D([y0, x0, _y1, _x1])) => [*x0, *y0],
60            Rect2D::XCYCWH(Vec4D([x_cen, y_cen, w, h])) => [x_cen - (w / 2.0), y_cen - (h / 2.0)],
61            Rect2D::XCYCW2H2(Vec4D([x_cen, y_cen, w_2, h_2])) => [x_cen - w_2, y_cen - h_2],
62        }
63    }
64
65    pub fn width(&self) -> f32 {
66        match self {
67            Rect2D::XYWH(Vec4D([_x, _y, w, _h])) => *w,
68            Rect2D::YXHW(Vec4D([_y, _x, _h, w])) => *w,
69            Rect2D::XYXY(Vec4D([x0, _y0, x1, _y1])) => x1 - x0,
70            Rect2D::YXYX(Vec4D([_y0, x0, _y1, x1])) => x1 - x0,
71            Rect2D::XCYCWH(Vec4D([_x_cen, _y_cen, w, _h])) => *w,
72            Rect2D::XCYCW2H2(Vec4D([_x_cen, _y_cen, w_2, _h_2])) => 2.0 * w_2,
73        }
74    }
75
76    pub fn height(&self) -> f32 {
77        match self {
78            Rect2D::XYWH(Vec4D([_x, _y, _w, h])) => *h,
79            Rect2D::YXHW(Vec4D([_y, _x, h, _w])) => *h,
80            Rect2D::XYXY(Vec4D([_x0, y0, _x1, y1])) => y1 - y0,
81            Rect2D::YXYX(Vec4D([y0, _x0, y1, _x1])) => y1 - y0,
82            Rect2D::XCYCWH(Vec4D([_x_cen, _y_cen, _w, h])) => *h,
83            Rect2D::XCYCW2H2(Vec4D([_x_cen, _y_cen, _w_2, h_2])) => 2.0 * h_2,
84        }
85    }
86}
87
88impl re_log_types::LegacyComponent for Rect2D {
89    #[inline]
90    fn legacy_name() -> re_log_types::ComponentName {
91        "rerun.rect2d".into()
92    }
93}
94
95re_log_types::component_legacy_shim!(Rect2D);