Subcube

Struct Subcube 

Source
pub struct Subcube(/* private fields */);
Expand description

A representation of a portion of the unit cube, to improve geometric searching of a catalog.

In a catalog stars can be marked as being on a part of the unit sphere. A subcube is created by dividing the cube from (-1, 1) in each dimension into ELE_PER_SIDE^3 subcubes; subcubes are easy to manipulate, and can be related to the portion of the unit sphere they encompass.

Not all subcubes include a portion of the unit sphere; in a catalog this would indicate there will be an empty list for that subcube. The catalog can maintain either a HashMap keyed on Subcube or a Vec indexed by subcube, of lists of stars within that subcube.

A subcube has up to 8 immediate neighbors (some may be out of bounds).

The Subcube provides methods for iterating over it and its neighbors, and within a region around the subcube.

§Rationale

Subdividing the unit sphere can be handled in many ways; the subcube division provides for simple iteration over space and over stars that are clustered together, which is a common search problem.

§Choice of ELE_PER_SIDE

If ELE_PER_SIDE were 2 then the maximum angle of difference between any two points in a subcube would be 90 degrees

If ELE_PER_SIDE were 4 the the maxim angle of difference between any two points in a subcube would be 45 degrees

If ELE_PER_SIDE were 32 then each subcube has side length 1/16; a maximum angle subtended of the line betwen two opposite corners and the centre of the circle as 2.asin(sqrt(3)*r/16 / r / 2) = 2.asin(sqrt(3)/32) = 6 degrees

Here also there is a shortest distance (minimum) of r/16 from corner of a cube, across its neighbor, to a the next neighbor (it will be more than that, but this is a mininum); this subtends an angle of 2*asin(1/16/2), or 3.58 degrees. cos(this) is 0.99804. Hence a star within a subcube must be at least 3.58 degrees from any star that is not within the subcube or one of its immediate neighbors - or rather, all stars within 3.58 degrees of the star MUST be within the same subcube as the star, or in one of its immediate neighbors

If ELE_PER_SIDE were 64 then each subcube has side length 1/32; a maximum angle subtended of the line betwen two opposite corners and the centre of the circle as 2.asin(sqrt(3)*r/32 / r / 2) = 2.asin(sqrt(3)/64) = 3 degrees

If ELE_PER_SIDE were 16 then theshortest distance (minimum) is r/8 from corner of a cube, across its neighbor, to a non-neighbor (it will be more than that, but this is a mininum); this subtends an angle of 2*asin(1/8/2), or 7.17 degrees cos(this) is 0.99219.

Emmpirically, using the Hipparcos star catalog:

ELE_PER_SIDE of 32 is needed for cos() > 0.9980 (3.62 degrees); 276,038 (/2) pairs of vmag<7.0

ELE_PER_SIDE of 16 is needed for cos() > 0.995 (5.73 degrees) There are 679082 (/2) pairs of stars of vmag < 7.0 separated by at most that

ELE_PER_SIDE of 8 is needed for cos() > 0.992 (7.25 degrees) There are 1080842 (/2) pairs of stars of vmag < 7.0 separated by at most that

§Angles of subcubes

With 32 subcubes the subcube_max_angle is 6.18 degrees

  • 2 subcubes = 12.4 degrees
  • 3 subcubes = 18.6 degrees
  • 4 subcubes = 24.8 degrees
  • 5 subcubes = 30.9 degrees
  • 6 subcubes = 37.1 degrees
  • 7 subcubes = 43.3 degrees
  • 8 subcubes = 49.5 degrees

Implementations§

Source§

impl Subcube

Source

pub const ELE_PER_SIDE: usize = 32usize

The number of subdivisions per dimension of the (-1,1) cube that produces the subcubes

Source

pub const NUM_SUBCUBES: usize = 32_768usize

The number of subcubes in the (-1,1) cube

A Catalog may have a Vec with this number of entries; each element would be a Vec, but only those that contain stars (and are therefore on the unit sphere) will contain elements, the rest would be empty

It is worth noting that as ELE_PER_SIDE increases, the number of populated subcubes approaches 2*ELE_PER_SIDE^2

Source

pub const SUBCUBE_SIZE: f64 = 0.0625f64

The size of each side of a Subcube

Source

pub const SUBCUBE_RADIUS: f64 = 0.054128124999999999f64

The raduis of the circumsphere of a Subcube - i.e. all stars within the subcube must be closer tthan this to the centre of the Subcube (although some such stars may be in a neighboring subcube)

Source

pub fn of_vector(vector: &[f64; 3]) -> Self

Get the subcube of a unit vector (which is thus a point on the unit sphere)

Source

pub fn as_usize(&self) -> usize

Get a value for the subcube, different for each within the (-1,1) cube

Source

pub fn center(&self) -> [f64; 3]

Get the vector of the centre of the Subcube (this is NOT a unit vector)!

Source

pub fn may_be_on_sphere(&self) -> bool

Return true if the subcube might contain part of the unit sphere

This returns false if the centre is too far from the unit sphere for any part of the subcube to overlap the unit sphere

Source

pub fn iter_all() -> SubcubeRangeIter

Get an iterator over all the Subcubes in the (-1, 1) cube

Source

pub fn iter_range(&self, dxyz: usize) -> SubcubeRangeIter

Get an iterator over this Subcube and all with X, Y or Z coordinates within dxyz of it

A value of 0 for dxyz returns an iterator over just this one Subcube

A value of 1 for dxyz returns an iterator over this subcube and all its immediate neighbors

Trait Implementations§

Source§

impl Add<isize> for Subcube

Source§

type Output = Subcube

The resulting type after applying the + operator.
Source§

fn add(self, delta: isize) -> Subcube

Performs the + operation. Read more
Source§

impl Clone for Subcube

Source§

fn clone(&self) -> Subcube

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Subcube

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<&Subcube> for (usize, usize, usize)

Source§

fn from(s: &Subcube) -> (usize, usize, usize)

Converts to this type from the input type.
Source§

impl From<(usize, usize, usize)> for Subcube

Source§

fn from((x, y, z): (usize, usize, usize)) -> Subcube

Converts to this type from the input type.
Source§

impl From<Subcube> for (usize, usize, usize)

Source§

fn from(s: Subcube) -> (usize, usize, usize)

Converts to this type from the input type.
Source§

impl Index<Subcube> for Catalog

Source§

type Output = Vec<CatalogIndex>

The returned type after indexing.
Source§

fn index(&self, q: Subcube) -> &Vec<CatalogIndex>

Performs the indexing (container[index]) operation. Read more
Source§

impl Copy for Subcube

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.