void p3dp_print_atom_quartet_info (int iw, int l, int k, int j, int i, int lrank, int krank, int jrank, int irank) { double dxkj[4], dxij[4], angle, normal[4], dxlk[4], dxjk[4], dihedral; double sl[3], sk[3], sj[3], si[3]; p3dp_s(sl, l, lrank); p3dp_s(sk, k, krank); p3dp_s(sj, j, jrank); p3dp_s(si, i, irank); angle = p3dp_atom_triplet_s(sk, sj, si, dxkj, dxij); print_atom_pair_info_s(iw, i, j, irank, jrank, si, sj); if (IS_MANAGER) printf ("bond angle = %g degrees.\n", RADIAN_TO_DEGREE(angle)); print_atom_pair_info_s(iw, k, j, krank, jrank, sk, sj); V3CROSS (dxkj, dxij, normal); normal[3] = V3LENGTH2 (normal); angle = p3dp_atom_triplet_s(sl, sk, sj, dxlk, dxjk); if (IS_MANAGER) printf ("bond angle = %g degrees.\n", RADIAN_TO_DEGREE(angle)); print_atom_pair_info_s(iw, l, k, lrank, krank, sl, sk); /* right-handed helix gives positive dihedral angle */ if ( (normal[3]>0) && (dxlk[3]>0) ) dihedral = acos( V3DOT(normal,dxlk)/sqrt(normal[3])/sqrt(dxlk[3]) ) - PI / 2; else dihedral = 0; if (IS_MANAGER) printf ("dihedral angle = %g degrees.\n", RADIAN_TO_DEGREE(dihedral)); return; }
/* dxkj[], dxij[] and the bond angle in radian [0,pi] */ double atom_triplet (int k, int j, int i, double dxkj[4], double dxij[4]) { atom_pair (k, j, dxkj); atom_pair (i, j, dxij); if ( (dxkj[3]>0) && (dxij[3]>0) ) return( acos( V3DOT(dxkj, dxij) / sqrt(dxkj[3]) / sqrt(dxij[3]) ) ); else return (0); } /* end atom_triplet_angle() */
double p3dp_atom_triplet_s (double *sk, double *sj, double *si, double dxkj[4], double dxij[4]) { p3dp_atom_pair_s(sk, sj, dxkj); p3dp_atom_pair_s(si, sj, dxij); if ( (dxkj[3]>0) && (dxij[3]>0) ) return( acos( V3DOT(dxkj, dxij) / sqrt(dxkj[3]) / sqrt(dxij[3]) ) ); else return (0); }
/* use pointer device to translate the viewport */ bool pointer_translate (int iw, int to_x, int to_y) { double z, tmp[3]; if (n[iw].anchor >= 0) V3SUB (B->BALL[n[iw].anchor].x, AX_3D[iw].x, tmp); else V3SUB (n[iw].hook, AX_3D[iw].x, tmp); z = V3DOT (AX_3D[iw].V[2], tmp); tmp[0] = (n[iw].lx - to_x) / AX_3D[iw].k * z; V3ADDmuL (tmp[0], AX_3D[iw].V[0], AX_3D[iw].x); tmp[1] = (n[iw].ly - to_y) / AX_3D[iw].k * z; V3ADDmuL (tmp[1], AX_3D[iw].V[1], AX_3D[iw].x); n[iw].lx = to_x; n[iw].ly = to_y; return (TRUE); } /* end pointer_translate() */
void print_atom_quartet_info (int iw, int l, int k, int j, int i) { double dxkj[4], dxij[4], angle, normal[4], dxlk[4], dxjk[4], dihedral; angle = atom_triplet (k, j, i, dxkj, dxij); print_atom_pair_info (iw, i, j); printf ("bond angle = %g degrees.\n", RADIAN_TO_DEGREE(angle)); print_atom_pair_info (iw, k, j); V3CROSS (dxkj, dxij, normal); normal[3] = V3LENGTH2 (normal); angle = atom_triplet (l, k, j, dxlk, dxjk); printf ("bond angle = %g degrees.\n", RADIAN_TO_DEGREE(angle)); print_atom_pair_info (iw, l, k); /* right-handed helix gives positive dihedral angle */ if ( (normal[3]>0) && (dxlk[3]>0) ) dihedral = acos( V3DOT(normal,dxlk)/sqrt(normal[3])/sqrt(dxlk[3]) ) - PI / 2; else dihedral = 0; printf ("dihedral angle = %g degrees.\n", RADIAN_TO_DEGREE(dihedral)); return; } /* end print_atom_quartet_info() */
/* use pointer device to shift the crystal */ bool pointer_grab_xtal_shift (int iw, int to_x, int to_y) { double z, tmp[3]; if (!n[iw].xtal_mode) { printf ("Crystal translation is only available under Xtal mode.\n"); return(FALSE); } if ((n[iw].lx == to_x) && (n[iw].ly == to_y)) return (FALSE); if (n[iw].anchor >= 0) V3SUB (B->BALL[n[iw].anchor].x, AX_3D[iw].x, tmp); else V3SUB (n[iw].hook, AX_3D[iw].x, tmp); z = V3DOT (AX_3D[iw].V[2], tmp); tmp[0] = (n[iw].lx - to_x) / AX_3D[iw].k * z; V3ADDmuL (tmp[0], AX_3D[iw].V[0], n[iw].xtal_origin); tmp[1] = (n[iw].ly - to_y) / AX_3D[iw].k * z; V3ADDmuL (tmp[1], AX_3D[iw].V[1], n[iw].xtal_origin); n[iw].lx = to_x; n[iw].ly = to_y; atom_xtal_origin (n[iw].xtal_origin); if (n[iw].bond_mode) bond_xtal_origin_update (iw); else n[iw].bond_xtal_origin_need_update = TRUE; return (TRUE); } /* end pointer_grab_xtal_shift() */