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); }
/// <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; } } }