/* compute normal vector of given triangle spanned by the points a, b, c */ static void triangle_normal( Vector *a, Vector *b, Vector *c, Vector *out ) { Vector v1 = *a; Vector v2 = *a; vector_sub( &v1, b ); vector_sub( &v2, c ); vector_crossprod( &v1, &v2, out ); }
ErrorCode update_torsional_angle(IndexValue bond, struct ResidueData *residues, IndexValue res, FloatValue *coords) { if (residues[res].bonds[bond].type == NOT_SET) { return ACCESSING_UNSET_BOND_ERROR; } IndexValue atom0, atom1, atom2, atom3; FloatValue x0, y0, z0; FloatValue x1, y1, z1; FloatValue x2, y2, z2; FloatValue x3, y3, z3; FloatValue x01, y01, z01; FloatValue x12, y12, z12; FloatValue x32, y32, z32; FloatValue px, py, pz; FloatValue qx, qy, qz; FloatValue rx, ry, rz; FloatValue u, v, u1, v1; FloatValue a; atom0 = residues[res].bonds[bond].atom0; x0 = coords[xcoord_index(atom0)]; y0 = coords[ycoord_index(atom0)]; z0 = coords[zcoord_index(atom0)]; atom1 = residues[res].bonds[bond].atom1; x1 = coords[xcoord_index(atom1)]; y1 = coords[ycoord_index(atom1)]; z1 = coords[zcoord_index(atom1)]; atom2 = residues[res].bonds[bond].atom2; x2 = coords[xcoord_index(atom2)]; y2 = coords[ycoord_index(atom2)]; z2 = coords[zcoord_index(atom2)]; atom3 = residues[res].bonds[bond].atom3; x3 = coords[xcoord_index(atom3)]; y3 = coords[ycoord_index(atom3)]; z3 = coords[zcoord_index(atom3)]; vector_subtract(&x01, &y01, &z01, x0, y0, z0, x1, y1, z1); // v01 = v0 - v1 vector_subtract(&x32, &y32, &z32, x3, y3, z3, x2, y2, z2); // v32 = v3 - v2 vector_subtract(&x12, &y12, &z12, x1, y1, z1, x2, y2, z2); // v12 = v1 - v2 vector_crossprod(&px, &py, &pz, x12, y12, z12, x01, y01, z01); // p = v12 x v01 vector_crossprod(&qx, &qy, &qz, x12, y12, z12, x32, y32, z32); // q = v12 x v32 vector_crossprod(&rx, &ry, &rz, x12, y12, z12, qx, qy, qz); // r = v12 x q vector_dotprod(&u, qx, qy, qz, qx, qy, qz); // u = q * q vector_dotprod(&v, rx, ry, rz, rx, ry, rz); // v = r * r if (u <= 0.0 || v <= 0.0) { a = 360.0; } else { vector_dotprod(&u1, px, py, pz, qx, qy, qz); // u1 = p * q vector_dotprod(&v1, px, py, pz, rx, ry, rz); // v1 = p * r u = u1 / sqrt(u); v = v1 / sqrt(v); if (fabs(u) > MIN_FLOAT_DIFF || fabs(v) > MIN_FLOAT_DIFF) a = atan2(v, u) * RADIANS_TO_DEGREES; else a = 360.0; } residues[res].bonds[bond].angle = a; residues[res].bonds[bond].newangle = a; return NO_ERROR; }