Created
November 10, 2021 23:54
-
-
Save JeanRibes/7f2e973f96667427d95b945454d3ed48 to your computer and use it in GitHub Desktop.
compilateur LOGO en rust, sortie SVG dans le terminal
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
use std::ops::Add; | |
use std::borrow::Borrow; | |
use crate::Instruction::{Forward, Left, Right, Repeat}; | |
use std::panic::panic_any; | |
use std::f64::consts::PI; | |
use std::fs::File; | |
use std::io::Write; | |
#[derive(Clone)] | |
enum Instruction { | |
Forward(u8), | |
Left(u8), | |
Right(u8), | |
Repeat(u8, Vec<Instruction>), | |
} | |
#[derive(Clone)] | |
struct Crayon { | |
x: f64, | |
y: f64, | |
t: f64, | |
} | |
#[derive(Clone)] | |
enum Point { | |
Point(f64, f64) | |
} | |
fn ins_to_str(ins: Instruction) -> String { | |
return match ins { | |
Forward(x) => format!("Forward {}", x).to_string(), | |
Left(x) => format!("Left {}", x).to_string(), | |
Right(x) => format!("Right {}", x).to_string(), | |
Repeat(repeat, prgm) => { | |
let mut res = format!("Repeat {} [", repeat).to_string(); | |
for subi in prgm { | |
res += ins_to_str(subi).as_str(); | |
res += ", "; | |
} | |
return res + "]"; | |
} | |
}; | |
} | |
fn print_instructions(prgm: Vec<Instruction>) { | |
println!("{}", ins_to_str(Repeat(1, prgm))); | |
} | |
fn flatten(prgm_in: Vec<Instruction>, mut prgm_out: Vec<Instruction>) -> Vec<Instruction> { | |
for ins in prgm_in { | |
match ins { | |
Repeat(repeat, sub_prgm) => { | |
for i in (0..repeat) { | |
prgm_out = flatten(Vec::from(sub_prgm.borrow()), prgm_out); | |
} | |
} | |
_ => { | |
prgm_out.push(ins.clone()); | |
} | |
} | |
} | |
return prgm_out; | |
} | |
fn draw_ins(mut crayon: Crayon, ins: Instruction) -> Crayon { | |
match ins { | |
Forward(l) => { | |
crayon.x += f64::from(l) * crayon.t.cos(); | |
crayon.y += f64::from(l) * crayon.t.sin(); | |
} | |
Left(t) => { | |
crayon.t -= f64::from(t) * PI / f64::from(180); | |
} | |
Right(t) => { | |
crayon.t += f64::from(t) * PI / f64::from(180); | |
} | |
Repeat(_, _) => { | |
panic_any("flatten() forgotten"); | |
} | |
} | |
return crayon; | |
} | |
fn turle(prgm: Vec<Instruction>) -> Vec<Point> { | |
let mut crayon = Crayon { | |
x: 150.0, | |
y: 150.0, | |
t: 0.0, | |
}; | |
let mut coords: Vec<Point> = Vec::new(); | |
for ins in prgm { | |
crayon = draw_ins(crayon, ins); | |
coords.push(Point::Point(crayon.x, crayon.y)); | |
} | |
return coords; | |
} | |
fn main() { | |
/*let prgm = vec![Forward(10), Left(90), Forward(10), | |
Repeat(2, vec![Forward(20), Right(10)])];*/ | |
// [ Repeat 36 [ Right 10, Repeat 8 [ Forward 25, Left 45 ] ]] | |
let prgm = vec![Repeat(36, vec![Right(10),Repeat(8,vec![Forward(25), Left(45)])])]; | |
//print_instructions(Vec::from(prgm.borrow())); | |
let mut flattened = Vec::new(); | |
flattened = flatten(prgm, flattened); | |
//print_instructions(flattened.clone()); | |
let coords = turle(flattened); | |
/*for Point::Point(x, y) in Vec::from(coords.borrow()) { | |
println!("{} {}", x, y) | |
}*/ | |
let mut file = match File::open("./logo.svg") { | |
Err(why) => panic!("couldn't open file: {}", why), | |
Ok(file) => file, | |
}; | |
println!("<?xml version=\"1.0\" encoding=\"utf-8\"?><svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"300\" height=\"300\">\n<title>SVG Jean et El Hadj</title>"); | |
let mut x0: f64 = 150 as f64; | |
let mut y0: f64 = 150 as f64; | |
for Point::Point(x, y) in coords { | |
println!("<line x1=\"{}\" y1=\"{}\" x2=\"{}\" y2=\"{}\" stroke=\"red\" stroke-width=\"1\" />", x0, y0, x, y); | |
x0=x; | |
y0=y; | |
} | |
println!("</svg>"); | |
file.flush(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment