Sphere::Sphere(double x, double y, double z, material_t material, double radius) { init(vector3_t({x, y, z}), material, radius); }
complex_t FormFactorTriangle(real_t qx, real_t qy, complex_t qz, RotMatrix_t & rot, triangle_t & tri) { complex_t ff = CMPLX_ZERO_; complex_t unitc = CMPLX_ONE_; complex_t n_unitc = CMPLX_MINUS_ONE_; // do the rotation std::vector<complex_t> mq = rot.rotate (qx, qy, qz); // calculate q^2 real_t q_sqr = 0.; for(int i=0; i<3; i++) q_sqr += std::norm(mq[i]); // form vertices std::vector<vector3_t> vertex; vertex.resize(3); vertex[0] = vector3_t(tri.v1[0], tri.v1[1], tri.v1[2]); vertex[1] = vector3_t(tri.v2[0], tri.v2[1], tri.v2[2]); vertex[2] = vector3_t(tri.v3[0], tri.v3[1], tri.v3[2]); // form edges std::vector<vector3_t> edge; edge.resize(3); edge[0] = vertex[1] - vertex[0]; edge[1] = vertex[2] - vertex[1]; edge[2] = vertex[0] - vertex[2]; // calculate projection of n_t on q vector3_t n_t = cross(edge[0], edge[1]); real_t t_area = 0.5 * n_t.abs(); n_t = n_t / n_t.abs(); // dot(q, n_t) complex_t q_dot_nt = CMPLX_ZERO_; for (int i=0; i<3; i++) q_dot_nt += mq[i] * n_t[i]; // proj_tq real_t proj_tq = q_sqr - std::norm(q_dot_nt); // CASE 1 if (std::abs(proj_tq) < TINY_){ complex_t q_dot_v = CMPLX_ZERO_; for (int i=0; i<3; i++) q_dot_v += mq[i] * tri.v1[i]; // calculate form-factor (Case 1) ff = unitc * q_dot_nt * t_area / q_sqr * std::exp(n_unitc * q_dot_v); } else { // iterate of each edge to compute form-factor for (int e = 0; e < 3; e++) { // edge-normal vector3_t n_e = cross(edge[e], n_t); n_e = n_e / n_e.abs(); // dot (q, n_e) complex_t q_dot_ne = CMPLX_ZERO_; for (int i=0; i<3; i++) q_dot_ne += mq[i] * n_e[i]; // proj_eq real_t proj_eq = proj_tq - std::norm(q_dot_ne); // CASE 2 if (std::abs(proj_eq) < TINY_){ // q_dot_v complex_t q_dot_v = CMPLX_ZERO_; for (int i=0; i<3; i++) q_dot_v += mq[i] * vertex[e][i]; real_t f0 = edge[e].abs() / (q_sqr * proj_tq); complex_t c0 = - q_dot_nt * q_dot_ne; complex_t c1 = std::exp(n_unitc * q_dot_v); ff += f0 * c0 * c1; } else { // CASE 3 (General case) // denominator real_t f0 = q_sqr * proj_tq * proj_eq; // dot(q, v_a) vertex a complex_t q_dot_v = CMPLX_ZERO_; for (int i=0; i<3; i++) q_dot_v += mq[i] * vertex[e][i]; // vertrex-normal a vector3_t n_v = edge[e] / edge[e].abs(); // dot(q, n_v) complex_t q_dot_nv = CMPLX_ZERO_; for (int i=0; i<3; i++) q_dot_nv += mq[i] * n_v[i]; // calculate contribution of vertex a complex_t c0 = n_unitc * q_dot_nt * q_dot_ne * q_dot_nv; complex_t c1 = std::exp(n_unitc * q_dot_v); ff += c0 * c1 / f0; // dot(q, v) the other vertex in the edge q_dot_v = CMPLX_ZERO_; int ep = (e+1)%3; for (int i=0; i<3; i++) q_dot_v += mq[i] * vertex[ep][i]; // dot (q, n_v) q_dot_nv = CMPLX_ZERO_; for (int i=0; i<3; i++) q_dot_nv -= mq[i] * n_v[i]; // calculate contribution of the other vertex c0 = n_unitc * q_dot_nt * q_dot_ne * q_dot_nv; c1 = std::exp(n_unitc * q_dot_v); ff += c0 * c1 / f0; } } } return ff; }
vector3_t min <vector3_t> (vector3_t a, vector3_t b) { return vector3_t((a[0] < b[0] ? a[0] : b[0]), (a[1] < b[1] ? a[1] : b[1]), (a[2] < b[2] ? a[2] : b[2])); } // min <vector3_t>
vector3_t max <vector3_t> (vector3_t a, vector3_t b) { return vector3_t((a[0] > b[0] ? a[0] : b[0]), (a[1] > b[1] ? a[1] : b[1]), (a[2] > b[2] ? a[2] : b[2])); } // max <vector3_t>
/** * specialized floor function */ vector3_t floor(vector3_t a) { return vector3_t(std::floor(a[0]), std::floor(a[1]), std::floor(a[2])); } // floor()