public void TestGetFarthestAtom_Point3d_IAtomContainer()
        {
            AtomPlacer3D   atmplacer = new AtomPlacer3D();
            IAtomContainer molecule  = TestMoleculeFactory.MakeBenzene();

            molecule.Atoms[0].Point3D = new Vector3(0.0, 0.0, 0.0);
            molecule.Atoms[1].Point3D = new Vector3(1.0, 1.0, 1.0);
            molecule.Atoms[4].Point3D = new Vector3(3.0, 2.0, 1.0);
            molecule.Atoms[5].Point3D = new Vector3(4.0, 4.0, 4.0);

            IAtom farthestFromAtoma = atmplacer.GetFarthestAtom(molecule.Atoms[0].Point3D.Value, molecule);
            IAtom farthestFromAtomb = atmplacer.GetFarthestAtom(molecule.Atoms[4].Point3D.Value, molecule);

            Assert.AreEqual(molecule.Atoms[5], farthestFromAtoma);
            Assert.AreEqual(molecule.Atoms[0], farthestFromAtomb);
        }
Esempio n. 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;
                }
            }
        }