Trait hexasphere::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 setup for a base shape, 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 initial vertices for the triangle. Note that Vec3A::new is not a const fn(), hence I recommend you use lazy_static. 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]>

Base triangles for the shape.

  • The fields a, b, and c define the indices for the points of the triangles given the data present in initial_points. Note that this crate assumes points are in a counter clockwise ordering.
  • The fields ab_edge, bc_edge, ca_edge mark the index of the edge which a/b, b/c, and c/a border respectively. While theoretically you could give each triangle its own edge, minimizing edges saves on memory footprint and performance.
  • Triangles should be created through Triangle::new.
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.

Object Safety§

This trait is not object safe.

Implementors§