Verified Commit 9916464e authored by Jenny's avatar Jenny
Browse files

optimized circle drawing

parent 772408e0
use std::io::prelude::Write;
use std::net::TcpStream;
use std::thread;
use std::thread::JoinHandle;
pub fn draw_circle(host: &str, radius: u32, center_x: u32, center_y: u32, color: &str) {
// r^2 = x^2 + y^2
let center_x: f32 = center_x as f32;
let center_y: f32 = center_y as f32;
use rand::thread_rng;
use rand::seq::SliceRandom;
fn draw_circle_slice(host: String, area: Vec<String>) {
let mut stream = TcpStream::connect(host).expect("Failed to connect!");
loop {
for pos in area.iter() {
stream.write(pos.as_bytes()).expect("Failed to send message!");
}
}
}
pub fn draw_circle(host: &str, color: &str, slices: u8, radius: u16, center_x: u16, center_y: u16, shuffle: bool) {
let center_x = center_x as i32;
let center_y = center_y as i32;
let r2 = radius * radius;
let mut area: Vec<String> = Vec::new();
for r in 0..=radius {
for x in 0..=r {
// y^2 = r^2 - x^2
let x = x as f32;
let r2: f32 = (r * r) as f32;
for x in 0..=radius {
for y in 0..=radius {
let x = x as i32;
let y = y as i32;
let r2 = r2 as i32;
let x2 = x * x;
let y2 = y * y;
if (x2 + y2) > r2 {
continue;
}
let x2: f32 = x * x;
let y2: f32 = r2 - x2;
let y = y2.sqrt().round();
let target_x_pos = x + center_x;
let target_x_neg = -1.0 * x + center_x;
let target_x_neg = -1 * x + center_x;
let target_y_pos = y + center_y;
let target_y_neg = -1.0 * y + center_y;
let target_y_neg = -1 * y + center_y;
let target_x: u32 = target_x_pos as u32;
let target_y: u32 = target_y_pos as u32;
let msg = format!("PX {} {} {}\n", target_x, target_y, color);
let msg = format!("PX {} {} {}\n", target_x_pos, target_y_pos, color);
area.push(msg);
if target_x_neg >= 0.0 {
let target_x: u32 = target_x_neg as u32;
let target_y: u32 = target_y_pos as u32;
let msg = format!("PX {} {} {}\n", target_x, target_y, color);
if target_x_neg >= 0 {
let msg = format!("PX {} {} {}\n", target_x_neg, target_y_pos, color);
area.push(msg);
}
if target_y_neg >= 0.0 {
let target_x: u32 = target_x_pos as u32;
let target_y: u32 = target_y_neg as u32;
let msg = format!("PX {} {} {}\n", target_x, target_y, color);
if target_y_neg >= 0 {
let msg = format!("PX {} {} {}\n", target_x_pos, target_y_neg, color);
area.push(msg);
}
if target_x_neg >= 0.0 && target_y_neg >= 0.0 {
let target_x: u32 = target_x_neg as u32;
let target_y: u32 = target_y_neg as u32;
let msg = format!("PX {} {} {}\n", target_x, target_y, color);
if target_x_neg >= 0 && target_y_neg >= 0 {
let msg = format!("PX {} {} {}\n", target_x_neg, target_y_neg, color);
area.push(msg);
}
}
}
if shuffle {
area.shuffle(&mut thread_rng());
}
let mut stream = TcpStream::connect(host).expect("Failed to connect!");
loop {
for pos in area.iter() {
stream.write(pos.as_bytes()).expect("Failed to send message!");
let slices = slices as usize;
let len = area.len();
let mut rest = len % slices;
let mut threads: Vec<JoinHandle<()>> = Vec::new();
for _ in 1..=slices {
let host_string = String::from(host);
let mut slice_count = len / slices;
if rest > 0 {
slice_count += 1;
rest -= 1;
}
let mut slice_area: Vec<String> = Vec::new();
for _ in 1..=slice_count {
slice_area.push(area.pop().unwrap());
}
let t = thread::spawn(move || {
draw_circle_slice(host_string, slice_area);
});
threads.push(t);
}
for t in threads {
t.join().unwrap();
}
}
\ No newline at end of file
......@@ -147,6 +147,14 @@ fn main() {
.takes_value(true)
.required(true)
)
.arg(Arg::new("slices")
.short('s')
.long("slices")
.value_name("SLICES")
.about("Number of threads that should draw the circle")
.takes_value(true)
.required(true)
)
.arg(Arg::new("radius")
.short('r')
.long("radius")
......@@ -173,6 +181,11 @@ fn main() {
.required(false)
.default_value("0")
)
.arg(Arg::new("no-shuffle")
.long("no-shuffle")
.about("Disable the shuffling of the pixel draw order")
.required(false)
)
)
.get_matches();
......@@ -205,11 +218,13 @@ fn main() {
Some("circle") => {
let matches = matches.subcommand_matches("circle").unwrap();
let color = matches.value_of("color").unwrap();
let radius: u32 = matches.value_of_t_or_exit("radius");
let offset_x: u32 = matches.value_of_t_or_exit("offset-x");
let offset_y: u32 = matches.value_of_t_or_exit("offset-y");
let slices: u8 = matches.value_of_t_or_exit("slices");
let radius: u16 = matches.value_of_t_or_exit("radius");
let offset_x: u16 = matches.value_of_t_or_exit("offset-x");
let offset_y: u16 = matches.value_of_t_or_exit("offset-y");
let shuffle = !matches.is_present("no-shuffle");
circle::draw_circle(host, radius, offset_x, offset_y, color);
circle::draw_circle(host, color, slices, radius, offset_x, offset_y, shuffle);
}
None => {
println!("No subcommand specified!");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment