Function clipline::clipline

source ·
pub fn clipline<T, F>(
    line: ((T, T), (T, T)),
    clip_rect: ((T, T), (T, T)),
    pixel_op: F
) -> Option<((T, T), (T, T))>
where T: Copy + Ord + Neg<Output = T> + Add<Output = T> + AddAssign + Sub<Output = T> + SubAssign + Mul<Output = T> + Div<Output = T> + Rem<Output = T> + MulAssign + Constant<Output = T>, Range<T>: Iterator<Item = T>, F: FnMut(T, T),
Expand description

Performs scan conversion of a line segment using Bresenham’s algorithm, while clipping it to a specified rectangle.

The function takes a line defined by two endpoints (inclusive) and a clipping rectangle defined by its corners (inclusive). The provided closure pixel_op is responsible for handling each pixel within the clipped region. To ensure optimal performance, it is recommended that pixel_op does not perform any bounds checks.

Arguments

  • line: A tuple representing the endpoints of the line segment, inclusive. The line segment will be drawn between these two points.

  • clip_rect: A tuple representing the corners of the clipping rectangle, inclusive. The line segment will be clipped to this rectangle, and only the visible portion will be drawn.

  • pixel_op: A closure that takes the coordinates of a pixel within the clipped region. It is invoked for each pixel along the line. You can use this closure to perform any desired pixel-specific operations without the need for bounds checking.

Returns

If any part of the line segment is visible within the clipping rectangle, the function returns an Option containing a tuple of two ClipPoint values representing the starting and ending points of the visible portion of the line segment. If the line is entirely outside the clipping region, the function returns None.

Example

use clipline::clipline;

fn draw_pixel(x: isize, y: isize) {
    // Your custom pixel drawing logic here
    // No bounds checks necessary here
}

let line = ((0, 0), (10, 10));
let clip_rect = ((2, 2), (8, 8));

let (start, end) = clipline(line, clip_rect, draw_pixel)
    .expect("line intersects clip_rect");
assert_eq!(start, clip_rect.0);
assert_eq!(end, clip_rect.1);

Note

This is slightly more optimized than the iterator version, but uses internal iteration. Unlike the iterator version, vertical and horizontal lines will always be traversed in an ascending order.