aabbn.h 2.58 KB
#ifndef STIM_AABBN_H
#define STIM_AABBN_H

#include <vector>
#include <stim/cuda/cudatools/callable.h>

namespace stim{

/// Structure for a 3D axis aligned bounding box
template<typename T, size_t D>
struct aabbn{

//protected:

	T low[D];					//top left corner position
	T high[D]; 							//dimensions along x and y and z

	CUDA_CALLABLE void init(T* i) {
		for (size_t d = 0; d < D; d++)
			low[d] = high[d] = i[d];
	}

	CUDA_CALLABLE aabbn() {}
	CUDA_CALLABLE aabbn(T* i) {
		init(i);
	}

	/// For even inputs to the constructor, the input could be one point or a set of pairs of points
	CUDA_CALLABLE aabbn(T x0, T x1) {
		if (D == 1) {
			low[0] = x0;
			high[0] = x1;
		}
		else if (D == 2) {
			low[0] = high[0] = x0;
			low[1] = high[1] = x1;
		}
	}

	/// In the case of 3 inputs, this must be a 3D bounding box, so initialize to a box of size 0 at (x, y, z)
	/*CUDA_CALLABLE aabbn(T x, T y, T z) {
		low[0] = high[0] = x;
		low[1] = high[1] = y;
		low[2] = high[2] = z;
	}*/

	CUDA_CALLABLE aabbn(T x0, T y0, T x1, T y1) {
		if (D == 2) {
			low[0] = x0;
			high[0] = x1;
			low[1] = y0;
			high[1] = y1;
		}
		else if(D == 4){
			low[0] = high[0] = x0;
			low[1] = high[1] = y0;
			low[2] = high[2] = x1;
			low[3] = high[3] = y1;
		}
	}

	/*CUDA_CALLABLE aabbn(T x0, T y0, T z0, T x1, T y1, T z1) {
		if (D == 3) {
			low[0] = x0;
			high[0] = x1;
			low[1] = y0;
			high[1] = y1;
			low[2] = z0;
			high[2] = z1;
		}
		else if (D == 6) {
			low[0] = high[0] = x0;
			low[1] = high[1] = y0;
			low[2] = high[2] = z0;
			low[3] = high[3] = x1;
			low[4] = high[4] = y1;
			low[5] = high[5] = z1;
		}
	}*/
	

	//insert a point into the bounding box, growing the box appropriately
	CUDA_CALLABLE void insert(T* p){
		for(size_t d = 0; d < D; d++){
			if(p[d] < low[d]) low[d] = p[d];
			if(p[d] > high[d]) high[d] = p[d];
		}
	}

	//trim the bounding box so that the lower bounds are b(x, y, z, ...)
	CUDA_CALLABLE void trim_low(T* b){
		for(size_t d = 0; d < D; d++)
			if(low[d] < b[d]) low[d] = b[d];
	}

	CUDA_CALLABLE void trim_high(T* b){
		for(size_t d = 0; d < D; d++)
			if(high[d] > b[d]) high[d] = b[d];
	}

	CUDA_CALLABLE T length(size_t d) {
		return high[d] - low[d];
	}

	CUDA_CALLABLE aabbn<T, D> operator*(T s) {
		aabbn<T, D> newbox;
		for (size_t d = 0; d < D; d++) {
			T c = (low[d] + high[d]) / 2;
			T l = high[d] - low[d];
			newbox.low[d] = c - l * s / 2;
			newbox.high[d] = c + l * s / 2;
		}
		return newbox;
	}

	//translate the box along dimension d a distance of v
	CUDA_CALLABLE void translate(size_t d, T v) {
		for (size_t d = 0; d < D; d++) {
			low[d] += v;
			high[d] += v;
		}
	}

};

}


#endif