commit 439f4859b853006aab7877c4fcc3b9f49f748043 Author: Sameer Puri Date: Sat Apr 20 18:51:50 2019 -0500 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f0e3bca --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +**/*.rs.bk \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..fdd303b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,116 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cairo-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glib 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "glib" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "glib-sys" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "gobject-sys" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lsys" +version = "0.1.0" +dependencies = [ + "cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pkg-config" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e09d8a818b2ccc8983f04d95a9350c3cf8d24cc456cedca3b88fa3a81fdc0e2" +"checksum cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fa13914fdc013387afa771f554f2f71d6ae931f4e5be9246c337d60c3dc484" +"checksum glib 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e8fdc159c196a5dfa53a92929ac4c10c8a6637ffb43951f3fff89c2cd2365" +"checksum glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bda542f3caee39a027638e9644ff89204101ad916fd7370b585ad2c5fc97e61" +"checksum gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23e05a14290d3dc255223cba51db4b0f3da438d5250657996fa99b2a30faf43e" +"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..dd778b0 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "lsys" +version = "0.1.0" +authors = ["purisame"] +edition = "2018" + +[dependencies] +cairo-rs = { version = "^0", features = ["svg"] } diff --git a/README.md b/README.md new file mode 100644 index 0000000..603deec --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# L-systems in Rust + +Renderings of various L-systems using Rust and Cairo. + +## Sierpinski Triangle +![sierpinski](out/sierpinski.svg) + +## Sierpinski Arrowhead +![arrowhead](out/arrowhead.svg) + +## Koch Curve +![koch](out/koch.svg) + +## Dragon Curve +![dragon](out/dragon.svg) diff --git a/out/arrowhead.svg b/out/arrowhead.svg new file mode 100644 index 0000000..faaf7c0 --- /dev/null +++ b/out/arrowhead.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/out/dragon.svg b/out/dragon.svg new file mode 100644 index 0000000..2f824c1 --- /dev/null +++ b/out/dragon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/out/koch.svg b/out/koch.svg new file mode 100644 index 0000000..2da1c7e --- /dev/null +++ b/out/koch.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/out/sierpinski.svg b/out/sierpinski.svg new file mode 100644 index 0000000..f0ed46e --- /dev/null +++ b/out/sierpinski.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..8a1ad64 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,119 @@ +extern crate cairo; + +use cairo::{svg, Context}; +use std::fs::File; +use std::io::Write; + +fn main() { + koch(); + sierpinski(); + arrowhead(); + dragon(); +} + +fn koch() { + let mut out = File::create("koch.svg").unwrap(); + run( + "F", + &['F'], + |c: char| match c { + 'F' => "F+F-F-F+F".chars().collect(), + other => vec![other], + }, + std::f64::consts::PI / 2., + 4, + &mut out, + ); +} + +fn sierpinski() { + let mut out = File::create("sierpinski.svg").unwrap(); + run( + "F-G-G", + &['F', 'G'], + |c: char| match c { + 'F' => "F-G+F+G-F".chars().collect(), + 'G' => "GG".chars().collect(), + other => vec![other], + }, + std::f64::consts::PI * 2. / 3., + 4, + &mut out, + ); +} + +fn arrowhead() { + let mut out = File::create("arrowhead.svg").unwrap(); + run( + "A", + &['A', 'B'], + |c: char| match c { + 'A' => "B-A-B".chars().collect(), + 'B' => "A+B+A".chars().collect(), + other => vec![other], + }, + std::f64::consts::PI * 1. / 3., + 4, + &mut out, + ); +} + +fn dragon() { + let mut out = File::create("dragon.svg").unwrap(); + run( + "FX", + &['F'], + |c: char| match c { + 'X' => "X+YF+".chars().collect(), + 'Y' => "-FX-Y".chars().collect(), + other => vec![other], + }, + std::f64::consts::PI / 2., + 10, + &mut out, + ); +} + +fn run(axiom: &str, variables: &[char], rules: F, angle: f64, iterations: usize, writer: W) +where + F: Fn(char) -> Vec + Copy, + W: Write, +{ + let surf = svg::Writer::new(1024.0, 1024.0, writer); + let ctx = Context::new(&surf); + ctx.scale(1024., 1024.); + + ctx.set_line_width(0.001); + ctx.set_source_rgb(0., 0., 0.); + + let mut state = axiom.to_string(); + + for _ in 0..iterations { + state = state.chars().map(rules).flatten().collect(); + } + + // let segment_count = state.chars().filter(|c| variables.contains(&c)).count(); + + + ctx.move_to(0.0, 0.5); + for c in state.chars() { + match c { + '+' => { + ctx.rotate(-angle); + } + '-' => { + ctx.rotate(angle); + } + other => { + if variables.contains(&other) { + ctx.rel_line_to(0.01, 0.0); + } + } + } + } + ctx.stroke(); + + // let mut fout = File::create("out.png").unwrap(); + // surf.write_all(&mut fout).unwrap(); + // println!("{}", axiom); +}