Fix bounding boxes of VectorData with rotations in several nodes (#1792)
The VectorData::bounding_box() function does not apply the VectorData's transform, and bounding_box_with_transform() must be used instead of applying the transform to the computed bounding box. It may make sense in the future to move the current version of bounding_box to a private method bounding_box_no_transform() and have the public bounding_box call bounding_box_with_transform so that external code doesn't need to know about how the VectorData stores it's data. This fixes the following nodes: - Repeat - Circular Repeat - Bounding Box Also add a test to the bounding box node for this situation.
This commit is contained in:
parent
84ac2e274e
commit
5ed5f55dfb
|
|
@ -76,7 +76,9 @@ fn repeat_vector_data(vector_data: VectorData, direction: DVec2, angle: f64, ins
|
|||
// Repeat the vector data
|
||||
let mut result = VectorData::empty();
|
||||
|
||||
let Some(bounding_box) = vector_data.bounding_box() else { return vector_data };
|
||||
let Some(bounding_box) = vector_data.bounding_box_with_transform(vector_data.transform) else {
|
||||
return vector_data;
|
||||
};
|
||||
let center = (bounding_box[0] + bounding_box[1]) / 2.;
|
||||
|
||||
for i in 0..instances {
|
||||
|
|
@ -108,7 +110,9 @@ fn circular_repeat_vector_data(vector_data: VectorData, angle_offset: f64, radiu
|
|||
|
||||
let mut result = VectorData::empty();
|
||||
|
||||
let Some(bounding_box) = vector_data.bounding_box() else { return vector_data };
|
||||
let Some(bounding_box) = vector_data.bounding_box_with_transform(vector_data.transform) else {
|
||||
return vector_data;
|
||||
};
|
||||
let center = (bounding_box[0] + bounding_box[1]) / 2.;
|
||||
|
||||
let base_transform = DVec2::new(0., radius) - center;
|
||||
|
|
@ -128,11 +132,8 @@ pub struct BoundingBoxNode;
|
|||
|
||||
#[node_macro::node_fn(BoundingBoxNode)]
|
||||
fn generate_bounding_box(vector_data: VectorData) -> VectorData {
|
||||
let bounding_box = vector_data.bounding_box().unwrap();
|
||||
VectorData::from_subpath(Subpath::new_rect(
|
||||
vector_data.transform.transform_point2(bounding_box[0]),
|
||||
vector_data.transform.transform_point2(bounding_box[1]),
|
||||
))
|
||||
let bounding_box = vector_data.bounding_box_with_transform(vector_data.transform).unwrap();
|
||||
VectorData::from_subpath(Subpath::new_rect(bounding_box[0], bounding_box[1]))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
|
@ -652,6 +653,16 @@ mod test {
|
|||
assert_eq!(bounding_box.region_bezier_paths().count(), 1);
|
||||
let subpath = bounding_box.region_bezier_paths().next().unwrap().1;
|
||||
assert_eq!(&subpath.anchors()[..4], &[DVec2::NEG_ONE, DVec2::new(1., -1.), DVec2::ONE, DVec2::new(-1., 1.),]);
|
||||
|
||||
// test a VectorData with non-zero rotation
|
||||
let mut square = VectorData::from_subpath(Subpath::new_rect(DVec2::NEG_ONE, DVec2::ONE));
|
||||
square.transform *= DAffine2::from_angle(core::f64::consts::FRAC_PI_4);
|
||||
let bounding_box = BoundingBoxNode.eval(square);
|
||||
assert_eq!(bounding_box.region_bezier_paths().count(), 1);
|
||||
let subpath = bounding_box.region_bezier_paths().next().unwrap().1;
|
||||
let sqrt2 = core::f64::consts::SQRT_2;
|
||||
let sqrt2_bounding_box = [DVec2::new(-sqrt2, -sqrt2), DVec2::new(sqrt2, -sqrt2), DVec2::new(sqrt2, sqrt2), DVec2::new(-sqrt2, sqrt2)];
|
||||
assert!(subpath.anchors()[..4].iter().zip(sqrt2_bounding_box).all(|(p1, p2)| p1.abs_diff_eq(p2, f64::EPSILON)));
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn copy_to_points() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue