/// <summary> Takes the given Z Matrix coordinates and converts them to cartesian coordinates. /// The first Atom end up in the origin, the second on on the x axis, and the third /// one in the XY plane. The rest is added by applying the Zmatrix distances, angles /// and dihedrals. /// /// </summary> /// <param name="distances"> Array of distance variables of the Z matrix /// </param> /// <param name="angles"> Array of angle variables of the Z matrix /// </param> /// <param name="dihedrals"> Array of distance variables of the Z matrix /// </param> /// <param name="first_atoms"> Array of atom ids of the first involed atom in distance, angle and dihedral /// </param> /// <param name="second_atoms"> Array of atom ids of the second involed atom in angle and dihedral /// </param> /// <param name="third_atoms"> Array of atom ids of the third involed atom in dihedral /// /// </param> /// <cdk.dictref> blue-obelisk:zmatrixCoordinatesIntoCartesianCoordinates </cdk.dictref> public static Point3d[] zmatrixToCartesian(double[] distances, int[] first_atoms, double[] angles, int[] second_atoms, double[] dihedrals, int[] third_atoms) { Point3d[] cartesianCoords = new Point3d[distances.Length]; for (int index = 0; index < distances.Length; index++) { if (index == 0) { cartesianCoords[index] = new Point3d(0d, 0d, 0d); } else if (index == 1) { cartesianCoords[index] = new Point3d(distances[1], 0d, 0d); } else if (index == 2) { cartesianCoords[index] = new Point3d((-System.Math.Cos((angles[2] / 180) * System.Math.PI)) * distances[2] + distances[1], System.Math.Sin((angles[2] / 180) * System.Math.PI) * distances[2], 0d); } else { Vector3d cd = new Vector3d(); cd.sub(cartesianCoords[third_atoms[index]], cartesianCoords[second_atoms[index]]); Vector3d bc = new Vector3d(); bc.sub(cartesianCoords[second_atoms[index]], cartesianCoords[first_atoms[index]]); Vector3d n1 = new Vector3d(); n1.cross(cd, bc); n1.normalize(); Vector3d n2 = rotate(n1, bc, dihedrals[index]); n2.normalize(); Vector3d ba = rotate(bc, n2, -angles[index]); ba.normalize(); Vector3d ban = new Vector3d(ba); ban.scale(distances[index]); Point3d result = new Point3d(); result.add(cartesianCoords[first_atoms[index]], ba); cartesianCoords[index] = result; } } return cartesianCoords; }
private static double getAngle(IAtom atom1, IAtom atom2, IAtom atom3) { Vector3d centerAtom = new Vector3d(); centerAtom.x = atom1.X3d; centerAtom.y = atom1.Y3d; centerAtom.z = atom1.Z3d; Vector3d firstAtom = new Vector3d(); Vector3d secondAtom = new Vector3d(); firstAtom.x = atom2.X3d; firstAtom.y = atom2.Y3d; firstAtom.z = atom2.Z3d; secondAtom.x = atom3.X3d; secondAtom.y = atom3.Y3d; secondAtom.z = atom3.Z3d; firstAtom.sub(centerAtom); secondAtom.sub(centerAtom); return firstAtom.angle(secondAtom); }