Computes the axis-aligned bounding box of a rounded rectangle after rotation. Uses the Minkowski-sum approach for equal corner radii: `AABB_w = |(w-2r)·cosθ| + |(h-2r)·sinθ| + 2r` `AABB_h = |(w-2r)·sinθ| + |(h-2r)·cosθ| + 2r` For non-uniform radii, uses the maximum radius as a conservative approximation. Returns `(effective_width, effective_height)`.
(
width: f32,
height: f32,
corner_radius: &CornerRadius,
rotation_radians: f32,
)
| 107 | /// For non-uniform radii, uses the maximum radius as a conservative approximation. |
| 108 | /// Returns `(effective_width, effective_height)`. |
| 109 | pub fn compute_rotated_aabb( |
| 110 | width: f32, |
| 111 | height: f32, |
| 112 | corner_radius: &CornerRadius, |
| 113 | rotation_radians: f32, |
| 114 | ) -> (f32, f32) { |
| 115 | let angle = classify_angle(rotation_radians); |
| 116 | match angle { |
| 117 | AngleType::Zero => (width, height), |
| 118 | AngleType::Straight180 => (width, height), |
| 119 | AngleType::Right90 | AngleType::Right270 => (height, width), |
| 120 | AngleType::Arbitrary(theta) => { |
| 121 | let r = corner_radius |
| 122 | .top_left |
| 123 | .max(corner_radius.top_right) |
| 124 | .max(corner_radius.bottom_left) |
| 125 | .max(corner_radius.bottom_right) |
| 126 | .min(width / 2.0) |
| 127 | .min(height / 2.0); |
| 128 | |
| 129 | let cos_t = theta.cos().abs(); |
| 130 | let sin_t = theta.sin().abs(); |
| 131 | let inner_w = (width - 2.0 * r).max(0.0); |
| 132 | let inner_h = (height - 2.0 * r).max(0.0); |
| 133 | |
| 134 | let eff_w = inner_w * cos_t + inner_h * sin_t + 2.0 * r; |
| 135 | let eff_h = inner_w * sin_t + inner_h * cos_t + 2.0 * r; |
| 136 | (eff_w, eff_h) |
| 137 | } |
| 138 | } |
| 139 | } |