Sierpinski square curve: Difference between revisions

Added Rust solution
m (Minor edit)
(Added Rust solution)
Line 367:
);</lang>
See: [https://github.com/thundergnat/rc/blob/master/img/sierpinski-square-curve-perl6.svg Sierpinski-square-curve-perl6.svg] (offsite SVG image)
 
=={{header|Rust}}==
Program output is a file in SVG format.
<lang rust>// [dependencies]
// svg = "0.8.0"
 
use svg::node::element::path::Data;
use svg::node::element::Path;
 
struct SierpinskiSquareCurve {
current_x : f64,
current_y : f64,
current_angle : i32,
line_length : f64
}
 
impl SierpinskiSquareCurve {
fn new(x : f64, y : f64, length : f64, angle : i32) -> SierpinskiSquareCurve {
SierpinskiSquareCurve {
current_x : x,
current_y : y,
current_angle : angle,
line_length : length
}
}
fn rewrite(order : usize) -> String {
let mut str = String::from("F+XF+F+XF");
for _ in 0..order {
let mut tmp = String::new();
for ch in str.chars() {
match ch {
'X' => tmp.push_str("XF-F+F-XF+F+XF-F+F-X"),
_ => tmp.push(ch)
}
}
str = tmp;
}
str
}
fn execute(&mut self, order : usize) -> Path {
let mut data = Data::new().move_to((self.current_x, self.current_y));
for ch in SierpinskiSquareCurve::rewrite(order).chars() {
match ch {
'F' => data = self.draw_line(data),
'+' => self.turn(90),
'-' => self.turn(-90),
_ => {}
}
}
Path::new()
.set("fill", "none")
.set("stroke", "black")
.set("stroke-width", "1")
.set("d", data)
}
fn draw_line(&mut self, data : Data) -> Data {
use std::f64::consts::PI;
let theta = (PI * self.current_angle as f64) / 180.0;
self.current_x += self.line_length * theta.cos();
self.current_y -= self.line_length * theta.sin();
data.line_to((self.current_x, self.current_y))
}
fn turn(&mut self, angle : i32) {
self.current_angle = (self.current_angle + angle) % 360;
}
fn save(file : &str, size : usize, order : usize) -> std::io::Result<()> {
use svg::node::element::Rectangle;
let x = 315.0;
let y = 630.0;
let rect = Rectangle::new()
.set("width", "100%")
.set("height", "100%")
.set("fill", "white");
let mut hilbert = SierpinskiSquareCurve::new(x, y, 5.0, 0);
let document = svg::Document::new()
.set("width", size)
.set("height", size)
.add(rect)
.add(hilbert.execute(order));
svg::save(file, &document)
}
}
 
fn main() {
SierpinskiSquareCurve::save("sierpinski_square_curve.svg", 635, 5).unwrap();
}</lang>
 
=={{header|Sidef}}==
1,777

edits