Improve tooltip docs with Markdown styling and refined math node explanations (#3488)

This commit is contained in:
Keavon Chambers
2025-12-20 01:05:15 -08:00
committed by GitHub
parent 2c21e1a90b
commit f1e8ebefc5
19 changed files with 276 additions and 185 deletions

View File

@@ -38,7 +38,7 @@ fn math<T: num_traits::float::Float>(
/// The value of "A" when calculating the expression.
#[implementations(f64, f32)]
operand_a: T,
/// A math expression that may incorporate "A" and/or "B", such as "sqrt(A + B) - B^2".
/// A math expression that may incorporate "A" and/or "B", such as `sqrt(A + B) - B^2`.
#[default(A + B)]
expression: String,
/// The value of "B" when calculating the expression.
@@ -76,98 +76,100 @@ fn math<T: num_traits::float::Float>(
}
}
/// The addition operation (+) calculates the sum of two numbers.
/// The addition operation (`+`) calculates the sum of two scalar numbers or vectors.
#[node_macro::node(category("Math: Arithmetic"))]
fn add<U: Add<T>, T>(
fn add<A: Add<B>, B>(
_: impl Ctx,
/// The left-hand side of the addition operation.
#[implementations(f64, f32, u32, DVec2, f64, DVec2)]
augend: U,
augend: A,
/// The right-hand side of the addition operation.
#[implementations(f64, f32, u32, DVec2, DVec2, f64)]
addend: T,
) -> <U as Add<T>>::Output {
addend: B,
) -> <A as Add<B>>::Output {
augend + addend
}
/// The subtraction operation (-) calculates the difference between two numbers.
/// The subtraction operation (`-`) calculates the difference between two scalar numbers or vectors.
#[node_macro::node(category("Math: Arithmetic"))]
fn subtract<U: Sub<T>, T>(
fn subtract<A: Sub<B>, B>(
_: impl Ctx,
/// The left-hand side of the subtraction operation.
#[implementations(f64, f32, u32, DVec2, f64, DVec2)]
minuend: U,
minuend: A,
/// The right-hand side of the subtraction operation.
#[implementations(f64, f32, u32, DVec2, DVec2, f64)]
subtrahend: T,
) -> <U as Sub<T>>::Output {
subtrahend: B,
) -> <A as Sub<B>>::Output {
minuend - subtrahend
}
/// The multiplication operation (×) calculates the product of two numbers.
/// The multiplication operation (`×`) calculates the product of two scalar numbers, vectors, or transforms.
#[node_macro::node(category("Math: Arithmetic"))]
fn multiply<U: Mul<T>, T>(
fn multiply<A: Mul<B>, B>(
_: impl Ctx,
/// The left-hand side of the multiplication operation.
#[implementations(f64, f32, u32, DVec2, f64, DVec2, DAffine2)]
multiplier: U,
multiplier: A,
/// The right-hand side of the multiplication operation.
#[default(1.)]
#[implementations(f64, f32, u32, DVec2, DVec2, f64, DAffine2)]
multiplicand: T,
) -> <U as Mul<T>>::Output {
multiplicand: B,
) -> <A as Mul<B>>::Output {
multiplier * multiplicand
}
/// The division operation (÷) calculates the quotient of two numbers.
/// The division operation (`÷`) calculates the quotient of two scalar numbers or vectors.
///
/// Produces 0 if the denominator is 0.
#[node_macro::node(category("Math: Arithmetic"))]
fn divide<U: Div<T> + Default + PartialEq, T: Default + PartialEq>(
fn divide<A: Div<B> + Default + PartialEq, B: Default + PartialEq>(
_: impl Ctx,
/// The left-hand side of the division operation.
#[implementations(f64, f32, u32, DVec2, DVec2, f64)]
numerator: U,
numerator: A,
/// The right-hand side of the division operation.
#[default(1.)]
#[implementations(f64, f32, u32, DVec2, f64, DVec2)]
denominator: T,
) -> <U as Div<T>>::Output
denominator: B,
) -> <A as Div<B>>::Output
where
<U as Div<T>>::Output: Default,
<A as Div<B>>::Output: Default,
{
if denominator == T::default() {
return <U as Div<T>>::Output::default();
if denominator == B::default() {
return <A as Div<B>>::Output::default();
}
numerator / denominator
}
/// The modulo operation (%) calculates the remainder from the division of two numbers. The sign of the result shares the sign of the numerator unless "Always Positive" is enabled.
/// The modulo operation (`%`) calculates the remainder from the division of two scalar numbers or vectors.
///
/// The sign of the result shares the sign of the numerator unless *Always Positive* is enabled.
#[node_macro::node(category("Math: Arithmetic"))]
fn modulo<U: Rem<T, Output: Add<T, Output: Rem<T, Output = U::Output>>>, T: Copy>(
fn modulo<A: Rem<B, Output: Add<B, Output: Rem<B, Output = A::Output>>>, B: Copy>(
_: impl Ctx,
/// The left-hand side of the modulo operation.
#[implementations(f64, f32, u32, DVec2, DVec2, f64)]
numerator: U,
numerator: A,
/// The right-hand side of the modulo operation.
#[default(2.)]
#[implementations(f64, f32, u32, DVec2, f64, DVec2)]
modulus: T,
/// Ensures the result will always be positive, even if the numerator is negative.
modulus: B,
/// Ensures the result is always positive, even if the numerator is negative.
#[default(true)]
always_positive: bool,
) -> <U as Rem<T>>::Output {
) -> <A as Rem<B>>::Output {
if always_positive { (numerator % modulus + modulus) % modulus } else { numerator % modulus }
}
/// The exponent operation (^) calculates the result of raising a number to a power.
/// The exponent operation (`^`) calculates the result of raising a number to a power.
#[node_macro::node(category("Math: Arithmetic"))]
fn exponent<T: Pow<T>>(
_: impl Ctx,
/// The base number that will be raised to the power.
/// The base number that is raised to the power.
#[implementations(f64, f32, u32)]
base: T,
/// The power to which the base number will be raised.
/// The power to which the base number is raised.
#[implementations(f64, f32, u32)]
#[default(2.)]
power: T,
@@ -175,15 +177,18 @@ fn exponent<T: Pow<T>>(
base.pow(power)
}
/// The square root operation () calculates the nth root of a number, equivalent to raising the number to the power of 1/n.
/// The `n`th root operation (`√`) calculates the inverse of exponentiation. Square root inverts squaring, cube root inverts cubing, and so on.
///
/// This is equivalent to raising the number to the power of `1/n`.
#[node_macro::node(category("Math: Arithmetic"))]
fn root<T: num_traits::float::Float>(
_: impl Ctx,
/// The number for which the nth root will be calculated.
/// The number inside the radical for which the `n`th root is calculated.
#[default(2.)]
#[implementations(f64, f32)]
radicand: T,
/// The degree of the root to be calculated. Square root is 2, cube root is 3, and so on.
/// Degrees 0 or less are invalid and will produce an output of 0.
#[default(2.)]
#[implementations(f64, f32)]
degree: T,
@@ -192,16 +197,18 @@ fn root<T: num_traits::float::Float>(
radicand.sqrt()
} else if degree == T::from(3.).unwrap() {
radicand.cbrt()
} else if degree <= T::from(0.).unwrap() {
T::from(0.).unwrap()
} else {
radicand.powf(T::from(1.).unwrap() / degree)
}
}
/// The logarithmic function (log) calculates the logarithm of a number with a specified base. If the natural logarithm function (ln) is desired, set the base to "e".
/// The logarithmic function (`log`) calculates the logarithm of a number with a specified base. If the natural logarithm function (`ln`) is desired, set the base to "e".
#[node_macro::node(category("Math: Arithmetic"))]
fn logarithm<T: num_traits::float::Float>(
_: impl Ctx,
/// The number for which the logarithm will be calculated.
/// The number for which the logarithm is calculated.
#[implementations(f64, f32)]
value: T,
/// The base of the logarithm, such as 2 (binary), 10 (decimal), and e (natural logarithm).
@@ -220,7 +227,7 @@ fn logarithm<T: num_traits::float::Float>(
}
}
/// The sine trigonometric function (sin) calculates the ratio of the angle's opposite side length to its hypotenuse length.
/// The sine trigonometric function (`sin`) calculates the ratio of the angle's opposite side length to its hypotenuse length.
#[node_macro::node(category("Math: Trig"))]
fn sine<T: num_traits::float::Float>(
_: impl Ctx,
@@ -233,7 +240,7 @@ fn sine<T: num_traits::float::Float>(
if radians { theta.sin() } else { theta.to_radians().sin() }
}
/// The cosine trigonometric function (cos) calculates the ratio of the angle's adjacent side length to its hypotenuse length.
/// The cosine trigonometric function (`cos`) calculates the ratio of the angle's adjacent side length to its hypotenuse length.
#[node_macro::node(category("Math: Trig"))]
fn cosine<T: num_traits::float::Float>(
_: impl Ctx,
@@ -246,7 +253,7 @@ fn cosine<T: num_traits::float::Float>(
if radians { theta.cos() } else { theta.to_radians().cos() }
}
/// The tangent trigonometric function (tan) calculates the ratio of the angle's opposite side length to its adjacent side length.
/// The tangent trigonometric function (`tan`) calculates the ratio of the angle's opposite side length to its adjacent side length.
#[node_macro::node(category("Math: Trig"))]
fn tangent<T: num_traits::float::Float>(
_: impl Ctx,
@@ -259,41 +266,43 @@ fn tangent<T: num_traits::float::Float>(
if radians { theta.tan() } else { theta.to_radians().tan() }
}
/// The inverse sine trigonometric function (asin) calculates the angle whose sine is the specified value.
/// The inverse sine trigonometric function (`asin`) calculates the angle whose sine is the input value.
#[node_macro::node(category("Math: Trig"))]
fn sine_inverse<T: num_traits::float::Float>(
_: impl Ctx,
/// The given value for which the angle will be calculated. Must be in the range [-1, 1] or else the result will be NaN.
/// The given value for which the angle is calculated. Must be in the domain `[-1, 1]` (it will be clamped to -1 or 1 otherwise).
#[implementations(f64, f32)]
value: T,
/// Whether the resulting angle should be given in as radians instead of degrees.
radians: bool,
) -> T {
if radians { value.asin() } else { value.asin().to_degrees() }
let angle = value.clamp(T::from(-1.).unwrap(), T::from(1.).unwrap()).asin();
if radians { angle } else { angle.to_degrees() }
}
/// The inverse cosine trigonometric function (acos) calculates the angle whose cosine is the specified value.
/// The inverse cosine trigonometric function (`acos`) calculates the angle whose cosine is the input value.
#[node_macro::node(category("Math: Trig"))]
fn cosine_inverse<T: num_traits::float::Float>(
_: impl Ctx,
/// The given value for which the angle will be calculated. Must be in the range [-1, 1] or else the result will be NaN.
/// The given value for which the angle is calculated. Must be in the domain `[-1, 1]` (it will be clamped to -1 or 1 otherwise).
#[implementations(f64, f32)]
value: T,
/// Whether the resulting angle should be given in as radians instead of degrees.
radians: bool,
) -> T {
if radians { value.acos() } else { value.acos().to_degrees() }
let angle = value.clamp(T::from(-1.).unwrap(), T::from(1.).unwrap()).acos();
if radians { angle } else { angle.to_degrees() }
}
/// The inverse tangent trigonometric function (atan or atan2, depending on input type) calculates:
/// atan: the angle whose tangent is the specified scalar number.
/// atan2: the angle of a ray from the origin to the specified vec2.
/// The inverse tangent trigonometric function (`atan` or `atan2`, depending on input type) calculates:
/// `atan`: the angle whose tangent is the input scalar number.
/// `atan2`: the angle of a ray from the origin to the input vec2.
///
/// The resulting angle is always in the range [-90°, 90°] or, in radians, [-π/2, π/2].
/// The resulting angle is always in the range `[-90°, 90°]` or, in radians, `[-π/2, π/2]`.
#[node_macro::node(category("Math: Trig"))]
fn tangent_inverse<T: TangentInverse>(
_: impl Ctx,
/// The given value for which the angle will be calculated.
/// The given value for which the angle is calculated.
#[implementations(f64, f32, DVec2)]
value: T,
/// Whether the resulting angle should be given in as radians instead of degrees.
@@ -325,18 +334,30 @@ impl TangentInverse for DVec2 {
}
}
/// Linearly maps an input value from one range to another. The ranges may be reversed.
///
/// For example, 0.5 in the input range `[0, 1]` would map to 0 in the output range `[-180, 180]`.
#[node_macro::node(category("Math: Numeric"))]
fn remap<U: num_traits::float::Float>(
_: impl Ctx,
#[implementations(f64, f32)] value: U,
#[implementations(f64, f32)] input_min: U,
/// The value to be mapped between ranges.
#[implementations(f64, f32)]
value: U,
/// The lower bound of the input range.
#[implementations(f64, f32)]
input_min: U,
/// The upper bound of the input range.
#[implementations(f64, f32)]
#[default(1.)]
input_max: U,
#[implementations(f64, f32)] output_min: U,
/// The lower bound of the output range.
#[implementations(f64, f32)]
output_min: U,
/// The upper bound of the output range.
#[implementations(f64, f32)]
#[default(1.)]
output_max: U,
/// Whether to constrain the result within the output range instead of extrapolating beyond its bounds.
clamped: bool,
) -> U {
let input_range = input_max - input_min;
@@ -363,17 +384,17 @@ fn remap<U: num_traits::float::Float>(
}
}
/// The random function (rand) converts a seed into a random number within the specified range, inclusive of the minimum and exclusive of the maximum. The minimum and maximum values are automatically swapped if they are reversed.
/// The random function (`rand`) converts a seed into a random number within the specified range, inclusive of the minimum and exclusive of the maximum. The minimum and maximum values are automatically swapped if they are reversed.
#[node_macro::node(category("Math: Numeric"))]
fn random(
_: impl Ctx,
_primary: (),
/// Seed to determine the unique variation of which number will be generated.
/// Seed to determine the unique variation of which number is generated.
seed: u64,
/// The smaller end of the range within which the random number will be generated.
/// The smaller end of the range within which the random number is generated.
#[default(0.)]
min: f64,
/// The larger end of the range within which the random number will be generated.
/// The larger end of the range within which the random number is generated.
#[default(1.)]
max: f64,
) -> f64 {
@@ -404,89 +425,89 @@ fn to_f64(_: impl Ctx, value: f64) -> f64 {
value
}
/// The rounding function (round) maps an input value to its nearest whole number. Halfway values are rounded away from zero.
/// The rounding function (`round`) maps an input value to its nearest whole number. Halfway values are rounded away from zero.
#[node_macro::node(category("Math: Numeric"))]
fn round<T: num_traits::float::Float>(
_: impl Ctx,
/// The number which will be rounded.
/// The number to be rounded to the nearest whole number.
#[implementations(f64, f32)]
value: T,
) -> T {
value.round()
}
/// The floor function (floor) rounds down an input value to the nearest whole number, unless the input number is already whole.
/// The floor function (`floor`) rounds down an input value to the nearest whole number, unless the input number is already whole.
#[node_macro::node(category("Math: Numeric"))]
fn floor<T: num_traits::float::Float>(
_: impl Ctx,
/// The number which will be rounded down.
/// The number to be rounded down.
#[implementations(f64, f32)]
value: T,
) -> T {
value.floor()
}
/// The ceiling function (ceil) rounds up an input value to the nearest whole number, unless the input number is already whole.
/// The ceiling function (`ceil`) rounds up an input value to the nearest whole number, unless the input number is already whole.
#[node_macro::node(category("Math: Numeric"))]
fn ceiling<T: num_traits::float::Float>(
_: impl Ctx,
/// The number which will be rounded up.
/// The number to be rounded up.
#[implementations(f64, f32)]
value: T,
) -> T {
value.ceil()
}
/// The absolute value function (abs) removes the negative sign from an input value, if present.
/// The absolute value function (`abs`) removes the negative sign from an input value, if present.
#[node_macro::node(category("Math: Numeric"))]
fn absolute_value<T: num_traits::sign::Signed>(
_: impl Ctx,
/// The number which will be made positive.
/// The number to be made positive.
#[implementations(f64, f32, i32, i64)]
value: T,
) -> T {
value.abs()
}
/// The minimum function (min) picks the smaller of two numbers.
/// The minimum function (`min`) picks the smaller of two numbers.
#[node_macro::node(category("Math: Numeric"))]
fn min<T: std::cmp::PartialOrd>(
_: impl Ctx,
/// One of the two numbers, of which the lesser will be returned.
/// One of the two numbers, of which the lesser is returned.
#[implementations(f64, f32, u32, &str)]
value: T,
/// The other of the two numbers, of which the lesser will be returned.
/// The other of the two numbers, of which the lesser is returned.
#[implementations(f64, f32, u32, &str)]
other_value: T,
) -> T {
if value < other_value { value } else { other_value }
}
/// The maximum function (max) picks the larger of two numbers.
/// The maximum function (`max`) picks the larger of two numbers.
#[node_macro::node(category("Math: Numeric"))]
fn max<T: std::cmp::PartialOrd>(
_: impl Ctx,
/// One of the two numbers, of which the greater will be returned.
/// One of the two numbers, of which the greater is returned.
#[implementations(f64, f32, u32, &str)]
value: T,
/// The other of the two numbers, of which the greater will be returned.
/// The other of the two numbers, of which the greater is returned.
#[implementations(f64, f32, u32, &str)]
other_value: T,
) -> T {
if value > other_value { value } else { other_value }
}
/// The clamp function (clamp) restricts a number to a specified range between a minimum and maximum value. The minimum and maximum values are automatically swapped if they are reversed.
/// The clamp function (`clamp`) restricts a number to a specified range between a minimum and maximum value. The minimum and maximum values are automatically swapped if they are reversed.
#[node_macro::node(category("Math: Numeric"))]
fn clamp<T: std::cmp::PartialOrd>(
_: impl Ctx,
/// The number to be clamped, which will be restricted to the range between the minimum and maximum values.
/// The number to be clamped, which is restricted to the range between the minimum and maximum values.
#[implementations(f64, f32, u32, &str)]
value: T,
/// The left (smaller) side of the range. The output will never be less than this number.
/// The left (smaller) side of the range. The output is never less than this number.
#[implementations(f64, f32, u32, &str)]
min: T,
/// The right (greater) side of the range. The output will never be greater than this number.
/// The right (greater) side of the range. The output is never greater than this number.
#[implementations(f64, f32, u32, &str)]
max: T,
) -> T {
@@ -504,10 +525,10 @@ fn clamp<T: std::cmp::PartialOrd>(
#[node_macro::node(category("Math: Numeric"))]
fn greatest_common_divisor<T: num_traits::int::PrimInt + std::ops::ShrAssign<i32> + std::ops::SubAssign>(
_: impl Ctx,
/// One of the two numbers for which the GCD will be calculated.
/// One of the two numbers for which the GCD is calculated.
#[implementations(u32, u64, i32)]
value: T,
/// The other of the two numbers for which the GCD will be calculated.
/// The other of the two numbers for which the GCD is calculated.
#[implementations(u32, u64, i32)]
other_value: T,
) -> T {
@@ -524,10 +545,10 @@ fn greatest_common_divisor<T: num_traits::int::PrimInt + std::ops::ShrAssign<i32
#[node_macro::node(category("Math: Numeric"))]
fn least_common_multiple<T: num_traits::ToPrimitive + num_traits::FromPrimitive + num_traits::identities::Zero>(
_: impl Ctx,
/// One of the two numbers for which the LCM will be calculated.
/// One of the two numbers for which the LCM is calculated.
#[implementations(u32, u64, i32)]
value: T,
/// The other of the two numbers for which the LCM will be calculated.
/// The other of the two numbers for which the LCM is calculated.
#[implementations(u32, u64, i32)]
other_value: T,
) -> T {
@@ -574,36 +595,8 @@ fn binary_gcd<T: num_traits::int::PrimInt + std::ops::ShrAssign<i32> + std::ops:
a << shift
}
/// The equality operation (==) compares two values and returns true if they are equal, or false if they are not.
#[node_macro::node(category("Math: Logic"))]
fn equals<T: std::cmp::PartialEq<T>>(
_: impl Ctx,
/// One of the two numbers to compare for equality.
#[implementations(f64, f32, u32, DVec2, bool, &str, String)]
value: T,
/// The other of the two numbers to compare for equality.
#[implementations(f64, f32, u32, DVec2, bool, &str, String)]
other_value: T,
) -> bool {
other_value == value
}
/// The inequality operation (!=) compares two values and returns true if they are not equal, or false if they are.
#[node_macro::node(category("Math: Logic"))]
fn not_equals<T: std::cmp::PartialEq<T>>(
_: impl Ctx,
/// One of the two numbers to compare for inequality.
#[implementations(f64, f32, u32, DVec2, bool, &str)]
value: T,
/// The other of the two numbers to compare for inequality.
#[implementations(f64, f32, u32, DVec2, bool, &str)]
other_value: T,
) -> bool {
other_value != value
}
/// The less-than operation (<) compares two values and returns true if the first value is less than the second, or false if it is not.
/// If enabled with "Or Equal", the less-than-or-equal operation (<=) will be used instead.
/// The less-than operation (`<`) compares two values and returns true if the first value is less than the second, or false if it is not.
/// If enabled with *Or Equal*, the less-than-or-equal operation (`<=`) is used instead.
#[node_macro::node(category("Math: Logic"))]
fn less_than<T: std::cmp::PartialOrd<T>>(
_: impl Ctx,
@@ -613,14 +606,14 @@ fn less_than<T: std::cmp::PartialOrd<T>>(
/// The number on the right-hand side of the comparison.
#[implementations(f64, f32, u32)]
other_value: T,
/// Uses the less-than-or-equal operation (<=) instead of the less-than operation (<).
/// Uses the less-than-or-equal operation (`<=`) instead of the less-than operation (`<`).
or_equal: bool,
) -> bool {
if or_equal { value <= other_value } else { value < other_value }
}
/// The greater-than operation (>) compares two values and returns true if the first value is greater than the second, or false if it is not.
/// If enabled with "Or Equal", the greater-than-or-equal operation (>=) will be used instead.
/// The greater-than operation (`>`) compares two values and returns true if the first value is greater than the second, or false if it is not.
/// If enabled with *Or Equal*, the greater-than-or-equal operation (`>=`) is used instead.
#[node_macro::node(category("Math: Logic"))]
fn greater_than<T: std::cmp::PartialOrd<T>>(
_: impl Ctx,
@@ -630,13 +623,41 @@ fn greater_than<T: std::cmp::PartialOrd<T>>(
/// The number on the right-hand side of the comparison.
#[implementations(f64, f32, u32)]
other_value: T,
/// Uses the greater-than-or-equal operation (>=) instead of the greater-than operation (>).
/// Uses the greater-than-or-equal operation (`>=`) instead of the greater-than operation (`>`).
or_equal: bool,
) -> bool {
if or_equal { value >= other_value } else { value > other_value }
}
/// The logical or operation (||) returns true if either of the two inputs are true, or false if both are false.
/// The equality operation (`==`, `XNOR`) compares two values and returns true if they are equal, or false if they are not.
#[node_macro::node(category("Math: Logic"))]
fn equals<T: std::cmp::PartialEq<T>>(
_: impl Ctx,
/// One of the two values to compare for equality.
#[implementations(f64, f32, u32, DVec2, bool, &str, String)]
value: T,
/// The other of the two values to compare for equality.
#[implementations(f64, f32, u32, DVec2, bool, &str, String)]
other_value: T,
) -> bool {
other_value == value
}
/// The inequality operation (`!=`, `XOR`) compares two values and returns true if they are not equal, or false if they are.
#[node_macro::node(category("Math: Logic"))]
fn not_equals<T: std::cmp::PartialEq<T>>(
_: impl Ctx,
/// One of the two values to compare for inequality.
#[implementations(f64, f32, u32, DVec2, bool, &str)]
value: T,
/// The other of the two values to compare for inequality.
#[implementations(f64, f32, u32, DVec2, bool, &str)]
other_value: T,
) -> bool {
other_value != value
}
/// The logical OR operation (`||`) returns true if either of the two inputs are true, or false if both are false.
#[node_macro::node(category("Math: Logic"))]
fn logical_or(
_: impl Ctx,
@@ -648,7 +669,7 @@ fn logical_or(
value || other_value
}
/// The logical and operation (&&) returns true if both of the two inputs are true, or false if any are false.
/// The logical AND operation (`&&`) returns true if both of the two inputs are true, or false if any are false.
#[node_macro::node(category("Math: Logic"))]
fn logical_and(
_: impl Ctx,
@@ -660,7 +681,7 @@ fn logical_and(
value && other_value
}
/// The logical not operation (!) reverses true and false value of the input.
/// The logical NOT operation (`!`) reverses true and false value of the input.
#[node_macro::node(category("Math: Logic"))]
fn logical_not(
_: impl Ctx,
@@ -736,20 +757,39 @@ fn footprint_value(_: impl Ctx, _primary: (), transform: DAffine2, #[default(100
}
}
/// The dot product operation (`·`) calculates the degree of similarity of a vec2 pair based on their angles and lengths.
///
/// Calculated as `‖a‖‖b‖cos(θ)`, it represents the product of their lengths (`‖a‖‖b‖`) scaled by the alignment of their directions (`cos(θ)`).
/// The output ranges from the positive to negative product of their lengths based on when they are pointing in the same or opposite directions.
/// If any vector has zero length, the output is 0.
#[node_macro::node(category("Math: Vector"))]
fn dot_product(_: impl Ctx, vector_a: DVec2, vector_b: DVec2) -> f64 {
vector_a.dot(vector_b)
fn dot_product(
_: impl Ctx,
/// An operand of the dot product operation.
vector_a: DVec2,
/// The other operand of the dot product operation.
#[default((1., 0.))]
vector_b: DVec2,
/// Whether to normalize both input vectors so the calculation ranges in `[-1, 1]` by considering only their degree of directional alignment.
normalize: bool,
) -> f64 {
if normalize {
vector_a.normalize_or_zero().dot(vector_b.normalize_or_zero())
} else {
vector_a.dot(vector_b)
}
}
/// Gets the length or magnitude of a vector.
// TODO: Rename to "Magnitude"
/// The magnitude operator (`‖x‖`) calculates the length of a vec2, which is the distance from the base to the tip of the arrow represented by the vector.
#[node_macro::node(category("Math: Vector"))]
fn length(_: impl Ctx, vector: DVec2) -> f64 {
vector.length()
}
/// Scales the input vector to unit length while preserving it's direction. This is equivalent to dividing the input vector by it's own magnitude.
/// Scales the input vector to unit length while preserving its direction. This is equivalent to dividing the input vector by its own magnitude.
///
/// Returns zero when the input vector is zero.
/// Returns 0 when the input vector has zero length.
#[node_macro::node(category("Math: Vector"))]
fn normalize(_: impl Ctx, vector: DVec2) -> DVec2 {
vector.normalize_or_zero()
@@ -765,7 +805,7 @@ mod test {
pub fn dot_product_function() {
let vector_a = DVec2::new(1., 2.);
let vector_b = DVec2::new(3., 4.);
assert_eq!(dot_product((), vector_a, vector_b), 11.);
assert_eq!(dot_product((), vector_a, vector_b, false), 11.);
}
#[test]

View File

@@ -574,7 +574,6 @@ fn vibrance<T: Adjust<Color>>(
image
}
/// Color Channel
#[repr(u32)]
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, node_macro::ChoiceType, BufferStruct, FromPrimitive, IntoPrimitive)]
#[cfg_attr(feature = "std", derive(dyn_any::DynAny, specta::Type, serde::Serialize, serde::Deserialize))]
@@ -586,7 +585,6 @@ pub enum RedGreenBlue {
Blue,
}
/// Color Channel
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, node_macro::ChoiceType, bytemuck::NoUninit, BufferStruct, FromPrimitive, IntoPrimitive)]
#[cfg_attr(feature = "std", derive(dyn_any::DynAny, specta::Type, serde::Serialize, serde::Deserialize))]
#[widget(Radio)]
@@ -599,7 +597,7 @@ pub enum RedGreenBlueAlpha {
Alpha,
}
/// Style of noise pattern
/// Style of noise pattern.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, node_macro::ChoiceType)]
#[cfg_attr(feature = "std", derive(dyn_any::DynAny, specta::Type, serde::Serialize, serde::Deserialize))]
#[widget(Dropdown)]
@@ -616,9 +614,9 @@ pub enum NoiseType {
WhiteNoise,
}
/// Style of layered levels of the noise pattern.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, node_macro::ChoiceType)]
#[cfg_attr(feature = "std", derive(dyn_any::DynAny, specta::Type, serde::Serialize, serde::Deserialize))]
/// Style of layered levels of the noise pattern
pub enum FractalType {
#[default]
None,
@@ -632,7 +630,7 @@ pub enum FractalType {
DomainWarpIndependent,
}
/// Distance function used by the cellular noise
/// Distance function used by the cellular noise.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, node_macro::ChoiceType)]
#[cfg_attr(feature = "std", derive(dyn_any::DynAny, specta::Type, serde::Serialize, serde::Deserialize))]
pub enum CellularDistanceFunction {
@@ -663,7 +661,6 @@ pub enum CellularReturnType {
Division,
}
/// Type of domain warp
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, node_macro::ChoiceType)]
#[cfg_attr(feature = "std", derive(dyn_any::DynAny, specta::Type, serde::Serialize, serde::Deserialize))]
#[widget(Dropdown)]