mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-17 07:18:04 +08:00
fixed all bugs and divide futher when angle greater than 180
This commit is contained in:
@@ -1253,7 +1253,7 @@ pub(crate) fn spiral_properties(node_id: NodeId, context: &mut NodePropertiesCon
|
||||
let turns = number_widget(ParameterWidgetsInfo::new(node_id, TurnsInput::INDEX, true, context), NumberInput::default().min(0.1));
|
||||
let angle_offset = number_widget(
|
||||
ParameterWidgetsInfo::new(node_id, AngleOffsetInput::INDEX, true, context),
|
||||
NumberInput::default().min(0.1).max(180.).unit("°"),
|
||||
NumberInput::default().min(1.).max(180.).unit("°"),
|
||||
);
|
||||
let start_angle = number_widget(ParameterWidgetsInfo::new(node_id, StartAngleInput::INDEX, true, context), NumberInput::default().unit("°"));
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::messages::prelude::{DocumentMessageHandler, FrontendMessage, InputPre
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::{self};
|
||||
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
||||
use crate::messages::tool::common_functionality::shapes::shape_utility::{calculate_b, extract_arc_or_log_spiral_parameters, get_arc_spiral_end_point, get_spiral_type, spiral_point};
|
||||
use crate::messages::tool::common_functionality::shapes::spiral_shape::calculate_circle_point;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graph_craft::document::NodeInput;
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
@@ -236,7 +237,6 @@ impl TightnessGizmo {
|
||||
} {
|
||||
let theta_start = base_theta;
|
||||
let theta_end = if is_reversed { base_theta - TAU } else { base_theta + TAU };
|
||||
log::info!("segment index {:?}, theta_start {:?} ,theta_end {:?}", segment_index, theta_start.to_degrees(), theta_end.to_degrees());
|
||||
|
||||
if (!is_reversed && theta_end > max_theta + start_angle_rad) || (is_reversed && theta_end < 0.0) {
|
||||
break;
|
||||
@@ -247,6 +247,10 @@ impl TightnessGizmo {
|
||||
continue;
|
||||
}
|
||||
|
||||
if is_reversed && theta_end < start_angle_rad {
|
||||
break;
|
||||
}
|
||||
|
||||
let spiral_start = spiral_point(theta_start, inner_radius, b, spiral_type);
|
||||
let spiral_end = spiral_point(theta_end, inner_radius, b, spiral_type);
|
||||
|
||||
@@ -294,14 +298,14 @@ impl TightnessGizmo {
|
||||
|
||||
let (start_point, end_point) = if self.spiral_slot == 0 && !reversed {
|
||||
let endpoint = spiral_point(0. + start_angle_rad, inner_radius, b, spiral_type);
|
||||
let circle_point = calculate_circle_point(self.angle, inner_radius.max(5.));
|
||||
let radius = endpoint.distance(DVec2::ZERO);
|
||||
|
||||
(
|
||||
viewport.transform_point2(radius * DVec2::new(self.angle.cos(), -self.angle.sin())),
|
||||
viewport.transform_point2(circle_point),
|
||||
viewport.transform_point2(spiral_point(base_angle, inner_radius, b, spiral_type)),
|
||||
)
|
||||
} else if self.spiral_slot == self.turns.floor() as i32 && reversed {
|
||||
log::info!("am i plzz reaching here");
|
||||
let radius = spiral_point(max_theta, inner_radius, b, spiral_type).distance(DVec2::ZERO);
|
||||
let endpoint = if self.angle >= (max_theta + start_angle_rad).rem_euclid(TAU) {
|
||||
viewport.transform_point2(spiral_point(base_angle - TAU, inner_radius, b, spiral_type))
|
||||
@@ -310,8 +314,12 @@ impl TightnessGizmo {
|
||||
};
|
||||
(viewport.transform_point2(radius * DVec2::new(self.angle.cos(), -self.angle.sin())), endpoint)
|
||||
} else {
|
||||
let ref_angle = (self.spiral_slot as f64 - 1.) * TAU + base_angle;
|
||||
let end_point_angle = if reversed { ref_angle - TAU } else { ref_angle + TAU };
|
||||
let ref_angle = if reversed {
|
||||
base_angle - (turns - self.spiral_slot as f64) * TAU
|
||||
} else {
|
||||
(self.spiral_slot as f64 - 1.) * TAU + base_angle
|
||||
};
|
||||
let end_point_angle = ref_angle + TAU;
|
||||
(
|
||||
viewport.transform_point2(spiral_point(ref_angle, inner_radius, b, spiral_type)),
|
||||
viewport.transform_point2(spiral_point(end_point_angle, inner_radius, b, spiral_type)),
|
||||
|
||||
@@ -173,7 +173,7 @@ impl SpiralTurns {
|
||||
|
||||
match self.gizmo_type {
|
||||
GizmoType::Start => {
|
||||
let sign = total_delta.signum() * -1.;
|
||||
let sign = -1.;
|
||||
responses.add(NodeGraphMessage::SetInput {
|
||||
input_connector: InputConnector::node(node_id, SPIRAL_START_ANGLE),
|
||||
input: NodeInput::value(TaggedValue::F64(self.initial_start_angle + total_delta), false),
|
||||
|
||||
@@ -41,8 +41,8 @@ impl ShapeGizmoHandler for SpiralGizmoHandler {
|
||||
input: &InputPreprocessorMessageHandler,
|
||||
responses: &mut VecDeque<Message>,
|
||||
) {
|
||||
// self.radius_handle.handle_actions(selected_spiral_layer, document, input.mouse.position, responses);
|
||||
// self.turns_handle.handle_actions(selected_spiral_layer, mouse_position, document, responses);
|
||||
self.radius_handle.handle_actions(selected_spiral_layer, document, input.mouse.position, responses);
|
||||
self.turns_handle.handle_actions(selected_spiral_layer, mouse_position, document, responses);
|
||||
self.tightness_handle.handle_actions(selected_spiral_layer, input.mouse.position, document, responses);
|
||||
}
|
||||
|
||||
|
||||
@@ -281,34 +281,47 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
||||
|
||||
let mut theta = start_angle;
|
||||
while theta < theta_end {
|
||||
let theta_next = f64::min(theta + delta_theta, theta_end);
|
||||
|
||||
let p0 = spiral_point(theta, a, b, spiral_type);
|
||||
let p3 = spiral_point(theta_next, a, b, spiral_type);
|
||||
let t0 = spiral_tangent(theta, a, b, spiral_type);
|
||||
let t1 = spiral_tangent(theta_next, a, b, spiral_type);
|
||||
|
||||
let arc_len = spiral_arc_length(theta, theta_next, a, b, spiral_type);
|
||||
let d = arc_len / 3.0;
|
||||
|
||||
let p1 = p0 + d * t0;
|
||||
let p2 = p3 - d * t1;
|
||||
|
||||
manipulator_groups.push(ManipulatorGroup::new(p0, prev_in_handle, Some(p1)));
|
||||
prev_in_handle = Some(p2);
|
||||
|
||||
// If final segment, end with anchor at theta_end
|
||||
if (theta_next - theta_end).abs() < f64::EPSILON {
|
||||
manipulator_groups.push(ManipulatorGroup::new(p3, prev_in_handle, None));
|
||||
break;
|
||||
}
|
||||
|
||||
theta = theta_next;
|
||||
let next_theta = f64::min(theta + delta_theta, theta_end);
|
||||
Self::fit_spiral_segment(theta, next_theta, a, b, spiral_type, &mut manipulator_groups, &mut prev_in_handle);
|
||||
theta = next_theta;
|
||||
}
|
||||
|
||||
// Add final anchor point
|
||||
let p_last = spiral_point(theta_end, a, b, spiral_type);
|
||||
manipulator_groups.push(ManipulatorGroup::new(p_last, prev_in_handle, None));
|
||||
|
||||
Self::new(manipulator_groups, false)
|
||||
}
|
||||
|
||||
fn fit_spiral_segment(theta_start: f64, theta_end: f64, a: f64, b: f64, spiral_type: SpiralType, manipulator_groups: &mut Vec<ManipulatorGroup<PointId>>, prev_in_handle: &mut Option<DVec2>) {
|
||||
let delta = (theta_end - theta_start).abs();
|
||||
|
||||
// Split large arcs into two halves
|
||||
if delta > std::f64::consts::FRAC_PI_2 {
|
||||
let mid = (theta_start + theta_end) / 2.0;
|
||||
Self::fit_spiral_segment(theta_start, mid, a, b, spiral_type, manipulator_groups, prev_in_handle);
|
||||
Self::fit_spiral_segment(mid, theta_end, a, b, spiral_type, manipulator_groups, prev_in_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute endpoints and tangents
|
||||
let p0 = spiral_point(theta_start, a, b, spiral_type);
|
||||
let p3 = spiral_point(theta_end, a, b, spiral_type);
|
||||
let t0 = spiral_tangent(theta_start, a, b, spiral_type);
|
||||
let t1 = spiral_tangent(theta_end, a, b, spiral_type);
|
||||
|
||||
// Use fixed handle length: 1/3 of the arc length
|
||||
let arc_len = spiral_arc_length(theta_start, theta_end, a, b, spiral_type);
|
||||
let h_in = arc_len / 3.0;
|
||||
let h_out = arc_len / 3.0;
|
||||
|
||||
let p1 = p0 + h_in * t0;
|
||||
let p2 = p3 - h_out * t1;
|
||||
|
||||
manipulator_groups.push(ManipulatorGroup::new(p0, *prev_in_handle, Some(p1)));
|
||||
*prev_in_handle = Some(p2);
|
||||
}
|
||||
|
||||
/// Constructs an ellipse with `corner1` and `corner2` as the two corners of the bounding box.
|
||||
pub fn new_ellipse(corner1: DVec2, corner2: DVec2) -> Self {
|
||||
let size = (corner1 - corner2).abs();
|
||||
|
||||
Reference in New Issue
Block a user