/* * Calc A0 matrix from lattice parameters and wavelength, and return it as r[][]. * Lattice spacings a,b,c and wavelength lambda are in same (arbitrary) units. * Lattice angles alpha, beta, gamma are in units of degrees. */ int calc_A0(double a, double b, double c, double alpha_arg, double beta_arg, double gamma_arg, double lambda, double r[3][3], double r_i[3][3]) { double A[3], B[3], C[3]; double AxB[3], BxC[3], CxA[3]; double tmp; double alpha = alpha_arg * D2R; double beta = beta_arg * D2R; double gamma = gamma_arg * D2R; if (orientDebug) printf("calc_A0: a=%f,b=%f,c=%f,alpha=%f,beta=%f,gamma=%f,lambda=%f\n", a,b,c,alpha,beta,gamma,lambda); A[0] = a; A[1] = 0; A[2] = 0; if (orientDebug) printVector(A, "calc_A0:A"); B[0] = b * cos(gamma); B[1] = b * sin(gamma); B[2] = 0; if (orientDebug) printVector(B, "calc_A0:B"); tmp = (cos(alpha) - cos(beta)*cos(gamma))/sin(gamma); C[0] = c * cos(beta); C[1] = c * tmp; C[2] = c * sqrt(1 - cos(beta)*cos(beta) - tmp*tmp); if (orientDebug) printVector(C, "calc_A0:C"); /* r = factor * |BxC, CxA, AxB| */ tmp = lambda/(2 * dotcross(A,B,C)); if (orientDebug) printf("calc_A0: lambda/(2*AXB.C) = %f\n", tmp); cross(A, B, AxB); cross(B, C, BxC); cross(C, A, CxA); if (orientDebug) { printVector(AxB, "calc_A0:AxB"); printVector(BxC, "calc_A0:BxC"); printVector(CxA, "calc_A0:CxA"); } r[0][0] = tmp * BxC[0]; r[0][1] = tmp * CxA[0]; r[0][2] = tmp * AxB[0]; r[1][0] = tmp * BxC[1]; r[1][1] = tmp * CxA[1]; r[1][2] = tmp * AxB[1]; r[2][0] = tmp * BxC[2]; r[2][1] = tmp * CxA[2]; r[2][2] = tmp * AxB[2]; if (invertArray(r, r_i)) { int i, j; /* error */ if (orientDebug) { printf("calc_A0: can't invert A0 matrix\n"); printArray(r, "A0"); } for (i=0; i<3; i++) { for (j=0; j<3; j++) { r[i][j] = r_i[i][j] = (i==j ? 1 : 0); } } return(-1); } return(0); }
num_t v3_t<num_t>::tetrahedron_volume(const v3_t<num_t>& a, const v3_t<num_t>& b, const v3_t<num_t>& c, const v3_t<num_t>& d) { return dotcross((a - d), (b - d), (c - d)) / num_t(6); }
// Volume of a tetrahedron described by 4 points. Will be // positive if the anticlockwise normal of a,b,c is oriented out // of the tetrahedron. // // see: http://mathworld.wolfram.com/Tetrahedron.html inline double tetrahedronVolume(const Vector &a, const Vector &b, const Vector &c, const Vector &d) { return dotcross((a - d), (b - d), (c - d)) / 6.0; }
num_t v3_t<num_t>::orient(const v3_t<num_t>& a, const v3_t<num_t>& b, const v3_t<num_t>& c, const v3_t<num_t>& d) { return dotcross((a - d), (b - d), (c - d)); }
inline double orient3d(const Vector &a, const Vector &b, const Vector &c, const Vector &d) { return dotcross((a - d), (b - d), (c - d)); }