Example #1
0
        /// <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. Assign coordinates directly to the atoms.
        /// </summary>
        /// <param name="molecule">the molecule to be placed in 3D</param>
        /// <param name="flagBranched">marks branched chain</param>
        // @author: egonw,cho
        public virtual void ZMatrixChainToCartesian(IAtomContainer molecule, bool flagBranched)
        {
            Vector3?result = null;

            for (int index = 0; index < distances.Length; index++)
            {
                if (index == 0)
                {
                    result = new Vector3(0d, 0d, 0d);
                }
                else if (index == 1)
                {
                    result = new Vector3(distances[1], 0d, 0d);
                }
                else if (index == 2)
                {
                    result = new Vector3(-Math.Cos((angles[2] / 180) * Math.PI) * distances[2] + distances[1],
                                         Math.Sin((angles[2] / 180) * Math.PI) * distances[2], 0);
                }
                else
                {
                    var cd = molecule.Atoms[thirdAtoms[index]].Point3D.Value
                             - molecule.Atoms[secondAtoms[index]].Point3D.Value;
                    var bc = molecule.Atoms[secondAtoms[index]].Point3D.Value
                             - molecule.Atoms[firstAtoms[index - 3]].Point3D.Value;
                    var n1 = Vector3.Cross(cd, bc);
                    n1 = Vector3.Normalize(n1);

                    Vector3 n2;
                    if (index == 3 && flagBranched)
                    {
                        n2 = AtomTetrahedralLigandPlacer3D.Rotate(n1, bc, DIHEDRAL_BRANCHED_CHAIN);
                    }
                    else
                    {
                        n2 = AtomTetrahedralLigandPlacer3D.Rotate(n1, bc, dihedrals[index]);
                    }
                    n2 = Vector3.Normalize(n2);

                    Vector3 ba = new Vector3();
                    if (index == 3 && flagBranched)
                    {
                        ba = AtomTetrahedralLigandPlacer3D.Rotate(cd, n2, (-angles[index] / 180) * Math.PI);
                        ba = AtomTetrahedralLigandPlacer3D.Rotate(ba, cd, (-angles[index] / 180) * Math.PI);
                    }
                    else
                    {
                        ba = AtomTetrahedralLigandPlacer3D.Rotate(cd, n2, (-angles[index] / 180) * Math.PI);
                    }

                    ba = Vector3.Normalize(ba);

                    Vector3 ban = ba;
                    ban *= distances[index];

                    result = molecule.Atoms[firstAtoms[index - 1]].Point3D.Value + ban;
                }
                IAtom atom = molecule.Atoms[firstAtoms[index]];
                if ((atom.Point3D == null || !atom.IsPlaced) &&
                    !atom.IsInRing && IsHeavyAtom(atom))
                {
                    atom.Point3D  = result;
                    atom.IsPlaced = true;
                }
            }
        }
