graphviz_pure_core/
geom.rs1use crate::math;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize)]
6pub struct Point {
7 pub x: f64,
8 pub y: f64,
9}
10
11impl Point {
12 #[inline]
13 pub const fn new(x: f64, y: f64) -> Self {
14 Self { x, y }
15 }
16
17 #[inline]
18 pub fn dist(self, other: Self) -> f64 {
19 math::hypot(self.x - other.x, self.y - other.y)
20 }
21
22 #[inline]
24 pub fn normalized_or_zero(self) -> Self {
25 let len = math::hypot(self.x, self.y);
26 if len <= 1e-12 {
27 Self::new(0.0, 0.0)
28 } else {
29 Self::new(self.x / len, self.y / len)
30 }
31 }
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Default, Serialize, Deserialize)]
36pub struct BoundingBox {
37 pub ll: Point,
38 pub ur: Point,
39}
40
41impl BoundingBox {
42 #[inline]
43 pub const fn new(llx: f64, lly: f64, urx: f64, ury: f64) -> Self {
44 Self {
45 ll: Point::new(llx, lly),
46 ur: Point::new(urx, ury),
47 }
48 }
49
50 #[inline]
51 pub fn width(&self) -> f64 {
52 (self.ur.x - self.ll.x).max(0.0)
53 }
54
55 #[inline]
56 pub fn height(&self) -> f64 {
57 (self.ur.y - self.ll.y).max(0.0)
58 }
59
60 #[inline]
61 pub fn expand_to_include(&mut self, pt: Point) {
62 if pt.x < self.ll.x {
63 self.ll.x = pt.x;
64 }
65 if pt.y < self.ll.y {
66 self.ll.y = pt.y;
67 }
68 if pt.x > self.ur.x {
69 self.ur.x = pt.x;
70 }
71 if pt.y > self.ur.y {
72 self.ur.y = pt.y;
73 }
74 }
75}
76
77#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
79pub struct BezierSegment {
80 pub points: Vec<Point>,
82 pub start_arrow: Option<Point>,
83 pub end_arrow: Option<Point>,
84}
85
86#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
87pub struct Spline {
88 pub segments: Vec<BezierSegment>,
89}