1pub mod transform {
3 mod rotate;
4 mod scale;
5 mod shift;
6
7 pub use rotate::*;
8 pub use scale::*;
9 pub use shift::*;
10}
11pub use transform::*;
12
13pub use crate::anchor::{Aabb, AabbPoint, Locate};
14
15use std::ops::Range;
16
17use color::{AlphaColor, ColorSpace, OpaqueColor, Srgb};
18use glam::{
19 DAffine2, DAffine3, DMat4, DQuat, DVec2, DVec3, Mat4, USizeVec3, Vec3, Vec3Swizzles, dvec3,
20};
21use num::complex::Complex64;
22
23use crate::{components::width::Width, utils::resize_preserving_order_with_repeated_indices};
24
25pub trait With {
39 fn with(mut self, f: impl Fn(&mut Self)) -> Self
41 where
42 Self: Sized,
43 {
44 f(&mut self);
45 self
46 }
47}
48
49impl<T> With for T {}
50
51pub trait Discard {
63 fn discard(&self) {}
65}
66
67impl<T> Discard for T {}
68
69pub trait Interpolatable {
74 fn lerp(&self, target: &Self, t: f64) -> Self;
76}
77
78impl Interpolatable for usize {
79 fn lerp(&self, target: &Self, t: f64) -> Self {
80 (*self as f32).lerp(&(*target as f32), t) as usize
81 }
82}
83
84impl Interpolatable for f32 {
85 fn lerp(&self, target: &Self, t: f64) -> Self {
86 self + (target - self) * t as f32
87 }
88}
89
90impl Interpolatable for f64 {
91 fn lerp(&self, target: &Self, t: f64) -> Self {
92 self + (target - self) * t
93 }
94}
95
96impl Interpolatable for DVec3 {
97 fn lerp(&self, target: &Self, t: f64) -> Self {
98 self + (target - self) * t
99 }
100}
101
102impl Interpolatable for Vec3 {
103 fn lerp(&self, target: &Self, t: f64) -> Self {
104 self + (target - self) * t as f32
105 }
106}
107
108impl Interpolatable for DVec2 {
109 fn lerp(&self, target: &Self, t: f64) -> Self {
110 self + (target - self) * t
111 }
112}
113
114impl Interpolatable for DQuat {
115 fn lerp(&self, target: &Self, t: f64) -> Self {
116 self.slerp(*target, t)
117 }
118}
119
120impl<CS: ColorSpace> Interpolatable for AlphaColor<CS> {
121 fn lerp(&self, target: &Self, t: f64) -> Self {
122 AlphaColor::lerp_rect(*self, *target, t as f32)
124 }
125}
126
127impl<CS: ColorSpace> Interpolatable for OpaqueColor<CS> {
128 fn lerp(&self, target: &Self, t: f64) -> Self {
129 OpaqueColor::lerp_rect(*self, *target, t as f32)
131 }
132}
133
134impl Interpolatable for DMat4 {
135 fn lerp(&self, target: &Self, t: f64) -> Self {
136 let mut result = DMat4::ZERO;
137 for i in 0..4 {
138 for j in 0..4 {
139 result.col_mut(i)[j] = self.col(i)[j].lerp(&target.col(i)[j], t);
140 }
141 }
142 result
143 }
144}
145
146impl Interpolatable for Mat4 {
147 fn lerp(&self, other: &Self, t: f64) -> Self {
148 let t = t as f32;
149 let mut result = Mat4::ZERO;
150 for i in 0..4 {
151 for j in 0..4 {
152 result.col_mut(i)[j] = self.col(i)[j] + (other.col(i)[j] - self.col(i)[j]) * t;
153 }
154 }
155 result
156 }
157}
158
159impl<T: Interpolatable> Interpolatable for Vec<T> {
160 fn lerp(&self, target: &Self, t: f64) -> Self {
161 self.iter().zip(target).map(|(a, b)| a.lerp(b, t)).collect()
162 }
163}
164
165impl<T: Interpolatable, const N: usize> Interpolatable for [T; N] {
166 fn lerp(&self, target: &Self, t: f64) -> Self {
167 core::array::from_fn(|i| self[i].lerp(&target[i], t))
168 }
169}
170
171macro_rules! impl_interpolatable_tuple {
172 ($(($T:ident, $s:ident)),*) => {
173 impl<$($T: Interpolatable),*> Interpolatable for ($($T,)*) {
174 #[allow(non_snake_case)]
175 fn lerp(&self, target: &Self, t: f64) -> Self {
176 let ($($s,)*) = self;
177 let ($($T,)*) = target;
178 ($($s.lerp($T, t),)*)
179 }
180 }
181 }
182}
183variadics_please::all_tuples!(impl_interpolatable_tuple, 1, 12, T, S);
184
185impl<T: Opacity + Alignable + Clone> Alignable for Vec<T> {
186 fn is_aligned(&self, other: &Self) -> bool {
187 self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a.is_aligned(b))
188 }
189 fn align_with(&mut self, other: &mut Self) {
190 let len = self.len().max(other.len());
191
192 let transparent_repeated = |items: &mut Vec<T>, repeat_idxs: Vec<usize>| {
193 for idx in repeat_idxs {
194 items[idx].set_opacity(0.0);
195 }
196 };
197 if self.len() != len {
198 let (mut items, idxs) = resize_preserving_order_with_repeated_indices(self, len);
199 transparent_repeated(&mut items, idxs);
200 *self = items;
201 }
202 if other.len() != len {
203 let (mut items, idxs) = resize_preserving_order_with_repeated_indices(other, len);
204 transparent_repeated(&mut items, idxs);
205 *other = items;
206 }
207 self.iter_mut()
208 .zip(other)
209 .for_each(|(a, b)| a.align_with(b));
210 }
211}
212
213pub trait Alignable: Clone {
221 fn is_aligned(&self, other: &Self) -> bool;
223 fn align_with(&mut self, other: &mut Self);
225}
226
227impl Alignable for DVec3 {
228 fn align_with(&mut self, _other: &mut Self) {}
229 fn is_aligned(&self, _other: &Self) -> bool {
230 true
231 }
232}
233
234pub trait Opacity {
237 fn set_opacity(&mut self, opacity: f32) -> &mut Self;
239}
240
241impl<T: Opacity, I> Opacity for I
242where
243 for<'a> &'a mut I: IntoIterator<Item = &'a mut T>,
244{
245 fn set_opacity(&mut self, opacity: f32) -> &mut Self {
246 self.into_iter().for_each(|x: &mut T| {
247 x.set_opacity(opacity);
248 });
249 self
250 }
251}
252
253pub trait Partial {
256 fn get_partial(&self, range: Range<f64>) -> Self;
258 fn get_partial_closed(&self, range: Range<f64>) -> Self;
260}
261
262pub trait Empty {
265 fn empty() -> Self;
267}
268
269pub trait FillColor {
272 fn fill_color(&self) -> AlphaColor<Srgb>;
274 fn set_fill_opacity(&mut self, opacity: f32) -> &mut Self;
276 fn set_fill_color(&mut self, color: AlphaColor<Srgb>) -> &mut Self;
278}
279
280impl<T: FillColor> FillColor for [T] {
281 fn fill_color(&self) -> color::AlphaColor<color::Srgb> {
282 self[0].fill_color()
283 }
284 fn set_fill_color(&mut self, color: color::AlphaColor<color::Srgb>) -> &mut Self {
285 self.iter_mut()
286 .for_each(|x| x.set_fill_color(color).discard());
287 self
288 }
289 fn set_fill_opacity(&mut self, opacity: f32) -> &mut Self {
290 self.iter_mut()
291 .for_each(|x| x.set_fill_opacity(opacity).discard());
292 self
293 }
294}
295
296pub trait StrokeColor {
299 fn stroke_color(&self) -> AlphaColor<Srgb>;
301 fn set_stroke_opacity(&mut self, opacity: f32) -> &mut Self;
303 fn set_stroke_color(&mut self, color: AlphaColor<Srgb>) -> &mut Self;
305}
306
307impl<T: StrokeColor> StrokeColor for [T] {
308 fn stroke_color(&self) -> AlphaColor<Srgb> {
309 self[0].stroke_color()
310 }
311 fn set_stroke_color(&mut self, color: color::AlphaColor<color::Srgb>) -> &mut Self {
312 self.iter_mut().for_each(|x| {
313 x.set_stroke_color(color);
314 });
315 self
316 }
317 fn set_stroke_opacity(&mut self, opacity: f32) -> &mut Self {
318 self.iter_mut().for_each(|x| {
319 x.set_stroke_opacity(opacity);
320 });
321 self
322 }
323}
324
325pub trait StrokeWidth {
328 fn stroke_width(&self) -> f32;
331 fn apply_stroke_func(&mut self, f: impl for<'a> Fn(&'a mut [Width])) -> &mut Self;
333 fn set_stroke_width(&mut self, width: f32) -> &mut Self {
335 self.apply_stroke_func(|widths| widths.fill(width.into()))
336 }
337}
338
339impl<T: StrokeWidth> StrokeWidth for [T] {
340 fn stroke_width(&self) -> f32 {
341 self[0].stroke_width()
342 }
343 fn apply_stroke_func(
344 &mut self,
345 f: impl for<'a> Fn(&'a mut [crate::components::width::Width]),
346 ) -> &mut Self {
347 self.iter_mut().for_each(|x| {
348 x.apply_stroke_func(&f);
349 });
350 self
351 }
352}
353
354pub trait Color: FillColor + StrokeColor {
359 fn set_color(&mut self, color: AlphaColor<Srgb>) -> &mut Self {
361 self.set_fill_color(color);
362 self.set_stroke_color(color);
363 self
364 }
365}
366
367impl<T: FillColor + StrokeColor + ?Sized> Color for T {}
368
369pub trait PointsFunc {
372 fn apply_points_func(&mut self, f: impl for<'a> Fn(&'a mut [DVec3])) -> &mut Self;
374
375 fn apply_affine2(&mut self, affine: DAffine2) -> &mut Self {
377 self.apply_point_func(|p| {
378 let transformed = affine.transform_point2(p.xy());
379 p.x = transformed.x;
380 p.y = transformed.y;
381 });
382 self
383 }
384
385 fn apply_affine3(&mut self, affine: DAffine3) -> &mut Self {
387 self.apply_point_func(|p| *p = affine.transform_point3(*p));
388 self
389 }
390
391 fn apply_point_func(&mut self, f: impl Fn(&mut DVec3)) -> &mut Self {
393 self.apply_points_func(|points| {
394 points.iter_mut().for_each(&f);
395 });
396 self
397 }
398 fn apply_point_map(&mut self, f: impl Fn(DVec3) -> DVec3) -> &mut Self {
400 self.apply_points_func(|points| {
401 points.iter_mut().for_each(|p| *p = f(*p));
402 });
403 self
404 }
405
406 fn apply_complex_func(&mut self, f: impl Fn(&mut Complex64)) -> &mut Self {
410 self.apply_point_func(|p| {
411 let mut c = Complex64::new(p.x, p.y);
412 f(&mut c);
413 p.x = c.re;
414 p.y = c.im;
415 });
416 self
417 }
418 fn apply_complex_map(&mut self, f: impl Fn(Complex64) -> Complex64) -> &mut Self {
422 self.apply_complex_func(|p| {
423 *p = f(*p);
424 });
425 self
426 }
427}
428
429impl PointsFunc for DVec3 {
430 fn apply_points_func(&mut self, f: impl for<'a> Fn(&'a mut [DVec3])) -> &mut Self {
431 f(std::slice::from_mut(self));
432 self
433 }
434}
435
436impl<T: PointsFunc> PointsFunc for [T] {
437 fn apply_points_func(&mut self, f: impl for<'a> Fn(&'a mut [DVec3])) -> &mut Self {
438 self.iter_mut()
439 .for_each(|x| x.apply_points_func(&f).discard());
440 self
441 }
442}
443
444pub trait AlignSlice<T: transform::ShiftTransformExt>: AsMut<[T]> {
447 fn align_anchor<A>(&mut self, axis: DVec3, anchor: A) -> &mut Self
449 where
450 A: Locate<T> + Clone,
451 {
452 let Some(dir) = axis.try_normalize() else {
453 return self;
454 };
455 let Some(point) = self.as_mut().first().map(|x| anchor.locate(x)) else {
456 return self;
457 };
458
459 self.as_mut().iter_mut().for_each(|x| {
460 let p = anchor.locate(x);
461
462 let v = p - point;
463 let proj = dir * v.dot(dir);
464 let closest = point + proj;
465 let displacement = closest - p;
466 x.shift(displacement);
467 });
468 self
469 }
470 fn align(&mut self, axis: DVec3) -> &mut Self
472 where
473 T: Aabb,
474 {
475 self.align_anchor(axis, AabbPoint::CENTER)
476 }
477}
478
479pub trait ArrangeSlice<T: transform::ShiftTransformExt>: AsMut<[T]> {
482 fn arrange_with(&mut self, pos_func: impl Fn(usize) -> DVec3)
486 where
487 AabbPoint: Locate<T>,
488 {
489 self.as_mut().iter_mut().enumerate().for_each(|(i, x)| {
490 x.move_to(pos_func(i));
491 });
492 }
493 fn arrange_in_y(&mut self, gap: f64)
495 where
496 T: Aabb,
497 AabbPoint: Locate<T>,
498 {
499 let Some(mut bbox) = self.as_mut().first().map(|x| x.aabb()) else {
500 return;
501 };
502
503 self.as_mut().iter_mut().for_each(|x| {
504 x.move_next_to_padded(bbox.as_slice(), AabbPoint(DVec3::Y), gap);
505 bbox = x.aabb();
506 });
507 }
508 fn arrange_in_grid(&mut self, cell_cnt: USizeVec3, cell_size: DVec3, gap: DVec3) -> &mut Self
510 where
511 AabbPoint: Locate<T>,
512 {
513 let pos_func = |idx: usize| {
515 let x = idx % cell_cnt.x;
516 let temp = idx / cell_cnt.x;
517
518 let y = temp % cell_cnt.y;
519 let z = temp / cell_cnt.y;
520 dvec3(x as f64, y as f64, z as f64) * cell_size
521 + gap * dvec3(x as f64, y as f64, z as f64)
522 };
523 self.arrange_with(pos_func);
524 self
525 }
526 fn arrange_in_cols_with(&mut self, ncols: usize, pos_func: impl Fn(usize, usize) -> DVec3)
530 where
531 AabbPoint: Locate<T>,
532 {
533 let pos_func = |idx: usize| {
534 let row = idx / ncols;
535 let col = idx % ncols;
536 pos_func(row, col)
537 };
538 self.arrange_with(pos_func);
539 }
540 fn arrange_in_rows_with(&mut self, nrows: usize, pos_func: impl Fn(usize, usize) -> DVec3)
544 where
545 AabbPoint: Locate<T>,
546 {
547 let ncols = self.as_mut().len().div_ceil(nrows);
548 self.arrange_in_cols_with(ncols, pos_func);
549 }
550}
551
552impl<T: transform::ShiftTransformExt, E: AsMut<[T]>> ArrangeSlice<T> for E {}