DrawRules

Struct DrawRules 

Source
pub struct DrawRules {
    pub rewrite_rules: RewriteRules,
    pub assignment: RuleAssignment,
}
Expand description

Gives the specification for an L-system, excluding the initial string.

Fields§

§rewrite_rules: RewriteRules

The rewriting rules.

§assignment: RuleAssignment

The assignment of characters to draw actions.

Implementations§

Source§

impl DrawRules

Source

pub fn new( rewrite_rules: HashMap<char, String>, assignment: HashMap<char, DrawAction>, ) -> Self

Creates DrawRules with the given rewrite rules and rule assignments given as HashMaps.

§Example
use std::collections::HashMap;
use std::f64::consts::PI;

use l_system_fractals::rules::{DrawAction, DrawRules};
use l_system_fractals::num_validity::AlmostEq;

// Koch snowflake
// from Benoit B. Mandelbrot (1983), _The Fractal Geometry of Nautre (Updated and
// Agumented)_, New York: W.H. Freeman and Company, p. 42

let rwr_hm: HashMap<char, String> = HashMap::from([('A', "A+A--A+A".into())]);
let assignment_hm: HashMap<char, DrawAction> =  HashMap::from([
   ('A', DrawAction::DrawForward(1.0)),
   ('+', DrawAction::RotateCW(PI/3.0)),
   ('-', DrawAction::RotateCW(-PI/3.0))
]);

let dr1 = DrawRules::new(rwr_hm.clone(), assignment_hm.clone());
let dr2 = DrawRules { rewrite_rules: rwr_hm.into(), assignment: assignment_hm.into() };

assert!(dr1.almost_eq(&dr2, 0.001));
Source

pub fn new_simple( replacement: HashMap<char, String>, angle_numerator: isize, angle_denominator: usize, ) -> Result<Self, LSystemError>

Creates a new DrawRules with the specified replacement rules and angle.

The resulting DrawRules will have the following properties:

  • The following commands are defined:

    • +: rotate clockwise by angle
    • -: rotate counterclockwise by angle
    • [: push current location/angle pair onto stack 0
    • ]: pop location/angle pair off of stack 0
  • The angle is specified as PI * angle_numerator / angle_denominator.

  • Every other character represents drawing forward a distance of 1.0.

§Example
use std::collections::HashMap;
use std::f64::consts::PI;

use l_system_fractals::rules::{DrawAction, DrawRules, RuleAssignment, RewriteRules};
use l_system_fractals::num_validity::AlmostEq;

// Koch snowflake
// from Benoit B. Mandelbrot (1983), _The Fractal Geometry of Nautre (Updated and
// Agumented)_, New York: W.H. Freeman and Company, p. 42

let rwr_hm = HashMap::from([('A', "A+A--A+A".into())]);
let angle_numerator: isize = 1;
let angle_denominator: usize = 3;

let dr1 = DrawRules::new_simple(
    rwr_hm.clone(),
    angle_numerator,
    angle_denominator
).unwrap();

let rwr = RewriteRules(rwr_hm);
let assignment = RuleAssignment(
    HashMap::from([
        ('A', DrawAction::DrawForward(1.0)),
        ('+', DrawAction::RotateCW(PI/3.0)),
        ('-', DrawAction::RotateCW(-PI/3.0)),
        ('[', DrawAction::Push(0)),
        (']', DrawAction::Pop(0))
    ])
);

let dr2 = DrawRules {
    rewrite_rules: rwr,
    assignment,
};

assert!(dr1.almost_eq(&dr2, 0.001));
Source

pub fn new_advanced( replacement: HashMap<char, String>, draw_step_sizes: HashMap<char, f64>, move_step_sizes: HashMap<char, f64>, angle_numerator: isize, angle_denominator: usize, ) -> Result<Self, LSystemError>

Creates a new DrawRules with the specified replacement rules, draw and move distances, and angle.

The resulting DrawRules will have the following properties:

  • The following commands are defined:

    • +: rotate clockwise by angle
    • -: rotate counterclockwise by angle
    • [: push current location/angle pair onto stack 0
    • ]: pop location/angle pair off of stack 0
  • The angle is specified as PI * angle_numerator / angle_denominator.

  • Other characters are mapped to drawing or moving forward based on the fields draw_step_sizes and move_step_sizes.

  • Any other character is mapped to Null.

§Example
use std::collections::HashMap;
use std::f64::consts::PI;

use l_system_fractals::rules::{DrawAction, DrawRules, RuleAssignment, RewriteRules};
use l_system_fractals::num_validity::AlmostEq;

// Islands
// from Benoit B. Mandelbrot (1983), _The Fractal Geometry of Nautre (Updated and
// Agumented)_, New York: W.H. Freeman and Company, p. 121

let replacement = HashMap::from([
    ('A', "A+BA-AA-A-AA+B+AA-BA+AA+A+AA-B-AAA".into()),
    ('B', "BBBBBB".into())
]);
let draw_step_sizes = HashMap::from([('A', 1.0)]);
let move_step_sizes = HashMap::from([('B', 1.0)]);
let angle_numerator: isize = 1;
let angle_denominator: usize = 2;

let dr1 = DrawRules::new_advanced(
    replacement.clone(),
    draw_step_sizes,
    move_step_sizes,
    angle_numerator,
    angle_denominator,
).unwrap();

let rwr = RewriteRules(replacement);
let assignment = RuleAssignment(
    HashMap::from([
        ('A', DrawAction::DrawForward(1.0)),
        ('B', DrawAction::MoveForward(1.0)),
        ('+', DrawAction::RotateCW(PI/2.0)),
        ('-', DrawAction::RotateCW(-PI/2.0)),
        ('[', DrawAction::Push(0)),
        (']', DrawAction::Pop(0))
    ])
);

let dr2 = DrawRules {
    rewrite_rules: rwr,
    assignment,
};

assert!(dr1.almost_eq(&dr2, 0.001));
Source

pub fn make_path( &self, s: String, start: Point, start_angle: f64, ) -> Result<Path, LSystemError>

Applies the the rules to the intial string s to create a path with given starting point and angle.

§Example
use std::collections::HashMap;

use l_system_fractals::rules::DrawRules;
use l_system_fractals::paths::{Path, Point};
use l_system_fractals::num_validity::AlmostEq;

let dw = DrawRules::new_simple(
    HashMap::from([
        ('A', "A-C+B+C-A".into()),
        ('B', "BBB".into()),
        ('C', "C".into())
    ]),
    1,
    2
).unwrap();

let pth1 = dw.make_path(
    "A-C+B+C-A".into(),
    Point::new(1.0, 5.0),
    0.0
).unwrap();

let pth2 = Path::from(
    vec![
        Point::new(1.0, 5.0),
        Point::new(2.0, 5.0),
        Point::new(2.0, 4.0),
        Point::new(3.0, 4.0),
        Point::new(3.0, 5.0),
        Point::new(4.0, 5.0)
    ]
);

assert!(pth1.almost_eq(&pth2, 0.001));
Source

pub fn make_default_path(&self, s: String) -> Result<Path, LSystemError>

Applies the rules to the string s to create a path from the default starting point (Point::new(0.0, 0.0)) and angle (0).

§Example
use std::collections::HashMap;

use l_system_fractals::rules::DrawRules;
use l_system_fractals::paths::{Path, Point};
use l_system_fractals::num_validity::AlmostEq;

let dw = DrawRules::new_simple(
    HashMap::from([
        ('A', "A-C+B+C-A".into()),
        ('B', "BBB".into()),
        ('C', "C".into())
    ]),
    1,
    2
).unwrap();

let pth1 = dw.make_default_path(
    "A-C+B+C-A".into(),
).unwrap();

let pth2 = Path::from(
    vec![
        Point::new(0.0, 0.0),
        Point::new(1.0, 0.0),
        Point::new(1.0, -1.0),
        Point::new(2.0, -1.0),
        Point::new(2.0, 0.0),
        Point::new(3.0, 0.0)
    ]
);

assert!(pth1.almost_eq(&pth2, 0.001));

Trait Implementations§

Source§

impl AlmostEq for DrawRules

Source§

fn almost_eq(&self, other: &Self, epsilon: f64) -> bool

Returns true if the distance between objects is less than epsilon.
Source§

impl Clone for DrawRules

Source§

fn clone(&self) -> DrawRules

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DrawRules

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for DrawRules

Source§

fn eq(&self, other: &DrawRules) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for DrawRules

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.