#ifndef STIM_CIRCLE_H #define STIM_CIRCLE_H #include #include #include #include #include #include #include #include namespace stim{ template class circle : plane { private: //stim::vec3 Y; T R; //radius of the circle /*CUDA_CALLABLE void init() { Y = U.cross(N).norm(); }*/ public: using stim::plane::n; using stim::plane::P; using stim::plane::N; using stim::plane::U; using stim::plane::rotate; using stim::plane::setU; using stim::plane::init; ///base constructor ///@param th value of the angle of the starting point from 0 to 360. CUDA_CALLABLE circle() : plane() { init(); } ///create a circle 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 circle(T radius, T z_pos = (T)0) : plane(z_pos) { //center(stim::vec3(0, 0, z_pos)); //scale(size); //init(); R = radius; } ///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 circle(vec3 c, vec3 n = vec3(0,0,1)) : plane(n, c) { //center(c); //normal(n); //init(); R = (T)1; } /*///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 circle(vec3 c, T s, vec3 n = vec3(0,0,1)) : plane() { init(); center(c); rotate(n, U, Y); scale(s); } */ ///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. ///@param u: x,y,z direction for the zero vector (from where the rotation starts) CUDA_CALLABLE circle(vec3 c, T r, vec3 n = vec3(0,0,1), vec3 u = vec3(1, 0, 0)) : plane() { P = c; N = n; setU(u); R = r; //init(); //setU(u); // U = u; //center(c); //normal(n); //scale(s); } ///scales the circle by a certain factor ///@param factor: the factor by which the dimensions of the shape are scaled. CUDA_CALLABLE void scale(T factor) { //U *= factor; //Y *= factor; R *= factor; } ///set the radius of circle to a certain value ///@param value: the new radius of the circle CUDA_CALLABLE void set_R(T value) { R = value; } ///sets the normal for the cirlce ///@param n: x,y,z direction of the normal. CUDA_CALLABLE void normal(vec3 n){ rotate(n); } ///sets the center of the circle. ///@param n: x,y,z location of the center. CUDA_CALLABLE void center(vec3 p){ P = p; } ///boolean comparison bool operator==(const circle & rhs) { if(P == rhs.P && U == rhs.U) return true; else return false; } //returns the point in world space corresponding to the polar coordinate (r, theta) CUDA_CALLABLE stim::vec3 p(T r, T theta) { T u = r * cos(theta); //calculate the coordinates in the planar space defined by the circle T v = r * sin(theta); vec3 V = U.cross(N); //calculate the orthogonal vector V return P + U * u + V * v; //calculate the cartesian coordinate of the specified point } //returns the point in world space corresponding to the value theta at radius R CUDA_CALLABLE stim::vec3 p(T theta) { return p(R, theta); } //get the world space value given the polar coordinates (r, theta) ///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; vec3 A = this->P - this->U * (T)0.5 - Y * (T)0.5; result = A + this->U * 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 r, T theta) { return p(r, theta); } //parenthesis operator returns the world space coordinate at the edge of the circle given theta CUDA_CALLABLE stim::vec3 operator()(T theta) { return p(theta); } ///returns a vector with the points on the initialized circle. ///connecting the points results in a circle. ///@param n: integer for the number of points representing the circle. std::vector< stim::vec3 > points(unsigned n) { std::vector< stim::vec3 > result(n); //initialize a vector of n points float dt = stim::TAU / n; for (unsigned i = 0; i < n; i++) result[i] = p(i * dt); //calculate a point on the edge of the circle return result; } ///returns a vector with the points on the initialized circle ///connecting the points results in a circle ///@param n: integer for the number of points representing the circle ///the only difference between points and glpoints is that the first point appears twice in the returning lists std::vector< stim::vec3 > glpoints(unsigned n) { std::vector< stim::vec3 > result(n + 1); float dt = stim::TAU / n; for (unsigned i = 0; i < n; i++) result[i] = p(i * dt); result[n] = p(0); //close the circle! return result; } std::string str() const { std::stringstream ss; ss << "r = "<