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
impl Subcube
Sourcepub const ELE_PER_SIDE: usize = 32usize
pub const ELE_PER_SIDE: usize = 32usize
The number of subdivisions per dimension of the (-1,1) cube that produces the subcubes
Sourcepub const NUM_SUBCUBES: usize = 32_768usize
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
Sourcepub const SUBCUBE_SIZE: f64 = 0.0625f64
pub const SUBCUBE_SIZE: f64 = 0.0625f64
The size of each side of a Subcube
Sourcepub const SUBCUBE_RADIUS: f64 = 0.054128124999999999f64
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)
Sourcepub fn of_vector(vector: &[f64; 3]) -> Self
pub fn of_vector(vector: &[f64; 3]) -> Self
Get the subcube of a unit vector (which is thus a point on the unit sphere)
Sourcepub fn as_usize(&self) -> usize
pub fn as_usize(&self) -> usize
Get a value for the subcube, different for each within the (-1,1) cube
Sourcepub fn center(&self) -> [f64; 3]
pub fn center(&self) -> [f64; 3]
Get the vector of the centre of the Subcube (this is NOT a unit vector)!
Sourcepub fn may_be_on_sphere(&self) -> bool
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
Sourcepub fn iter_all() -> SubcubeRangeIter
pub fn iter_all() -> SubcubeRangeIter
Get an iterator over all the Subcubes in the (-1, 1) cube
Sourcepub fn iter_range(&self, dxyz: usize) -> SubcubeRangeIter
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