#ifndef STIM_RECT_H #define STIM_RECT_H //enable CUDA_CALLABLE macro #include #include #include #include #include #include #include #include namespace stim{ //template for a rectangle class in ND space template class rect : plane { /* ^ O | | Y P | | O---------X---------> */ protected: stim::vec3 X; stim::vec3 Y; public: using stim::plane::n; using stim::plane::P; using stim::plane::N; using stim::plane::U; using stim::plane::rotate; ///base constructor. CUDA_CALLABLE rect() : plane() { init(); } ///create a rectangle given a size and position in Z space. ///@param size: size of the rectangle in ND space. ///@param z_pos z coordinate of the rectangle. CUDA_CALLABLE rect(T size, T z_pos = (T)0) : plane(z_pos) { init(); //use the default setup scale(size); //scale the rectangle } ///create a rectangle from a center point, normal ///@param c: x,y,z location of the center. ///@param n: x,y,z direction of the normal. CUDA_CALLABLE rect(vec3 c, vec3 n = vec3(0, 0, 1)) : plane() { init(); //start with the default setting normal(n); //orient } ///create a rectangle from a center point, normal, and size ///@param c: x,y,z location of the center. ///@param s: size of the rectangle. ///@param n: x,y,z direction of the normal. CUDA_CALLABLE rect(vec3 c, T s, vec3 n = vec3(0, 0, 1)) : plane() { init(); //start with the default setting scale(s); center(c); rotate(n, X, Y); } ///creates a rectangle from a centerpoint and an X and Y direction vectors. ///@param center: x,y,z location of the center. ///@param directionX: u,v,w direction of the X vector. ///@param directionY: u,v,w direction of the Y vector. CUDA_CALLABLE rect(vec3 center, vec3 directionX, vec3 directionY ) : plane((directionX.cross(directionY)).norm(),center) { X = directionX; Y = directionY; } ///creates a rectangle from a size, centerpoint, X, and Y direction vectors. ///@param size of the rectangle in ND space. ///@param center: x,y,z location of the center. ///@param directionX: u,v,w direction of the X vector. ///@param directionY: u,v,w direction of the Y vector. CUDA_CALLABLE rect(T size, vec3 center, vec3 directionX, vec3 directionY ) : plane((directionX.cross(directionY)).norm(),center) { X = directionX; Y = directionY; scale(size); } ///creates a rectangle from a size, centerpoint, X, and Y direction vectors. ///@param size of the rectangle in ND space, size[0] = size in X, size[1] = size in Y. ///@param center: x,y,z location of the center. ///@param directionX: u,v,w direction of the X vector. ///@param directionY: u,v,w direction of the Y vector. CUDA_CALLABLE rect(vec3 size, vec3 center, vec3 directionX, vec3 directionY) : plane((directionX.cross(directionY)).norm(), center) { X = directionX; Y = directionY; scale(size[0], size[1]); } CUDA_CALLABLE void scale(T factor){ X *= factor; Y *= factor; } ///scales a rectangle in ND space. ///@param factor1: size of the scale in the X-direction. ///@param factor2: size of the scale in the Y-direction. CUDA_CALLABLE void scale(T factor1, T factor2) { X *= factor1; Y *= factor2; } ///@param n; vector with the normal. ///Orients the rectangle along the normal n. CUDA_CALLABLE void normal(vec3 n) { //orient the rectangle along the specified normal rotate(n, X, Y); } ///general init method that sets a general rectangle. CUDA_CALLABLE void init() { X = vec3(1, 0, 0); Y = vec3(0, 1, 0); } //boolean comparison bool operator==(const rect & rhs) { if(P == rhs.P && X == rhs.X && Y == rhs.Y) return true; else return false; } //get the world space value given the planar coordinates a, b in [0, 1] CUDA_CALLABLE stim::vec3 p(T a, T b) { stim::vec3 result; //given the two parameters a, b = [0 1], returns the position in world space vec3 A = this->P - X * (T)0.5 - Y * (T)0.5; result = A + X * a + Y * b; return result; } //parenthesis operator returns the world space given rectangular coordinates a and b in [0 1] CUDA_CALLABLE stim::vec3 operator()(T a, T b) { return p(a, b); } std::string str() { std::stringstream ss; vec3 A = P - X * (T)0.5 - Y * (T)0.5; ss<"<<"C="<"<<"D="< operator*(T rhs) { //scales the plane by a scalar value //create the new rectangle rect result = *this; result.scale(rhs); return result; } ///computes the distance between the specified point and this rectangle. ///@param p: x, y, z coordinates of the point to calculate distance to. CUDA_CALLABLE T dist(vec3 p) { //compute the distance between a point and this rect vec3 A = P - X * (T)0.5 - Y * (T)0.5; //first break the rect up into two triangles triangle T0(A, A+X, A+Y); triangle T1(A+X+Y, A+X, A+Y); T d0 = T0.dist(p); T d1 = T1.dist(p); if(d0 < d1) return d0; else return d1; } CUDA_CALLABLE T center(vec3 p) { this->P = p; } ///Returns the maximum distance of the rectangle from a point p to the sides of the rectangle. ///@param p: x, y, z point. CUDA_CALLABLE T dist_max(vec3 p) { vec3 A = P - X * (T)0.5 - Y * (T)0.5; T da = (A - p).len(); T db = (A+X - p).len(); T dc = (A+Y - p).len(); T dd = (A+X+Y - p).len(); return std::max( da, std::max(db, std::max(dc, dd) ) ); } }; } //end namespace rts template std::ostream& operator<<(std::ostream& os, stim::rect R) { os<