vox_geometry_rust 0.1.2

Geometry Tools for Rust
Documentation
/*
 * // Copyright (c) 2021 Feng Yang
 * //
 * // I am making my contributions/submissions to this project solely in my
 * // personal capacity and am not conveying any rights to any intellectual
 * // property of any third parties.
 */

use crate::vector3::Vector3D;
use crate::vector2::Vector2D;

/// Returns randomly sampled direction within a cone.
///
/// For a given cone, defined by axis and angle, this function returns a sampled
/// direction vector within the cone.
/// - Parameters:
///   - u1: First random sample.
///   - u2: Second random sample.
///   - axis: The axis of the cone.
///   - angle: The angle of the cone.
/// - Returns: Sampled direction vector.
pub fn uniform_sample_cone(u1: f64, u2: f64,
                           axis: &Vector3D,
                           angle: f64) -> Vector3D {
    let cos_angle_2 = f64::cos(angle / 2.0);
    let y: f64 = 1.0 - (1.0 - cos_angle_2) * u1;
    let r = f64::sqrt(f64::max(0.0, 1.0 - y * y));
    let phi = crate::constants::K_TWO_PI_D * u2;
    let x = r * f64::cos(phi);
    let z = r * f64::sin(phi);
    let ts = axis.tangential();

    let result = ts.0 * x + *axis * y;
    return result + ts.1 * z;
}

/// Returns randomly sampled point within a unit hemisphere.
///
/// For a given unit hemisphere, defined by center normal vector, this function
/// returns a point within the hemisphere.
/// - Parameters:
///   - u1: First random sample.
///   - u2: Second random sample.
///   - normal: The center normal of the hemisphere.
/// - Returns: Sampled point.
pub fn uniform_sample_hemisphere(u1: f64, u2: f64,
                                 normal: &Vector3D) -> Vector3D {
    let y = u1;
    let r = f64::sqrt(f64::max(0.0, 1.0 - y * y));
    let phi = crate::constants::K_TWO_PI_D * u2;
    let x = r * f64::cos(phi);
    let z = r * f64::sin(phi);
    let ts = normal.tangential();

    let result = ts.0 * x + *normal * y;
    return result + ts.1 * z;
}

/// Returns weighted sampled point on a hemisphere.
///
/// For a given hemisphere, defined by center normal vector, this function
/// returns a point on the hemisphere, where the probability is
/// cosine-weighted.
/// - Parameters:
///   - u1: First random sample.
///   - u2: Second random sample.
///   - normal: The center normal of the hemisphere.
/// - Returns: Sampled point.
pub fn cosine_weighted_sample_hemisphere(u1: f64, u2: f64,
                                         normal: &Vector3D) -> Vector3D {
    let phi = crate::constants::K_TWO_PI_D * u1;
    let y = f64::sqrt(u2);
    let theta = f64::acos(y);
    let x = f64::cos(phi) * f64::sin(theta);
    let z = f64::sin(phi) * f64::sin(theta);
    let ts = normal.tangential();

    let result = ts.0 * x + *normal * y;
    return result + ts.1 * z;
}

/// Returns randomly a point on a sphere.
///
/// For a given sphere, defined by center normal vector, this function returns a
/// point on the sphere.
/// - Parameters:
///   - u1: First random sample.
///   - u2: Second random sample.
/// - Returns: Sampled point.
pub fn uniform_sample_sphere(u1: f64, u2: f64) -> Vector3D {
    let y = 1.0 - 2.0 * u1;
    let r = f64::sqrt(f64::max(0.0, 1.0 - y * y));
    let phi = crate::constants::K_TWO_PI_D * u2;
    let x = r * f64::cos(phi);
    let z = r * f64::sin(phi);
    return Vector3D::new(x, y, z);
}

/// Returns randomly a point on a disk.
///
/// For a given disk, this function returns a point on the disk.
/// - Parameters:
///   - u1: First random sample.
///   - u2: Second random sample.
/// - Returns: Sampled point.
pub fn uniform_sample_disk(u1: f64, u2: f64) -> Vector2D {
    let r = f64::sqrt(u1);
    let theta = crate::constants::K_TWO_PI_D * u2;

    return Vector2D::new(r * f64::cos(theta), r * f64::sin(theta));
}