linalg.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2026 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use async_trait::async_trait;
  19. use darkfi_serial::{SerialDecodable, SerialEncodable};
  20. use std::ops::{Add, AddAssign, Div, DivAssign, Mul, Sub, SubAssign};
  21. #[derive(Clone, Copy, Debug, SerialEncodable, SerialDecodable)]
  22. pub struct Dimension {
  23. pub w: f32,
  24. pub h: f32,
  25. }
  26. impl Dimension {
  27. pub fn contains(&self, other: &Dimension) -> bool {
  28. other.w <= self.w && other.h <= self.h
  29. }
  30. }
  31. impl From<[f32; 2]> for Dimension {
  32. fn from(dim: [f32; 2]) -> Self {
  33. Self { w: dim[0], h: dim[1] }
  34. }
  35. }
  36. impl Mul<f32> for Dimension {
  37. type Output = Dimension;
  38. fn mul(self, scale: f32) -> Self::Output {
  39. Self { w: self.w * scale, h: self.h * scale }
  40. }
  41. }
  42. impl Div<f32> for Dimension {
  43. type Output = Dimension;
  44. fn div(self, scale: f32) -> Self::Output {
  45. Self { w: self.w / scale, h: self.h / scale }
  46. }
  47. }
  48. #[derive(Clone, Copy, Default, PartialEq, SerialEncodable, SerialDecodable)]
  49. pub struct Point {
  50. pub x: f32,
  51. pub y: f32,
  52. }
  53. impl Point {
  54. pub const fn new(x: f32, y: f32) -> Self {
  55. Self { x, y }
  56. }
  57. pub fn zero() -> Self {
  58. Self { x: 0., y: 0. }
  59. }
  60. pub fn unpack(&self) -> (f32, f32) {
  61. (self.x, self.y)
  62. }
  63. pub fn as_arr(&self) -> [f32; 2] {
  64. [self.x, self.y]
  65. }
  66. pub fn offset(&self, off_x: f32, off_y: f32) -> Self {
  67. Self { x: self.x + off_x, y: self.y + off_y }
  68. }
  69. pub fn to_rect(&self, w: f32, h: f32) -> Rectangle {
  70. Rectangle { x: self.x, y: self.y, w, h }
  71. }
  72. pub fn dist_sq(&self, other: Point) -> f32 {
  73. (self.x - other.x).powi(2) + (self.y - other.y).powi(2)
  74. }
  75. pub fn dist(&self, other: Point) -> f32 {
  76. self.dist_sq(other).sqrt()
  77. }
  78. pub fn normalize(&mut self) {
  79. let scale = self.dist(Point::zero());
  80. self.x /= scale;
  81. self.y /= scale;
  82. assert!((self.dist(Point::zero()) - 1.) < f32::EPSILON);
  83. }
  84. /// Counterclockwise perp vector (with -y up)
  85. pub fn perp_left(&self) -> Point {
  86. Point::new(self.y, -self.x)
  87. }
  88. /// Clockwise perp vector (with +y down)
  89. pub fn perp_right(&self) -> Point {
  90. Point::new(-self.y, self.x)
  91. }
  92. }
  93. impl From<[f32; 2]> for Point {
  94. fn from(pos: [f32; 2]) -> Self {
  95. Self { x: pos[0], y: pos[1] }
  96. }
  97. }
  98. impl std::fmt::Debug for Point {
  99. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  100. write!(f, "({}, {})", self.x, self.y)
  101. }
  102. }
  103. impl Add for Point {
  104. type Output = Self;
  105. fn add(self, other: Self) -> Self::Output {
  106. Self { x: self.x + other.x, y: self.y + other.y }
  107. }
  108. }
  109. impl Sub for Point {
  110. type Output = Self;
  111. fn sub(self, other: Self) -> Self::Output {
  112. Self { x: self.x - other.x, y: self.y - other.y }
  113. }
  114. }
  115. impl AddAssign for Point {
  116. fn add_assign(&mut self, other: Self) {
  117. *self = Self { x: self.x + other.x, y: self.y + other.y };
  118. }
  119. }
  120. impl SubAssign for Point {
  121. fn sub_assign(&mut self, other: Self) {
  122. *self = Self { x: self.x - other.x, y: self.y - other.y };
  123. }
  124. }
  125. impl Mul<f32> for Point {
  126. type Output = Self;
  127. fn mul(self, scale: f32) -> Self {
  128. Point::new(scale * self.x, scale * self.y)
  129. }
  130. }
  131. impl Div<f32> for Point {
  132. type Output = Self;
  133. fn div(self, div: f32) -> Self {
  134. Point::new(self.x / div, self.y / div)
  135. }
  136. }
  137. #[derive(Clone, Copy, PartialEq, SerialEncodable, SerialDecodable)]
  138. pub struct Rectangle {
  139. pub x: f32,
  140. pub y: f32,
  141. pub w: f32,
  142. pub h: f32,
  143. }
  144. /// Accumulates the union of many rectangles. Starts empty; `get()` returns
  145. /// `None` until something has been added.
  146. #[derive(Clone, Copy)]
  147. pub struct RectangleUnion {
  148. bounds: Option<Rectangle>,
  149. }
  150. impl RectangleUnion {
  151. pub fn new() -> Self {
  152. Self { bounds: None }
  153. }
  154. pub fn add(&mut self, rect: Rectangle) {
  155. self.bounds = Some(match self.bounds {
  156. Some(bounds) => bounds.union(&rect),
  157. None => rect,
  158. });
  159. }
  160. /// Fold another union into this one
  161. pub fn join(&mut self, other: Self) {
  162. if let Some(rect) = other.bounds {
  163. self.add(rect);
  164. }
  165. }
  166. /// The union of everything added so far, or `None` if empty
  167. pub fn get(&self) -> Option<Rectangle> {
  168. self.bounds
  169. }
  170. }
  171. impl Default for RectangleUnion {
  172. fn default() -> Self {
  173. Self::new()
  174. }
  175. }
  176. impl Rectangle {
  177. pub const fn new(x: f32, y: f32, w: f32, h: f32) -> Self {
  178. Self { x, y, w, h }
  179. }
  180. pub fn zero() -> Self {
  181. Self { x: 0., y: 0., w: 0., h: 0. }
  182. }
  183. /// Use from() instead
  184. #[deprecated]
  185. pub fn from_array(arr: [f32; 4]) -> Self {
  186. Self { x: arr[0], y: arr[1], w: arr[2], h: arr[3] }
  187. }
  188. pub fn clip(&self, other: &Self) -> Option<Self> {
  189. if other.x + other.w < self.x ||
  190. other.x > self.x + self.w ||
  191. other.y + other.h < self.y ||
  192. other.y > self.y + self.h
  193. {
  194. return None
  195. }
  196. let mut clipped = other.clone();
  197. if clipped.x < self.x {
  198. clipped.x = self.x;
  199. clipped.w = other.x + other.w - clipped.x;
  200. }
  201. if clipped.y < self.y {
  202. clipped.y = self.y;
  203. clipped.h = other.y + other.h - clipped.y;
  204. }
  205. if clipped.x + clipped.w > self.x + self.w {
  206. clipped.w = self.x + self.w - clipped.x;
  207. }
  208. if clipped.y + clipped.h > self.y + self.h {
  209. clipped.h = self.y + self.h - clipped.y;
  210. }
  211. Some(clipped)
  212. }
  213. /// Smallest rectangle covering both `self` and `other`
  214. pub fn union(&self, other: &Self) -> Self {
  215. let x1 = self.x.min(other.x);
  216. let y1 = self.y.min(other.y);
  217. let x2 = (self.x + self.w).max(other.x + other.w);
  218. let y2 = (self.y + self.h).max(other.y + other.h);
  219. Self::new(x1, y1, x2 - x1, y2 - y1)
  220. }
  221. pub fn with_zero_pos(&self) -> Self {
  222. Self::new(0., 0., self.w, self.h)
  223. }
  224. pub fn clip_point(&self, mut point: Point) -> Point {
  225. if point.x < self.x {
  226. point.x = self.x;
  227. }
  228. if point.y < self.y {
  229. point.y = self.y;
  230. }
  231. if point.x > self.x + self.w {
  232. point.x = self.x + self.w;
  233. }
  234. if point.y > self.y + self.h {
  235. point.y = self.y + self.h;
  236. }
  237. point
  238. }
  239. pub fn contains(&self, point: Point) -> bool {
  240. self.x <= point.x &&
  241. point.x <= self.x + self.w &&
  242. self.y <= point.y &&
  243. point.y <= self.y + self.h
  244. }
  245. pub fn rhs(&self) -> f32 {
  246. self.x + self.w
  247. }
  248. pub fn bhs(&self) -> f32 {
  249. self.y + self.h
  250. }
  251. pub fn pos(&self) -> Point {
  252. Point { x: self.x, y: self.y }
  253. }
  254. pub fn corner(&self) -> Point {
  255. Point { x: self.x + self.w, y: self.y + self.h }
  256. }
  257. pub fn center(&self) -> Point {
  258. Point { x: self.x + self.w / 2., y: self.y + self.h / 2. }
  259. }
  260. pub fn top_right(&self) -> Point {
  261. Point { x: self.rhs(), y: self.y }
  262. }
  263. pub fn bot_left(&self) -> Point {
  264. Point { x: self.x, y: self.y + self.h }
  265. }
  266. pub fn dim(&self) -> Dimension {
  267. Dimension { w: self.w, h: self.h }
  268. }
  269. #[deprecated]
  270. pub fn top_left(&self) -> Point {
  271. Point { x: self.x, y: self.y }
  272. }
  273. #[deprecated]
  274. pub fn bottom_right(&self) -> Point {
  275. Point { x: self.x + self.w, y: self.y + self.h }
  276. }
  277. pub fn includes(&self, child: &Self) -> bool {
  278. self.contains(child.pos()) && self.contains(child.corner())
  279. }
  280. }
  281. impl From<[f32; 4]> for Rectangle {
  282. fn from(rect: [f32; 4]) -> Self {
  283. Self { x: rect[0], y: rect[1], w: rect[2], h: rect[3] }
  284. }
  285. }
  286. impl Add<Point> for Rectangle {
  287. type Output = Rectangle;
  288. fn add(self, other: Point) -> Self::Output {
  289. Self { x: self.x + other.x, y: self.y + other.y, w: self.w, h: self.h }
  290. }
  291. }
  292. impl Sub<Point> for Rectangle {
  293. type Output = Rectangle;
  294. fn sub(self, other: Point) -> Self::Output {
  295. Self { x: self.x - other.x, y: self.y - other.y, w: self.w, h: self.h }
  296. }
  297. }
  298. impl Mul<f32> for Rectangle {
  299. type Output = Rectangle;
  300. fn mul(self, scale: f32) -> Self::Output {
  301. Self { x: self.x * scale, y: self.y * scale, w: self.w * scale, h: self.h * scale }
  302. }
  303. }
  304. impl Div<f32> for Rectangle {
  305. type Output = Rectangle;
  306. fn div(self, scale: f32) -> Self::Output {
  307. Self { x: self.x / scale, y: self.y / scale, w: self.w / scale, h: self.h / scale }
  308. }
  309. }
  310. impl DivAssign<f32> for Rectangle {
  311. fn div_assign(&mut self, scale: f32) {
  312. self.x /= scale;
  313. self.y /= scale;
  314. self.w /= scale;
  315. self.h /= scale;
  316. }
  317. }
  318. impl std::fmt::Debug for Rectangle {
  319. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  320. write!(f, "({}, {}, {}, {})", self.x, self.y, self.w, self.h)
  321. }
  322. }
  323. impl From<parley::BoundingBox> for Rectangle {
  324. fn from(rect: parley::BoundingBox) -> Self {
  325. Self::new(rect.x0 as f32, rect.y0 as f32, rect.width() as f32, rect.height() as f32)
  326. }
  327. }
  328. #[derive(Debug, Clone, Copy)]
  329. pub struct Segment {
  330. pub start: Point,
  331. pub end: Point,
  332. }
  333. #[derive(Debug, Clone, Copy, PartialEq)]
  334. pub struct Vector {
  335. pub x: f32,
  336. pub y: f32,
  337. }
  338. impl Vector {
  339. pub fn mag(&self) -> f32 {
  340. (self.x * self.x + self.y * self.y).sqrt()
  341. }
  342. }
  343. impl From<Point> for Vector {
  344. fn from(point: Point) -> Self {
  345. Vector { x: point.x, y: point.y }
  346. }
  347. }