有没有更好的方法来使用图像0.18箱子实现中点圆算法?

时间:2018-03-29 15:01:51

标签: algorithm rust geometry

我正在尝试在Rust中实现中点圆算法。 我已将C code from Wikipedia重写为Rust语法。

我在“put pixel”部分遇到了麻烦,首先我创建了:

let mut pixel = buffer.get_pixel_mut(x0 + x, y0 + y);

然后给它rgb值

pixel.data = [red, green, blue];

并试图用下一个像素做同样的事情

pixel = buffer.get_pixel_mut(x0 + y, y0 + x);

等等;

问题是我试图在同一范围内多次借用buffer,所以我为每个像素分配创建了一个范围。它有效,但代码看起来很糟糕。有一个更好的方法吗?

完整功能:

fn draw_circle(
    x0: u32,
    y0: u32,
    radius: u32,
    buffer: &mut ImageBuffer<Rgb<u8>, Vec<u8>>,
    red: u8,
    green: u8,
    blue: u8,
) {
    let mut x: i32 = radius as i32;
    let mut y: i32 = 0;
    let mut err: i32 = 0;

    while x >= y {
        {
            let pixel = buffer.get_pixel_mut(x0 + x as u32, y0 + y as u32);
            pixel.data = [red, green, blue];
        }
        {
            let pixel = buffer.get_pixel_mut(x0 + y as u32, y0 + x as u32);
            pixel.data = [red, green, blue];
        }
        {
            let pixel = buffer.get_pixel_mut(x0 - y as u32, y0 + x as u32);
            pixel.data = [red, green, blue];
        }
        {
            let pixel = buffer.get_pixel_mut(x0 - x as u32, y0 + y as u32);
            pixel.data = [red, green, blue];
        }
        {
            let pixel = buffer.get_pixel_mut(x0 - x as u32, y0 - y as u32);
            pixel.data = [red, green, blue];
        }
        {
            let pixel = buffer.get_pixel_mut(x0 - y as u32, y0 - x as u32);
            pixel.data = [red, green, blue];
        }
        {
            let pixel = buffer.get_pixel_mut(x0 + y as u32, y0 - x as u32);
            pixel.data = [red, green, blue];
        }
        {
            let pixel = buffer.get_pixel_mut(x0 + x as u32, y0 - y as u32);
            pixel.data = [red, green, blue];
        }

        if err <= 0 {
            y += 1;
            err += 2 * y + 1;
        }

        if err > 0 {
            x -= 1;
            err -= 2 * x + 1;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我不认识Rust,但你可以这样做:

while x >= y {
    for xsign in [-1,1] {
        for ysign in [-1,1] {
            {
                let pixel = buffer.get_pixel_mut(x0 + xsign*x as u32, y0 + ysign*y as u32);
                pixel.data = [red, green, blue];
            }
            {
                let pixel = buffer.get_pixel_mut(x0 + xsign*y as u32, y0 + ysign*x as u32);
                pixel.data = [red, green, blue];
            }
        }
    }

如果Rust提供了一种简单的方式来说for dx,dy in ( (x,y), (y,x) ),那么您可以使用x0+xsign*dxy0+ysing*dy将最后两个合并为一个循环。

在Python中,您可以考虑使用itertools.product将三个for循环组合成一个for循环,从笛卡尔积xsign,ysign,(dx,dy)获取[-1,1]x[-1,1]x((x,y),(y,x))。在Python中,这最终会成为:

while x >= y:
    for xsign,ysign,(dx,dy) in itertools.product([-1,1],[-1,1],((x,y),(y,x))):
        let pixel = buffer.get_pixel_mut(x0 + xsign*x as u32, y0 + ysign*y as u32);
        pixel.data = [red, green, blue];

我不知道Rust(我已经说清楚了吗?),但如果Rust没有类似的机制,我会感到惊讶。