[−][src]Trait cichlid::math::ScalingInt
Scaling, Dimming, Brightening, and other misc functions functions for integers representing scalar components.
These functions are extremely useful for operating on integer color components,
such as the red/blue/green values seen in RGB
color encoding.
Notes on Fractional Components
These methods are used primarily for representing integers as fractions, rather than
whole numbers. They can also be treated as fractions, percents, or some otherwise
range-bounded scalar to a dimension. A more accurate way to represent this information
would be to use a f32
/f64
and clamping the result to a pre-defined range.
Integers are used as the math is significantly faster to compute, and floating values
aren't always available on all target platforms.
For example, a u8
takes on the range [0:255]
. The maximum value
of 255 doesn't represent the existence of 255 items, but rather being the maximum
possible scalar for a dimension. Respectively, the value of 0 is the minimum value
for a dimension.
As a by-product, these functions are saturating, hitting a ceiling at the maximum
possible value, and hitting a floor at the minimum possible value (usually 0,
except for _video
functions).
Terminology
_video
: The output is guaranteed to only be zero if at least one of the inputs is zero._lin
: Used only in brightening and dimming functions. If the input is below half of the maximum value, the value is brightened / dimmed linearly instead of scaled.
Required methods
fn scale(self, other: Self) -> Self
Scales self by a second one (scale
), which is treated as the numerator
of a fraction whose denominator is Self::MAX
.
In other words, it computes i * (scale / Self::MAX)
Example
use cichlid::ScalingInt; assert_eq!(100u8.scale(255), 100); // 100 * 1.0 assert_eq!(100u8.scale(0), 0); // 100 * 0.0 assert_eq!(100u8.scale(255 / 2), 50); // 100 * 0.5
fn scale_video(self, other: Self) -> Self
The "video" version of scale.
This version guarantees that the output will be only be zero if one or both of the inputs are zero. If both inputs are non-zero, the output is guaranteed to be non-zero.
This makes for better 'video'/LED dimming, at the cost of several additional cycles.
Example
use cichlid::ScalingInt; assert_eq!(100u8.scale_video(255), 100u8.scale(255)); // same as scale8... assert_ne!(1u8.scale_video(1), 1u8.scale(1)); // Except scale8() == 0
fn dim_raw(self) -> Self
Dims an integer.
The eye does not respond in a linear way to light. High speed PWM'd LEDs at 50% duty cycle appear far brighter then the 'half as bright' you might expect.
If you want your midpoint brightness level (for u8
, that'd be 128) to appear half as
bright as 'full' brightness (255 for u8
), you have to apply a dimming function.
Example
use cichlid::ScalingInt; let full_brightness: u8 = 255; assert_eq!(255, full_brightness.dim_raw()); let half_brightness: u8 = full_brightness / 2; assert_eq!(63, half_brightness.dim_raw());
fn dim_video(self) -> Self
Dims in video mode.
This is the same as dim_raw
, but the output of this function will only be zero if the
input is zero.
Example
use cichlid::ScalingInt; assert_eq!(255u8.dim_raw(), 255u8.dim_video()); assert_ne!(30u8.dim_raw(), 30u8.dim_video());
fn dim_lin(self) -> Self
Dims an integer linearly.
This is the same as dim_raw
, but when x < (Self::MAX / 2)
, the value is simply halved.
The output will only be zero if the input is zero.
fn brighten_raw(self) -> Self
Inverse of the dim_raw
function, brightens a value.
fn brighten_video(self) -> Self
Inverse of the dim_video
function, brightens a value.
fn brighten_lin(self) -> Self
Linear version of the brighten8_raw
, that halves for values < Self::MAX / 2
.
Notably, this is the relative inverse of dim_lin
.
fn blend(self, b: Self, amount_of_b: Self) -> Self
Blends self with another integer by the fraction amount_of_b
.