KDTree¶
- class giant.ray_tracer.kdtree.KDTree(self, surface, max_depth=10, _root=None, _rotation=None, _position=None, _bounding_box=None, _reference_ellipsoid=None)¶
A KD Tree representation for accelerated tracing of surface objects with many geometry primitives using axis aligned bounding box acceleration.
A KD Tree is essentially a modifier on a
Surface
which makes it much more computationally efficient to trace without altering the results from the trace at all (that is tracing aSurface
and aKDTree
built for that surface will produce equivalent results. The acceleration is performed by dividing the surface into local sub surfaces which much fewer primitives contained in them. Each sub surface is then encapsulated by anAxisAlignedBoundingBox
specifying the extent of the geometry contained in it. Each one of these subsurfaces is contained in aKDNode
.The nodes are built hierarchically, so that there is one large node at the top (the
root
of the tree) and then exponentially divide as you descend the tree until you reach the nodes that contain actual geometry. This structure allows very efficient tracing by dramatically decreasing the number of geometry primitives that must be traced for each ray. The wikipedia article on kd trees provides a decent description of how they work (https://en.wikipedia.org/wiki/K-d_tree) though our specific implementation varies slightly from what is described there.Conceptually, if you don’t care about the details, the tree can be treated just like any other surface in GIANT. You can use it as a target for relative opnav, or trace rays through it however you see fit. Simply provide your
Surface
, call thebuild()
method, and then use the results in aSceneObject
. The only real setting you may need to worry about is themax_depth
which specifies how many node levels you want to make before tracing the remaining geometry. Typically you want to set this so that there are between 10-100 remaining geometry primitives inside of the final leaf nodes in the tree (this information is provided to you if you use theingest_shape
script). If you have too many geometry primitives remaining then your tree will be inefficient. If you have too few geometry primitives remaining your tree will also be inefficient (it is sometimes a case of trial and error to find the optimal number). Just remember that when adjusting this number that it is exponential.- Parameters:
surface (Optional[Surface]) – the surface that is to be stored in the tree. This must be a
RawSurface
subclassmax_depth (int) – The maximum depth when building the tree (resulting in
2**max_depth
nodes)_root (Optional[KDNode]) – The root node for the tree. This is only used for pickling/unpickling purposes and is typically not used by the user.
_rotation (Optional[Rotation]) – The current orientation from the world frame to the local tree frame as a
Rotation
. This is only used for pickling/unpickling purposes and is typically not used by the user._position (Optional[numpy.ndarray]) – The current location of the center of the tree in the world frame. This is only used for pickling/unpickling purposes and is typically not used by the user.
_bounding_box (Optional[AxisAlignedBoundingBox]) – The bounding box for the tree. This is only used for pickling/unpickling purposes and is typically not used by the user.
_reference_ellipsoid (Optional[Ellipsoid]) – The reference for the tree. This is only used for pickling/unpickling purposes and is typically not used by the user.
- bounding_box: AxisAlignedBoundingBox¶
The
AxisAlignedBoundingBox
that fully contains the surface represented by this acceleration structure.
- reference_ellipsoid: Ellipsoid¶
The
Ellipsoid
that best represents the surface represented by this acceleration structure.
- root: KDNode¶
The
KDNode
that serves as the root (initial branch node) of the tree. This is where all tracing begins
- surface: RawSurface¶
The
Surface
that this acceleration structure was built for as initially provided.Note that this does not get rotated/translated with the tree, so do not expect the
RawSurface.vertices
orRawSurface.normals
attributes to be in the current frame.
- max_depth: int¶
The maximum depth to which to build the tree.
The maximum depth puts a limit on how many branch nodes can end up in the tree as \(\sum_{i=0}^{\text{max_depth}}2^i\). In many cases however, you will end up with less than this maximum limit since we typically don’t split nodes with less than 10 primitives in them.
- order¶
The order for the tree, which is the same as the
order
of theroot
plus theid_order
of theroot
.Essentially this number represents the number of digits required to uniquely identify every geometry primitive contained in the tree.
- position¶
The current location of the center of the tree in the world frame as a numpy array.
This is used to translate the rays into the tree frame (using the opposite) which is typically more computationally more efficient than translating the entire tree
Summary of Methods
This method performs the branching of the tree down to the maximum depth. |
|
This method computes the intersects between a single ray and the surface describe by this object. |
|
This python method provides an easy interface to trace a number of Rays through the surface. |
|
This method determines the limb points for a surface (visible edge of the surface) that would be visible for an observer located at |
|
This method computes the linear change in the limb location given a change in the relative position between the surface and the observer. |
|
Rotate the tree by |
|
Translate the tree by translation. |
|
Use this method to dump the tree to a pickle file. |
|
Load a tree from a pickle file and overwrite this instance with that tree. |