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 ( - Math . cos ( ( angles [ 2 ] / 180 ) * Math . PI ) * distances [ 2 ] + distances [ 1 ] , Math . sin ( ( angles [ 2 ] / 180 ) * Math . PI ) * distances [ 2 ] , 0d ) ; if ( first_atoms [ index ] == 0 ) cartesianCoords [ index ] . x = ( cartesianCoords [ index ] . x - distances [ 1 ] ) * - 1 ; } 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 ) ; Vector3d n2 = rotate ( n1 , bc , - dihedrals [ index ] ) ; Vector3d ba = rotate ( bc , n2 , - angles [ index ] ) ; ba . normalize ( ) ; ba . scale ( distances [ index ] ) ; Point3d result = new Point3d ( ) ; result . add ( cartesianCoords [ first_atoms [ index ] ] , ba ) ; cartesianCoords [ index ] = result ; } } return cartesianCoords ; }
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 . Angles are in degrees .