Example #2
0
        /// <summary>
        /// Layout the ring system, rotate and translate the template.
        /// </summary>
        /// <param name="originalCoord">coordinates of the placedRingAtom from the template</param>
        /// <param name="placedRingAtom">placedRingAtom</param>
        /// <param name="ringSet">ring system which placedRingAtom is part of</param>
        /// <param name="centerPlacedMolecule">the geometric center of the already placed molecule</param>
        /// <param name="atomB">placed neighbour atom of placedRingAtom</param>
        private static void LayoutRingSystem(Vector3 originalCoord, IAtom placedRingAtom, IRingSet ringSet,
                                             Vector3 centerPlacedMolecule, IAtom atomB, AtomPlacer3D ap3d)
        {
            //Debug.WriteLine("****** Layout ring System ******");Console.Out.WriteLine(">around atom:"+molecule.Atoms.IndexOf(placedRingAtom));
            IAtomContainer ac       = RingSetManipulator.GetAllInOneContainer(ringSet);
            Vector3        newCoord = placedRingAtom.Point3D.Value;
            Vector3        axis     = new Vector3(atomB.Point3D.Value.X - newCoord.X, atomB.Point3D.Value.Y - newCoord.Y, atomB.Point3D.Value.Z - newCoord.Z);

            TranslateStructure(originalCoord, newCoord, ac);
            //Rotate Ringsystem to farthest possible point
            Vector3 startAtomVector    = new Vector3(newCoord.X - atomB.Point3D.Value.X, newCoord.Y - atomB.Point3D.Value.Y, newCoord.Z - atomB.Point3D.Value.Z);
            IAtom   farthestAtom       = ap3d.GetFarthestAtom(placedRingAtom.Point3D.Value, ac);
            Vector3 farthestAtomVector = new Vector3(farthestAtom.Point3D.Value.X - newCoord.X, farthestAtom.Point3D.Value.Y - newCoord.Y, farthestAtom.Point3D.Value.Z - newCoord.Z);
            Vector3 n1 = Vector3.Cross(axis, farthestAtomVector);

            n1 = Vector3.Normalize(n1);
            double  lengthFarthestAtomVector = farthestAtomVector.Length();
            Vector3 farthestVector           = startAtomVector;

            farthestVector  = Vector3.Normalize(farthestVector);
            farthestVector *= startAtomVector.Length() + lengthFarthestAtomVector;
            double  dotProduct = Vector3.Dot(farthestAtomVector, farthestVector);
            double  angle      = Math.Acos(dotProduct / (farthestAtomVector.Length() * farthestVector.Length()));
            Vector3 ringCenter = new Vector3();

            for (int i = 0; i < ac.Atoms.Count; i++)
            {
                if (!(ac.Atoms[i].IsPlaced))
                {
                    ringCenter.X        = (ac.Atoms[i].Point3D).Value.X - newCoord.X;
                    ringCenter.Y        = (ac.Atoms[i].Point3D).Value.Y - newCoord.Y;
                    ringCenter.Z        = (ac.Atoms[i].Point3D).Value.Z - newCoord.Z;
                    ringCenter          = AtomTetrahedralLigandPlacer3D.Rotate(ringCenter, n1, angle);
                    ac.Atoms[i].Point3D =
                        new Vector3(ringCenter.X + newCoord.X, ringCenter.Y + newCoord.Y, ringCenter.Z + newCoord.Z);
                    //ac.GetAtomAt(i).IsPlaced = true;
                }
            }

            //Rotate Ring so that geometric center is max from placed center
            //Debug.WriteLine("Rotate RINGSYSTEM");
            Vector3 pointRingCenter = GeometryUtil.Get3DCenter(ac);
            double  distance        = 0;
            double  rotAngleMax     = 0;

            angle        = 1 / 180 * Math.PI;
            ringCenter   = new Vector3(pointRingCenter.X, pointRingCenter.Y, pointRingCenter.Z);
            ringCenter.X = ringCenter.X - newCoord.X;
            ringCenter.Y = ringCenter.Y - newCoord.Y;
            ringCenter.Z = ringCenter.Z - newCoord.Z;
            for (int i = 1; i < 360; i++)
            {
                ringCenter = AtomTetrahedralLigandPlacer3D.Rotate(ringCenter, axis, angle);
                if (Vector3.Distance(centerPlacedMolecule, new Vector3(ringCenter.X, ringCenter.Y, ringCenter.Z)) > distance)
                {
                    rotAngleMax = i;
                    distance    = Vector3.Distance(centerPlacedMolecule, new Vector3(ringCenter.X, ringCenter.Y, ringCenter.Z));
                }
            }

            //rotate ring around axis with best angle
            rotAngleMax = (rotAngleMax / 180) * Math.PI;
            for (int i = 0; i < ac.Atoms.Count; i++)
            {
                if (!(ac.Atoms[i].IsPlaced))
                {
                    ringCenter.X         = (ac.Atoms[i].Point3D).Value.X;
                    ringCenter.Y         = (ac.Atoms[i].Point3D).Value.Y;
                    ringCenter.Z         = (ac.Atoms[i].Point3D).Value.Z;
                    ringCenter           = AtomTetrahedralLigandPlacer3D.Rotate(ringCenter, axis, rotAngleMax);
                    ac.Atoms[i].Point3D  = new Vector3(ringCenter.X, ringCenter.Y, ringCenter.Z);
                    ac.Atoms[i].IsPlaced = true;
                }
            }
        }