Created
March 22, 2017 14:52
-
-
Save timgluz/910326675df3b71bb19104282cd34594 to your computer and use it in GitHub Desktop.
Midpoint circle algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// implemention of http://groups.csail.mit.edu/graphics/classes/6.837/F98/Lecture6/circle.html | |
use std::fs::File; | |
use std::path::Path; | |
use image::{self, GenericImage, ImageBuffer, Pixel, Rgba}; | |
struct Point { | |
x: u32, | |
y: u32 | |
} | |
pub struct Picture { | |
buffer: Box< ImageBuffer<Rgba<u8>, Vec<u8>> >, | |
height: u32, | |
width: u32 | |
} | |
fn set_circle_point(pic: &mut Picture, center_pt: &Point, line_pt: &Point, color: u8){ | |
let act = Rgba::from_channels(255, 0, 0, 255); | |
let pix = Rgba::from_channels(255, 0, color, 255); | |
let ref mut buf = &mut pic.buffer; | |
if line_pt.x == 0 { | |
buf.put_pixel(center_pt.x, center_pt.y + line_pt.y, act ); | |
buf.put_pixel(center_pt.x, center_pt.y - line_pt.y, pix); | |
buf.put_pixel(center_pt.x + line_pt.y, line_pt.y, pix); | |
buf.put_pixel(center_pt.x - line_pt.y, line_pt.y, pix); | |
} else if line_pt.x == line_pt.y { | |
buf.put_pixel(center_pt.x + line_pt.x, center_pt.y + line_pt.y, act); | |
buf.put_pixel(center_pt.x - line_pt.x, center_pt.y + line_pt.y, pix); | |
buf.put_pixel(center_pt.x + line_pt.x, center_pt.y - line_pt.y, pix); | |
buf.put_pixel(center_pt.x - line_pt.x, center_pt.y - line_pt.y, pix); | |
} else if line_pt.x < line_pt.y { | |
buf.put_pixel(center_pt.x + line_pt.x, center_pt.y + line_pt.y, act); | |
buf.put_pixel(center_pt.x - line_pt.x, center_pt.y + line_pt.y, pix); | |
buf.put_pixel(center_pt.x + line_pt.x, center_pt.y - line_pt.y, pix); | |
buf.put_pixel(center_pt.x - line_pt.x, center_pt.y - line_pt.y, pix); | |
buf.put_pixel(center_pt.x + line_pt.y, center_pt.y + line_pt.x, pix); | |
buf.put_pixel(center_pt.x - line_pt.y, center_pt.y + line_pt.x, pix); | |
buf.put_pixel(center_pt.x + line_pt.y, center_pt.y - line_pt.x, pix); | |
buf.put_pixel(center_pt.x - line_pt.y, center_pt.y - line_pt.x, pix); | |
} | |
} | |
fn draw(pic: &mut Picture, center_pt: Point, radius: u32, color: u8) { | |
let mut start_pt = Point {x: 0, y: radius}; | |
let r:i32 = radius as i32; | |
let mut p:i32 = ( 5 - r * 4) / 4; | |
set_circle_point(pic, ¢er_pt, &start_pt, color); | |
while start_pt.x < start_pt.y { | |
start_pt.x += 1; | |
println!("P: {}", p); | |
if p < 0 { | |
p += (2 * start_pt.x + 1) as i32; | |
} else { | |
start_pt.y -= 1; | |
p += (2 * ( (start_pt.x as i32) - (start_pt.y as i32) ) + 1) as i32; | |
} | |
set_circle_point(pic, ¢er_pt, &start_pt, color); | |
} | |
} | |
#[test] | |
fn save_test_image(){ | |
let (w, h) = (512,512); | |
let mut buf = ImageBuffer::new(w, h); | |
let mut pic = Picture { buffer: Box::new(buf), width: w, height: h}; | |
let center_point = Point {x: 255, y: 255}; | |
let radius = 128; | |
let color = 64u8; | |
draw(&mut pic, center_point, radius, color); | |
let ref mut fout = File::create(&Path::new("circle.png")).unwrap(); | |
image::ImageRgba8(*pic.buffer).save(fout, image::PNG).unwrap(); | |
assert!(true); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment