JSONDrawRules

Enum JSONDrawRules 

Source
pub enum JSONDrawRules {
    Simple {
        replacement: HashMap<char, String>,
        angle_numerator: isize,
        angle_denominator: usize,
        start: String,
    },
    Advanced {
        replacement: HashMap<char, String>,
        draw_step_sizes: HashMap<char, f64>,
        move_step_sizes: HashMap<char, f64>,
        angle_numerator: isize,
        angle_denominator: usize,
        start: String,
    },
    Full {
        replacement: HashMap<char, String>,
        assignment: HashMap<char, JSONDrawAction>,
        start: String,
    },
}
Expand description

Represents user input from JSON of the L-System rules, for conversion into DrawRules.

Variants§

§

Simple

Most basic specification syntax for rules.

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::parse_files::{JSONDrawAction, JSONDrawRules};
use l_system_fractals::rules::{
    DrawAction,
    DrawRules,
    InitializedDrawRules,
    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 json_string = r#"{
    "type": "Simple",
    "replacement": {"A": "A+A--A+A"},
    "angle_numerator": 1,
    "angle_denominator": 3,
    "start": "+A--A--A"
}"#;

let json_dr: JSONDrawRules = serde_json::from_str(json_string).unwrap();
let dr1: InitializedDrawRules = json_dr.try_into().unwrap();

let rwr = RewriteRules(HashMap::from([('A', "A+A--A+A".into())]));
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 = InitializedDrawRules {
    draw_rules: DrawRules {
        rewrite_rules: rwr,
        assignment,
    },
    start: "+A--A--A".into()
};
assert!(dr1.almost_eq(&dr2, 0.001));

Fields

§replacement: HashMap<char, String>

Describes the replacement used in each iteration step.

§angle_numerator: isize

Numerator of fraction of π to rotate.

§angle_denominator: usize

Denominator of fraction of π to rotate.

§start: String

Initial string.

§

Advanced

A more advanced specification syntax for rules that provides more flexibility.

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::parse_files::{JSONDrawAction, JSONDrawRules};
use l_system_fractals::rules::{
    DrawAction,
    DrawRules,
    InitializedDrawRules,
    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 json_string = r#"{
    "type": "Advanced",
    "replacement": { "A": "A+BA-AA-A-AA+B+AA-BA+AA+A+AA-B-AAA", "B": "BBBBBB" },
    "draw_step_sizes": { "A": 1.0 },
    "move_step_sizes": { "B": 1.0 },
    "angle_numerator": 1,
    "angle_denominator": 2,
    "start": "A-A-A-A-"
}"#;

let json_dr: JSONDrawRules = serde_json::from_str(json_string).unwrap();
let dr1: InitializedDrawRules = json_dr.try_into().unwrap();

let rwr = RewriteRules(HashMap::from([
    ('A', "A+BA-AA-A-AA+B+AA-BA+AA+A+AA-B-AAA".into()),
    ('B', "BBBBBB".into())
]));
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 = InitializedDrawRules {
    draw_rules: DrawRules {
        rewrite_rules: rwr,
        assignment
    },
    start: "A-A-A-A-".into()
};

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

Fields

§replacement: HashMap<char, String>

Describes the replacement used in each iteration step.

§draw_step_sizes: HashMap<char, f64>

Used to define which characters will represent drawing forward (and how much).

§move_step_sizes: HashMap<char, f64>

Used to define which characters will represent moving forward (and how much).

§angle_numerator: isize

Numerator of fraction of π to rotate.

§angle_denominator: usize

Denominator of fraction of π to rotate.

§start: String

Initial string.

§

Full

A specification syntax that allows for complete flexibility.

§Example

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

use l_system_fractals::parse_files::{JSONDrawAction, JSONDrawRules};
use l_system_fractals::rules::{
    DrawAction,
    DrawRules,
    InitializedDrawRules,
    RuleAssignment,
    RewriteRules
};
use l_system_fractals::num_validity::AlmostEq;

let json_string = r#"{
    "type": "Full",
    "replacement": {
      "A": "A[A{B<AX",
      "B": "BBBB",
      "X": "}+A{>+A<]+A["
    },
    "assignment": {
      "A": { "type": "DrawForward", "dist": 1.0 },
      "B": { "type": "MoveForward", "dist": 1.0 },
      "X": { "type": "Null" },
      "[": { "type": "Push", "stack": 0 },
      "{": { "type": "Push", "stack": 1 },
      "<": { "type": "Push", "stack": 2 },
      "]": { "type": "Pop", "stack": 0 },
      "}": { "type": "Pop", "stack": 1 },
      ">": { "type": "Pop", "stack": 2 },
      "+": { "type": "RotateCW", "numerator": 2, "denominator": 9 }
    },
    "start": "+A+A+A+A+A+A+A+A+A"
}"#;

let json_dr: JSONDrawRules = serde_json::from_str(json_string).unwrap();
let dr1: InitializedDrawRules = json_dr.try_into().unwrap();

let rwr = RewriteRules(HashMap::from([
      ('A', "A[A{B<AX".into()),
      ('B', "BBBB".into()),
      ('X', "}+A{>+A<]+A[".into())
]));
let assignment = RuleAssignment(
    HashMap::from([
        ('A', DrawAction::DrawForward(1.0)),
        ('B', DrawAction::MoveForward(1.0)),
        ('X', DrawAction::Null),
        ('+', DrawAction::RotateCW(2.0 * PI/9.0)),
        ('[', DrawAction::Push(0)),
        ('{', DrawAction::Push(1)),
        ('<', DrawAction::Push(2)),
        (']', DrawAction::Pop(0)),
        ('}', DrawAction::Pop(1)),
        ('>', DrawAction::Pop(2)),
    ])
);

let dr2 = InitializedDrawRules {
    draw_rules: DrawRules {
        rewrite_rules: rwr,
        assignment
    },
    start: "+A+A+A+A+A+A+A+A+A".into()
};
assert!(dr1.almost_eq(&dr2, 0.001));

Fields

§replacement: HashMap<char, String>

Describes the replacement used in each iteration step.

§assignment: HashMap<char, JSONDrawAction>

Specification of a JSONDrawAction for each character.

§start: String

Initial string.

Trait Implementations§

Source§

impl AlmostEq for JSONDrawRules

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 JSONDrawRules

Source§

fn clone(&self) -> JSONDrawRules

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 JSONDrawRules

Source§

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

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

impl<'de> Deserialize<'de> for JSONDrawRules

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for JSONDrawRules

Source§

fn eq(&self, other: &JSONDrawRules) -> 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 TryFrom<JSONDrawRules> for InitializedDrawRules

Source§

type Error = LSystemError

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

fn try_from(json_input: JSONDrawRules) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl StructuralPartialEq for JSONDrawRules

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.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,