Skip to main content

DensitySet

Struct DensitySet 

Source
pub struct DensitySet {
    pub characters: Vec<char>,
    pub name: String,
}
Expand description

Character density set for intensity-based rendering

Maps intensity values [0.0, 1.0] to characters ordered from sparse (low intensity) to dense (high intensity). Provides smooth gradient effects for ASCII-art style visualizations.

§Algorithm

The mapping algorithm uses linear interpolation:

  1. Clamp intensity to [0.0, 1.0] range
  2. Calculate index: round(intensity * (length - 1))
  3. Return character at calculated index

This ensures:

  • Intensity 0.0 always maps to first character (sparsest)
  • Intensity 1.0 always maps to last character (densest)
  • Intermediate values distribute linearly across character array

§Examples

use dotmax::density::DensitySet;

// Create custom density set
let density = DensitySet::new(
    "Custom".to_string(),
    vec![' ', '.', ':', '#', '@']
).unwrap();

// Map intensity values
assert_eq!(density.map(0.0), ' ');   // First character
assert_eq!(density.map(0.5), ':');   // Middle character
assert_eq!(density.map(1.0), '@');   // Last character

// Out-of-range intensities are clamped
assert_eq!(density.map(-0.5), ' ');  // Clamped to 0.0
assert_eq!(density.map(1.5), '@');   // Clamped to 1.0

Fields§

§characters: Vec<char>

Characters ordered from sparse (low intensity) to dense (high intensity)

§name: String

Descriptive name for this density set

Implementations§

Source§

impl DensitySet

Source

pub fn new(name: String, characters: Vec<char>) -> Result<Self, DotmaxError>

Create custom density set with validation

Creates a new density set from a character array. Characters must be ordered from sparse (low visual density) to dense (high visual density).

§Arguments
  • name: Descriptive name for the density set
  • characters: Character array ordered sparse to dense
§Validation Rules
  • Character list must not be empty (at least 1 character required)
  • Character list must not exceed 256 characters (performance limit)
  • No validation of character ordering (user responsibility)
§Errors

Returns DotmaxError::EmptyDensitySet if characters is empty.

Returns DotmaxError::TooManyCharacters if characters.len() > 256.

§Examples
use dotmax::density::DensitySet;

// Valid: Create custom density set
let density = DensitySet::new(
    "Emoji".to_string(),
    vec!['🌑', '🌒', '🌓', '🌔', '🌕']
).unwrap();
assert_eq!(density.characters.len(), 5);

// Error: Empty character list
let result = DensitySet::new("Empty".to_string(), vec![]);
assert!(result.is_err());

// Error: Too many characters (>256)
let too_many: Vec<char> = (0..300).map(|i| (i as u8) as char).collect();
let result = DensitySet::new("TooMany".to_string(), too_many);
assert!(result.is_err());
Source

pub fn map(&self, intensity: f32) -> char

Map intensity value [0.0, 1.0] to character

Maps a floating-point intensity value to a character from the density set using linear interpolation. Intensity values are clamped to [0.0, 1.0] range, so out-of-range values are handled gracefully.

§Algorithm
  1. Clamp intensity: clamped = intensity.clamp(0.0, 1.0)
  2. Calculate index: index = round(clamped * (len - 1))
  3. Return: characters[index]
§Arguments
  • intensity: Intensity value, ideally in [0.0, 1.0] range
    • 0.0 = darkest (first character)
    • 1.0 = brightest (last character)
    • Out-of-range values are clamped
§Examples
use dotmax::density::DensitySet;

let density = DensitySet::simple();

// Boundary values
assert_eq!(density.map(0.0), ' ');  // First character (sparsest)
assert_eq!(density.map(1.0), '@');  // Last character (densest)

// Middle value
let mid_char = density.map(0.5);
assert!(mid_char == '+' || mid_char == '*');  // Approximate middle

// Out-of-range values are clamped
assert_eq!(density.map(-0.5), ' '); // Clamped to 0.0 → first char
assert_eq!(density.map(1.5), '@');  // Clamped to 1.0 → last char
assert_eq!(density.map(f32::NAN), ' '); // NaN clamped to 0.0
Source

pub fn ascii() -> Self

Create predefined ASCII density set (69 characters)

Returns a density set with the full ASCII gradient, providing maximum smoothness for detailed visualizations. Works on all terminals with 7-bit ASCII support.

§Examples
use dotmax::density::DensitySet;

let density = DensitySet::ascii();
assert_eq!(density.name, "ASCII");
assert_eq!(density.characters.len(), 69);
Source

pub fn simple() -> Self

Create predefined simple density set (10 characters)

Returns a density set with a simple 10-character gradient, ideal for quick prototypes and minimalist visualizations.

§Examples
use dotmax::density::DensitySet;

let density = DensitySet::simple();
assert_eq!(density.name, "Simple");
assert_eq!(density.characters.len(), 10);
Source

pub fn blocks() -> Self

Create predefined Unicode blocks density set (5 characters)

Returns a density set using Unicode block drawing characters for smooth gradients. Requires modern terminal with Unicode support.

§Examples
use dotmax::density::DensitySet;

let density = DensitySet::blocks();
assert_eq!(density.name, "Blocks");
assert_eq!(density.characters.len(), 5);
Source

pub fn braille() -> Self

Create predefined braille density set (9 characters)

Returns a density set using braille Unicode characters for density progression. Unique to dotmax, combines density rendering with braille theme.

§Examples
use dotmax::density::DensitySet;

let density = DensitySet::braille();
assert_eq!(density.name, "Braille");
assert_eq!(density.characters.len(), 9);

Trait Implementations§

Source§

impl Clone for DensitySet

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for DensitySet

Source§

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

Formats the value using the given formatter. Read more

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> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

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

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

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 more
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 = !

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

fn try_from(value: U) -> Result<T, !>

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> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more