Repository: GraphiteEditor/Graphite
File: editor/src/messages/tool/common_functionality/shape_editor.rs (Rust)

Code before:
		// Set the manipulator to have colinear handles
		if let (Some(a), Some(b)) = (handles.first(), handles.get(1)) {
			let handles = [*a, *b];
			let modification_type = VectorModificationType::SetG1Continuous { handles, enabled: true };
			responses.add(GraphOperationMessage::Vector { layer, modification_type });
		}

		// Flip the vector if it is not facing towards the same direction as the anchor
		let [first, second] = [anchor_positions.first().copied().flatten(), anchor_positions.get(1).copied().flatten()];
		if first.is_some_and(|group| (group - anchor_position).normalize_or_zero().dot(handle_direction) < 0.)
			|| second.is_some_and(|group| (group - anchor_position).normalize_or_zero().dot(handle_direction) > 0.)
		{
			handle_direction *= -1.;
		}

		if non_zero_handles != 0 {
			let [a, b] = handles.as_slice() else { return };
			let (non_zero_handle, zero_handle) = if a.length(vector_data) > 1e-6 { (a, b) } else { (b, a) };
			let Some(direction) = non_zero_handle
				.to_manipulator_point()
				.get_position(&vector_data)
				.and_then(|position| (position - anchor_position).try_normalize())
			else {
				return;
			};
			let new_position = non_zero_handle.length(vector_data) * direction * -1.;
			let modification_type = zero_handle.set_relative_position(new_position);
			responses.add(GraphOperationMessage::Vector { layer, modification_type });
		} else {
			// Push both in and out handles into the correct position
			for ((handle, sign), other_anchor) in handles.iter().zip([1., -1.]).zip(&anchor_positions) {
				// To find the length of the new tangent we just take the distance to the anchor and divide by 3 (pretty arbitrary)
				let Some(length) = other_anchor.map(|position| (position - anchor_position).length() / 3.) else {
					continue;
				};
				let new_position = handle_direction * length * sign;
				let modification_type = handle.set_relative_position(new_position);
				responses.add(GraphOperationMessage::Vector { layer, modification_type });

				// Create the opposite handle if it doesn't exist (if it is not a cubic segment)
				if handle.opposite().to_manipulator_point().get_position(vector_data).is_none() {
					let modification_type = handle.opposite().set_relative_position(DVec2::ZERO);
					responses.add(GraphOperationMessage::Vector { layer, modification_type });
				}
			}
		}
	}

	/// Converts all selected points to colinear while moving the handles to ensure their 180° angle separation.
	/// If only one handle is selected, the other handle will be moved to match the angle of the selected handle.
	/// If both or neither handles are selected, the angle of both handles will be averaged from their current angles, weighted by their lengths.

Review comment (suggestion):
`-direction` is probably cleaner than `direction * -1`. Maybe also put it on the left hand side of the multiplication for further cleanliness/readability.

Code after:
			segment_count += 1.;
		}

		// For a non-endpoint anchor, handles are perpendicular to the average tangent of adjacent segments.(Refer:https://github.com/GraphiteEditor/Graphite/pull/2620#issuecomment-2881501494)
		let mut handle_direction = if segment_count > 1. {
			segment_angle = segment_angle / segment_count;
			segment_angle += std::f64::consts::FRAC_PI_2;
			DVec2::new(segment_angle.cos(), segment_angle.sin())
		} else {
			DVec2::new(segment_angle.cos(), segment_angle.sin())
		};

		// Set the manipulator to have colinear handles
		if let (Some(a), Some(b)) = (handles.first(), handles.get(1)) {
			let handles = [*a, *b];
			let modification_type = VectorModificationType::SetG1Continuous { handles, enabled: true };
			responses.add(GraphOperationMessage::Vector { layer, modification_type });
		}

		// Flip the vector if it is not facing towards the same direction as the anchor
		let [first, second] = [anchor_positions.first().copied().flatten(), anchor_positions.get(1).copied().flatten()];
		if first.is_some_and(|group| (group - anchor_position).normalize_or_zero().dot(handle_direction) < 0.)
			|| second.is_some_and(|group| (group - anchor_position).normalize_or_zero().dot(handle_direction) > 0.)
		{
			handle_direction *= -1.;
		}

		if non_zero_handles != 0 {
			let [a, b] = handles.as_slice() else { return };
			let (non_zero_handle, zero_handle) = if a.length(vector_data) > 1e-6 { (a, b) } else { (b, a) };
			let Some(direction) = non_zero_handle
				.to_manipulator_point()
				.get_position(&vector_data)
				.and_then(|position| (position - anchor_position).try_normalize())
			else {
				return;
			};
			let new_position = -direction * non_zero_handle.length(vector_data);
			let modification_type = zero_handle.set_relative_position(new_position);
			responses.add(GraphOperationMessage::Vector { layer, modification_type });
		} else {
			// Push both in and out handles into the correct position
			for ((handle, sign), other_anchor) in handles.iter().zip([1., -1.]).zip(&anchor_positions) {
				let Some(anchor_vector) = other_anchor.map(|position| (position - anchor_position)) else {
					continue;
				};

				let Some(unit_vector) = anchor_vector.try_normalize() else {
					continue;
				};