hexasphere

Trait BaseShape

Source
pub trait BaseShape {
    const EDGES: usize;

    // Required methods
    fn initial_points(&self) -> Vec<Vec3A>;
    fn triangles(&self) -> Box<[Triangle]>;
    fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A;

    // Provided methods
    fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A { ... }
    fn interpolate_multiple(
        &self,
        a: Vec3A,
        b: Vec3A,
        indices: &[u32],
        points: &mut [Vec3A],
    ) { ... }
}
Expand description

Defines the geometry of the shape to be subdivided, and the functions used in interpolation.

If you want to use a different interpolation function, implement this trait for a new type, and carry over only the properties you’d like to keep:

use hexasphere::{Triangle, shapes::IcoSphereBase};
use glam::Vec3A;
// Uses linear interpolation instead of spherical.
struct FlatIcosahedron;

impl BaseShape for FlatIcosahedron {
    // Keep the initial parameters.
    fn initial_points(&self) -> Vec<Vec3A> {
        IcoSphereBase.initial_points()
    }

    fn triangles(&self) -> Box<[Triangle]> {
        IcoSphereBase.triangles()
    }
    const EDGES: usize = IcoSphereBase::EDGES;

    // Swap out what you'd like to change.
    fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A {
        hexasphere::interpolation::lerp(a, b, p)
    }

    fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A {
        hexasphere::interpolation::lerp_half(a, b)
    }

    fn interpolate_multiple(&self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A]) {
        hexasphere::interpolation::lerp_multiple(a, b, indices, points);
    }
}

Or, create your own shape, by changing the values for initial_points, triangles, and EDGES. Check the documentation for these members individually on how they should be implemented.

Required Associated Constants§

Source

const EDGES: usize

Number of unique edges defined in the contents of triangles(). This number is 5 for a square for example:

a - 0 - b
|     / |
3   4   1
| /     |
d - 2 - c

Required Methods§

Source

fn initial_points(&self) -> Vec<Vec3A>

The vertices for all main triangles of the shape. Check the source file for this crate and look for the constants module at the bottom for an example.

Constraints on the points depend on the interpolation function used:

  • slerp requires normalized (magnitude 1) data.
  • lerp doesn’t care.
  • normalized_lerp requires normalized (magnitude 1) data.
Source

fn triangles(&self) -> Box<[Triangle]>

Main triangles for the shape; that is, the triangles which exist before subdivision.

See Triangle::new() for details.

Source

fn interpolate(&self, a: Vec3A, b: Vec3A, p: f32) -> Vec3A

Basic function used for interpolation. When p is 0.0, a is expected. When p is 1.0, b is expected. There are three options already implemented in this crate:

  • lerp implements linear interpolation.
  • geometric_slerp implements spherical interpolation. (Interpolates along an arc on a sphere)
  • normalized_lerp implements cheaper yet less accurate spherical interpolation. The accuracy decreases as the angle between the two points on the unit sphere increases.

Provided Methods§

Source

fn interpolate_half(&self, a: Vec3A, b: Vec3A) -> Vec3A

If an optimization is available for the case where p is 0.5, this function should implement it. This defaults to calling interpolate(a, b, 0.5) however.

Source

fn interpolate_multiple( &self, a: Vec3A, b: Vec3A, indices: &[u32], points: &mut [Vec3A], )

If an optimization is available for the case where p varies but a and b don’t, this function should implement it.

§Parameters
  • a: start.
  • b: end.
  • indices: list of indices to index into points. points at the index should contain the result. The index (n) of an index should correspond with the nth point in a distribution of indices.len() points between (exclusive) a and b.
  • points: list of points where the results of the calculation should end up. To be indexed by values in indices.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§