@@ -3,44 +3,21 @@ use glam::{DAffine2, DVec2};
33use graph_craft::document::value::TaggedValue;
44use graph_craft::document::{NodeId, NodeInput};
55use graphene_std::subpath::Subpath;
6+ use graphene_std::transform::Transform;
67use graphene_std::vector::PointId;
78
8- /// Convert an affine transform into the tuple `(scale, angle, translation, shear)` assuming `shear.y = 0`.
9- pub fn compute_scale_angle_translation_shear(transform: DAffine2) -> (DVec2, f64, DVec2, DVec2) {
10- let x_axis = transform.matrix2.x_axis;
11- let y_axis = transform.matrix2.y_axis;
12-
13- // Assuming there is no vertical shear
14- let angle = x_axis.y.atan2(x_axis.x);
15- let (sin, cos) = angle.sin_cos();
16- let scale_x = if cos.abs() > 1e-10 { x_axis.x / cos } else { x_axis.y / sin };
17-
18- let mut shear_x = (sin * y_axis.y + cos * y_axis.x) / (sin * sin * scale_x + cos * cos * scale_x);
19- if !shear_x.is_finite() {
20- shear_x = 0.;
21- }
22- let scale_y = if cos.abs() > 1e-10 {
23- (y_axis.y - scale_x * sin * shear_x) / cos
24- } else {
25- (scale_x * cos * shear_x - y_axis.x) / sin
26- };
27- let translation = transform.translation;
28- let scale = DVec2::new(scale_x, scale_y);
29- let shear = DVec2::new(shear_x, 0.);
30- (scale, angle, translation, shear)
31- }
32-
339/// Update the inputs of the transform node to match a new transform
3410pub fn update_transform(network_interface: &mut NodeNetworkInterface, node_id: &NodeId, transform: DAffine2) {
35- let (scale, rotation, translation, shear) = compute_scale_angle_translation_shear(transform);
11+ let (rotation, scale, skew) = transform.decompose_rotation_scale_skew();
12+ let translation = transform.translation;
3613
3714 let rotation = rotation.to_degrees();
38- let shear = DVec2::new(shear.x. atan().to_degrees(), shear.y.atan().to_degrees() );
15+ let skew = DVec2::new(skew. atan().to_degrees(), 0. );
3916
4017 network_interface.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::DVec2(translation), false), &[]);
4118 network_interface.set_input(&InputConnector::node(*node_id, 2), NodeInput::value(TaggedValue::F64(rotation), false), &[]);
4219 network_interface.set_input(&InputConnector::node(*node_id, 3), NodeInput::value(TaggedValue::DVec2(scale), false), &[]);
43- network_interface.set_input(&InputConnector::node(*node_id, 4), NodeInput::value(TaggedValue::DVec2(shear ), false), &[]);
20+ network_interface.set_input(&InputConnector::node(*node_id, 4), NodeInput::value(TaggedValue::DVec2(skew ), false), &[]);
4421}
4522
4623// TODO: This should be extracted from the graph at the location of the transform node.
@@ -81,12 +58,12 @@ pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 {
8158 };
8259 let rotation = if let Some(&TaggedValue::F64(rotation)) = inputs[2].as_value() { rotation } else { 0. };
8360 let scale = if let Some(&TaggedValue::DVec2(scale)) = inputs[3].as_value() { scale } else { DVec2::ONE };
84- let shear = if let Some(&TaggedValue::DVec2(shear )) = inputs[4].as_value() { shear } else { DVec2::ZERO };
61+ let skew = if let Some(&TaggedValue::DVec2(skew )) = inputs[4].as_value() { skew } else { DVec2::ZERO };
8562
8663 let rotation = rotation.to_radians();
87- let shear = DVec2::new(shear .x.to_radians().tan(), shear .y.to_radians().tan());
64+ let skew = DVec2::new(skew .x.to_radians().tan(), skew .y.to_radians().tan());
8865
89- DAffine2::from_scale_angle_translation(scale, rotation, translation) * DAffine2::from_cols_array(&[1., shear .y, shear .x, 1., 0., 0.])
66+ DAffine2::from_scale_angle_translation(scale, rotation, translation) * DAffine2::from_cols_array(&[1., skew .y, skew .x, 1., 0., 0.])
9067}
9168
9269/// Extract the current normalized pivot from the layer
@@ -135,31 +112,32 @@ mod tests {
135112 /// ```
136113 #[test]
137114 fn derive_transform() {
138- for shear_x in -10..=10 {
139- let shear_x = (shear_x as f64) / 2.;
115+ for skew_x in -10..=10 {
116+ let skew_x = (skew_x as f64) / 2.;
140117 for angle in (0..=360).step_by(15) {
141118 let angle = (angle as f64).to_radians();
142119 for scale_x in 1..10 {
143120 let scale_x = (scale_x as f64) / 5.;
144121 for scale_y in 1..10 {
145122 let scale_y = (scale_y as f64) / 5.;
146123
147- let shear = DVec2::new(shear_x , 0.);
124+ let skew = DVec2::new(skew_x , 0.);
148125 let scale = DVec2::new(scale_x, scale_y);
149126 let translate = DVec2::new(5666., 644.);
150127
151128 let original_transform = DAffine2::from_cols(
152- DVec2::new(scale.x * angle.cos() - scale.y * angle.sin() * shear .y, scale.x * angle.sin() + scale.y * angle.cos() * shear .y),
153- DVec2::new(scale.x * angle.cos() * shear .x - scale.y * angle.sin(), scale.x * angle.sin() * shear .x + scale.y * angle.cos()),
129+ DVec2::new(scale.x * angle.cos() - scale.y * angle.sin() * skew .y, scale.x * angle.sin() + scale.y * angle.cos() * skew .y),
130+ DVec2::new(scale.x * angle.cos() * skew .x - scale.y * angle.sin(), scale.x * angle.sin() * skew .x + scale.y * angle.cos()),
154131 translate,
155132 );
156133
157- let (new_scale, new_angle, new_translation, new_shear) = compute_scale_angle_translation_shear(original_transform);
158- let new_transform = DAffine2::from_scale_angle_translation(new_scale, new_angle, new_translation) * DAffine2::from_cols_array(&[1., new_shear.y, new_shear.x, 1., 0., 0.]);
134+ let (new_angle, new_scale, new_skew) = original_transform.decompose_rotation_scale_skew();
135+ let new_translation = original_transform.translation;
136+ let new_transform = DAffine2::from_scale_angle_translation(new_scale, new_angle, new_translation) * DAffine2::from_cols_array(&[1., 0., new_skew, 1., 0., 0.]);
159137
160138 assert!(
161139 new_transform.abs_diff_eq(original_transform, 1e-10),
162- "original_transform {original_transform} new_transform {new_transform} / scale {scale} new_scale {new_scale} / angle {angle} new_angle {new_angle} / shear {shear } / new_shear {new_shear }",
140+ "original_transform {original_transform} new_transform {new_transform} / scale {scale} new_scale {new_scale} / angle {angle} new_angle {new_angle} / skew {skew } / new_skew {new_skew }",
163141 );
164142 }
165143 }
0 commit comments