vec3 PLANE_Intersect( const Plane &p1, const Plane &p2, const Plane &p3 ) { vec3 n2n3 = CrossP( p2.n, p3.n ); vec3 n3n1 = CrossP( p3.n, p1.n ); vec3 n1n2 = CrossP( p1.n, p2.n ); vec3 p = ( p1.d * n2n3 + p2.d * n3n1 + p3.d * n1n2 ) / -( p1.n * n2n3 ); return p; }
/***=======================================================================***/ double Dihedral(double* alocs, double* blocs, double* clocs, double* dlocs) { int i; double theta, acosarg; double ab[3], bc[3], cd[3], scr[3], crabbc[3], crbccd[3]; for (i = 0; i < 3; i++) { ab[i] = blocs[i] - alocs[i]; bc[i] = clocs[i] - blocs[i]; cd[i] = dlocs[i] - clocs[i]; } CrossP(ab, bc, crabbc); CrossP(bc, cd, crbccd); acosarg = DotP(crabbc, crbccd, 3)/(DMag(crabbc, 3)*DMag(crbccd, 3)); CrossP(crabbc, crbccd, scr); if (DotP(scr, bc, 3) > 0.0) { theta = acos(TrimAcos(acosarg)); } else { theta = -acos(TrimAcos(acosarg)); } return theta; }
/***=======================================================================***/ void UnitNormal2Plane(double* unv, double* A, double* B, double* C) { int i; double BA[3], BC[3]; /*** Compute the vectors BA and BC ***/ BA[0] = A[0] - B[0]; BA[1] = A[1] - B[1]; BA[2] = A[2] - B[2]; BC[0] = C[0] - B[0]; BC[1] = C[1] - B[1]; BC[2] = C[2] - B[2]; /*** Take the cross product and normalize ***/ CrossP(BA, BC, unv); UnitVector3(unv); }
/***=======================================================================***/ int BiColorGrid(bgrid tg, double* crds, int natm, dmat U, dmat invU, double R, int updateUser) { int h, h3, i, j, k, ibuff, jbuff, kbuff, ncol; int imin, jmin, kmin, imax, jmax, kmax; double ax, ay, az, dx, dy, dz, R2; double xyz0[3], ic1[3], ic2[3], ic3[3], thx[3], thy[3], thz[3]; double px, py, pz; /*** Grid coloring counter ***/ ncol = 0; /*** Determine limits ***/ R2 = R*R; xyz0[0] = invU.data[0] + invU.data[1] + invU.data[2]; xyz0[1] = invU.data[4] + invU.data[5]; xyz0[2] = invU.data[8]; for (i = 0; i < 3; i++) { ic1[i] = invU.map[i][0]; ic2[i] = invU.map[i][1]; ic3[i] = invU.map[i][2]; } CrossP(ic2, ic3, thx); CrossP(ic1, ic3, thy); CrossP(ic1, ic2, thz); Normalize(thx, 3); Normalize(thy, 3); Normalize(thz, 3); ibuff = ceil(tg.lx/(fabs(DotP(thx, xyz0, 3))/R))+1.01; jbuff = ceil(tg.ly/(fabs(DotP(thy, xyz0, 3))/R))+1.01; kbuff = ceil(tg.lz/(fabs(DotP(thz, xyz0, 3))/R))+1.01; for (h = 0; h < natm; h++) { if (h % 64 == 0 && updateUser == 1) { fprintf(stderr, "\rBiColorGrid >> Coloring atom %6d", h); fflush(stderr); } h3 = 3*h; ax = crds[h3] - tg.ox; ay = crds[h3+1] - tg.oy; az = crds[h3+2] - tg.oz; i = ax / tg.gx; j = ay / tg.gy; k = az / tg.gz; imin = (i > ibuff) ? i - ibuff : 0; imax = (i + ibuff < tg.lx) ? i + ibuff : tg.lx; jmin = (j > jbuff) ? j - jbuff : 0; jmax = (j + jbuff < tg.ly) ? j + jbuff : tg.ly; kmin = (k > kbuff) ? k - kbuff : 0; kmax = (k + kbuff < tg.lz) ? k + kbuff : tg.lz; for (i = imin; i < imax; i++) { dx = ax - i*tg.gx; for (j = jmin; j < jmax; j++) { dy = ay - j*tg.gy; for (k = kmin; k < kmax; k++) { if (ReadBoolGrid(tg, i, j, k) == 1) { continue; } dz = az - k*tg.gz; px = invU.data[0]*dx + invU.data[1]*dy + invU.data[2]*dz; py = invU.data[3]*dx + invU.data[4]*dy + invU.data[5]*dz; pz = invU.data[6]*dx + invU.data[7]*dy + invU.data[8]*dz; if (px*px + py*py + pz*pz < R2) { /*** Color this grid point ***/ WriteBoolGrid(tg, i, j, k, 1); ncol++; } } } } } return ncol; }