`(max, min)` factors by which a unit vector is stretched under `transform`'s linear part — the principal and minor singular values, equal to the semi-axes of the ellipse a unit circle maps to. Equivalent to `(max(sx, sy), min(sx, sy))` for axis-aligned scales, but accounts for shear.
(transform: DAffine2)
| 272 | fn singular_values(transform: DAffine2) -> (f64, f64) { |
| 273 | let m = transform.matrix2; |
| 274 | let a = m.x_axis.x; |
| 275 | let b = m.x_axis.y; |
| 276 | let c = m.y_axis.x; |
| 277 | let d = m.y_axis.y; |
| 278 | // Eigenvalues of MᵀM via the closed form for a 2×2, both are non-negative |
| 279 | let trace = a * a + b * b + c * c + d * d; |
| 280 | let det = a * d - b * c; |
| 281 | let discriminant = (trace * trace - 4. * det * det).max(0.).sqrt(); |
| 282 | let largest_eigenvalue = (trace + discriminant) * 0.5; |
| 283 | let smallest_eigenvalue = ((trace - discriminant) * 0.5).max(0.); |
| 284 | (largest_eigenvalue.sqrt(), smallest_eigenvalue.sqrt()) |
| 285 | } |
| 286 | |
| 287 | pub fn black_or_white_for_best_contrast(background: Option<Color>) -> Color { |
| 288 | let Some(bg) = background else { return core_types::consts::LAYER_OUTLINE_STROKE_COLOR }; |
| 289 | |
| 290 | let alpha = bg.a(); |
no test coverage detected