pub struct LSystem {
pub axiom: String,
pub rules: HashMap<char, String>,
}
Expand description
§LSystem
What it says on the box; a simple L-system implementation for use with plotter based fractal art.
§Example
use aoer_plotty_rs::turtle::{TurtleTrait, Turtle, degrees};
use aoer_plotty_rs::l_system::LSystem;
use aoer_plotty_rs::geo_types::nannou::NannouDrawer;
use std::collections::HashMap;
use nannou::lyon::tessellation::{LineCap, LineJoin};
use nannou::Draw;
let draw = Draw::new();
let gosper = LSystem{
axiom: "A".to_string(),
rules: HashMap::from([
('A', "A-B--B+A++AA+B-".to_string()),
('B', "+A-BB--B-A++A+B". to_string())])
};
let tlines = Turtle::new()
.pen_down()
.walk_lpath(&gosper.expand(4), degrees(60.0), 8.0)
.to_multiline();
for line in tlines {
draw.polyline()
.stroke_weight(3.0)
.caps(LineCap::Round)
.join(LineJoin::Round)
.polyline_from_linestring(&line)
.color(nannou::color::NAVY);
}
Fields§
§axiom: String
§rules: HashMap<char, String>
Implementations§
Source§impl LSystem
impl LSystem
Sourcepub fn expand(&self, order: u32) -> String
pub fn expand(&self, order: u32) -> String
#expand
Expands the L-system by the requested “order” of iterations. Returns a string
representing the state of the L-system. Useful with
crate::turtle::TurtleTrait::walk_lpath
Examples found in repository?
examples/gosper_lsys_turtle_nannou.rs (line 44)
24fn model(_app: &App) -> Model {
25 // Create a turtle
26 let mut t = Turtle::new();
27 // And put its pen down so that it is drawing.
28 t = t.pen_down();
29
30 // Create a new LSystem, which defines a Gosper curve. We'll be expanding this
31 // into a path next.
32 let gosper = LSystem {
33 axiom: "A".to_string(),
34 rules: HashMap::from([
35 ('A', "A-B--B+A++AA+B-".to_string()),
36 ('B', "+A-BB--B-A++A+B".to_string())]),
37 };
38
39 // Create a MultiLineString via the Turtle
40 let tlines = t
41 // Use the turtle's TurtleTrait to walk an LPath, which is given by...
42 .walk_lpath(
43 // Expanding the gosper system we just created, on the 4th order
44 &gosper.expand(4), degrees(60.0), 8.0)
45 // And convert to multiline
46 .to_multiline();
47
48 // Find the center of the drawing
49 let bc = tlines.bounding_rect().unwrap().bounding_rect().center();
50
51 // Center it
52 let tlines = tlines.translate(-bc.x, -bc.y);
53
54 // We're done. Save it in the model.
55 Model {
56 loops: 0,
57 tlines
58 }
59}
More examples
examples/gosper_svg.rs (line 29)
8fn main() {
9 // First, we create a new Turtle, which is capable of drawing things.
10 let mut t = Turtle::new();
11
12 // And put its pen down so that it is drawing.
13 t = t.pen_down();
14
15 // Create a new LSystem, which defines a Gosper curve. We'll be expanding this
16 // into a path next.
17 let gosper = LSystem {
18 axiom: "A".to_string(),
19 rules: HashMap::from([
20 ('A', "A-B--B+A++AA+B-".to_string()),
21 ('B', "+A-BB--B-A++A+B".to_string())]),
22 };
23
24 // Create a MultiLineString via the Turtle
25 let tlines = t
26 // Use the turtle's TurtleTrait to walk an LPath, which is given by...
27 .walk_lpath(
28 // Expanding the gosper system we just created, on the 4th order
29 &gosper.expand(3), degrees(60.0), 8.0)
30 // And convert to multiline
31 .to_multiline();
32
33 // Define our viewbox/canvas (in mm)
34 let viewbox = Rect::new(
35 coord! {x:0f64, y:0f64},
36 coord! {x: 300f64, y:400f64});
37
38 // Define an arrangement where we center the Gosper Curve in the center
39 // of the page, with the viewbox of 300mmx400mm as the canvas.
40 let arrangement = Arrangement::FitCenter(viewbox, true);
41
42 // Now we create the base SVG document from our arrangement,
43 // and use the to_path feature to create a path for the lines.
44 // Note that you can call that add multiple times, but if you
45 // do, you should use a set transformation instead of just fit/center
46 // which could misalign separate path sets (or just use MultiLineString
47 // with several LineStrings inside to consistently draw and align).
48 let svg = arrangement.create_svg_document().unwrap()
49 .add(tlines.to_path(&arrangement))
50 .set("fill", "none")
51 .set("stroke", "black")
52 .set("stroke-width", 2)
53 .set("stroke-linejoin", "round")
54 .set("stroke-linecap", "round");
55
56 // Write it to the images folder, so we can use it as an example!
57 svg::save("images/gosper-to-svg-example.svg", &svg).unwrap();
58}
Trait Implementations§
Auto Trait Implementations§
impl Freeze for LSystem
impl RefUnwindSafe for LSystem
impl Send for LSystem
impl Sync for LSystem
impl Unpin for LSystem
impl UnwindSafe for LSystem
Blanket Implementations§
Source§impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for S
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for S
Source§fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<Swp, Dwp, T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<Swp, Dwp, T>,
Convert the source color to the destination color using the specified
method
Source§fn adapt_into(self) -> D
fn adapt_into(self) -> D
Convert the source color to the destination color using the bradford
method by default
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T, U> ConvertInto<U> for Twhere
U: ConvertFrom<T>,
impl<T, U> ConvertInto<U> for Twhere
U: ConvertFrom<T>,
Source§fn convert_into(self) -> U
fn convert_into(self) -> U
Convert into T with values clamped to the color defined bounds Read more
Source§fn convert_unclamped_into(self) -> U
fn convert_unclamped_into(self) -> U
Convert into T. The resulting color might be invalid in its color space Read more
Source§fn try_convert_into(self) -> Result<U, OutOfBounds<U>>
fn try_convert_into(self) -> Result<U, OutOfBounds<U>>
Convert into T, returning ok if the color is inside of its defined range,
otherwise an
OutOfBounds
error is returned which contains the unclamped color. Read moreSource§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
The inverse inclusion map: attempts to construct
self
from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
Checks if
self
is actually part of its subset T
(and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
Use with care! Same as
self.to_subset
but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
The inclusion map: converts
self
to the equivalent element of its superset.