Repository: GraphiteEditor/Graphite
File: node-graph/gcore/src/vector/algorithms/bezpath_algorithms.rs (Rust)

Code before:
	match segment {
		PathSeg::Line(line) => line.deriv().eval(t),
		PathSeg::Quad(quad_bez) => quad_bez.deriv().eval(t),
		PathSeg::Cubic(cubic_bez) => cubic_bez.deriv().eval(t),
	}
}

pub fn sample_points_on_bezpath(bezpath: BezPath, spacing: f64, start_offset: f64, stop_offset: f64, adaptive_spacing: bool, count_points : bool, segments_length: &[f64]) -> Option<BezPath> {
	let mut sample_bezpath = BezPath::new();

	let was_closed = matches!(bezpath.elements().last(), Some(PathEl::ClosePath));

	// Calculate the total length of the collected segments.
	let total_length: f64 = segments_length.iter().sum();

	// Adjust the usable length by subtracting start and stop offsets.
	let mut used_length = total_length - start_offset - stop_offset;

	if used_length <= 0. {
		return None;
	}

	// Determine the number of points to generate along the path.
	let sample_count = if count_points {
		spacing
	}else {
		if adaptive_spacing {
			// Calculate point count to evenly distribute points while covering the entire path.
			// With adaptive spacing, we widen or narrow the points as necessary to ensure the last point is always at the end of the path.
			(used_length / spacing).round()
		} else {
			// Calculate point count based on exact spacing, which may not cover the entire path.

			// Without adaptive spacing, we just evenly space the points at the exact specified spacing, usually falling short before the end of the path.
			let count = (used_length / spacing + f64::EPSILON).floor();
			used_length -= used_length % spacing;
			count
		}
	};

	// Skip if there are no points to generate.
	if sample_count < 1. {
		return None;
	}

	// Decide how many loop-iterations: if closed, skip the last duplicate point
	let sample_count_usize = sample_count as usize;
	let max_i = if was_closed { sample_count_usize } else { sample_count_usize + 1 };

	// Generate points along the path based on calculated intervals.
	let mut length_up_to_previous_segment = 0.;

Review comment (suggestion):
You'll need to always run `rustfmt` before committing, if your editor isn't configured to do that on save.

Code after:
	let (segment_index, t) = t_value_to_parametric(bezpath, t, euclidian, None);
	let segment = bezpath.get_seg(segment_index + 1).unwrap();

	// Divide the segment.
	let first_segment = segment.subsegment(0.0..t);
	let second_segment = segment.subsegment(t..1.);

	let mut first_bezpath = BezPath::new();
	let mut second_bezpath = BezPath::new();

	// Append the segments up to the subdividing segment from original bezpath to first bezpath.
	for segment in bezpath.segments().take(segment_index) {
		if first_bezpath.elements().is_empty() {
			first_bezpath.move_to(segment.start());
		}
		first_bezpath.push(segment.as_path_el());
	}

	// Append the first segment of the subdivided segment.
	if first_bezpath.elements().is_empty() {
		first_bezpath.move_to(first_segment.start());
	}
	first_bezpath.push(first_segment.as_path_el());

	// Append the second segment of the subdivided segment in the second bezpath.
	if second_bezpath.elements().is_empty() {
		second_bezpath.move_to(second_segment.start());
	}
	second_bezpath.push(second_segment.as_path_el());

	// Append the segments after the subdividing segment from original bezpath to second bezpath.
	for segment in bezpath.segments().skip(segment_index + 1) {
		if second_bezpath.elements().is_empty() {
			second_bezpath.move_to(segment.start());
		}
		second_bezpath.push(segment.as_path_el());
	}

	Some((first_bezpath, second_bezpath))
}

pub fn position_on_bezpath(bezpath: &BezPath, t: f64, euclidian: bool, segments_length: Option<&[f64]>) -> Point {
	let (segment_index, t) = t_value_to_parametric(bezpath, t, euclidian, segments_length);
	bezpath.get_seg(segment_index + 1).unwrap().eval(t)
}

pub fn tangent_on_bezpath(bezpath: &BezPath, t: f64, euclidian: bool, segments_length: Option<&[f64]>) -> Point {
	let (segment_index, t) = t_value_to_parametric(bezpath, t, euclidian, segments_length);
	let segment = bezpath.get_seg(segment_index + 1).unwrap();
	match segment {
		PathSeg::Line(line) => line.deriv().eval(t),