我正在实现使用角手柄旋转形状的功能。旋转对于方形形状效果很好,但我遇到了非方形形状(纵横比不同于 1:1 的矩形)的问题。当通过拖动角手柄来旋转这些形状时,它们会意外地“捕捉”或旋转,而不考虑形状的纵横比。这会导致光标的初始单击点和形状的旋转行为之间不对齐。
我怀疑问题出在我的旋转计算上,没有考虑纵横比,导致旋转时角度偏移不正确。
如何正确计算旋转,同时考虑形状的长宽比,以确保用户旋转非方形形状时平滑且符合预期的行为?
也许我也在尝试解决问题的问题,所以我想解决的核心问题基本上是如何通过角手柄绕中心旋转矩形。您可以在此视频中看到该行为。
代码:
pub fn handle_rotating(
composition: &CompositionRes,
selected_nodes_query: &mut Query<
(
&mut RelativeTransformMixin,
&AbsoluteTransformMixin,
&mut DimensionMixin,
),
With<Selected>,
>,
event: &CursorMovedOnComposition,
corner: u8,
initial_rotation: f32,
) {
let CursorMovedOnComposition {
position: cursor_position,
..
} = event;
let cursor_position = transform_point_to_view_box(composition, cursor_position, true);
selected_nodes_query.for_each_mut(
|(mut relative_transform_mixin, absolute_transform_mixin, dimension_mixin)| {
let relative_pivot_point = Vec2::new(
dimension_mixin.width as f32 / 2.0,
dimension_mixin.height as f32 / 2.0,
);
let absolute_pivot_point =
apply_transform_to_point(absolute_transform_mixin.0, relative_pivot_point);
// Determine rotation offset based on corner
let rotation_offset_in_radians: f32 = match corner {
_ if corner == (HandleSide::Top as u8 | HandleSide::Left as u8) => {
(-135.0 as f32).to_radians()
}
_ if corner == (HandleSide::Top as u8 | HandleSide::Right as u8) => {
(-45.0 as f32).to_radians()
}
_ if corner == (HandleSide::Bottom as u8 | HandleSide::Right as u8) => {
(45.0 as f32).to_radians()
}
_ if corner == (HandleSide::Bottom as u8 | HandleSide::Left as u8) => {
(135.0 as f32).to_radians()
}
_ => 0.0,
};
// Calculate rotation based on the corner
let rotation_angle =
calculate_rotation(initial_rotation, &cursor_position, &absolute_pivot_point);
let final_rotation_angle =
rotation_angle + rotation_offset_in_radians - initial_rotation;
relative_transform_mixin.0 = set_rotation(
relative_transform_mixin.0,
final_rotation_angle,
relative_pivot_point,
);
},
);
}
fn calculate_rotation(
initial_angle_in_radians: f32,
cursor_point: &Vec2,
pivot_point: &Vec2,
) -> f32 {
// Calculate the angle from the pivot point to the current cursor position
let current_angle = (cursor_point.y - pivot_point.y).atan2(cursor_point.x - pivot_point.x);
// Calculate the raw angle difference
let angle_diff = current_angle - initial_angle_in_radians;
return -angle_diff;
}