📄 atomtetrahedralligandplacer3d.java
字号:
public Point3d[] get3DCoordinatesForSP3Ligands(IAtom refAtom, IAtomContainer noCoords, IAtomContainer withCoords, IAtom atomC, int nwanted, double length, double angle) { //logger.debug("SP3 Ligands start "); Point3d newPoints[] = new Point3d[0]; Point3d aPoint = refAtom.getPoint3d(); int nwithCoords = withCoords.getAtomCount(); if (angle < 0) { angle = TETRAHEDRAL_ANGLE; } if (nwithCoords == 0) { newPoints = calculate3DCoordinates0(refAtom.getPoint3d(), nwanted, length); } else if (nwithCoords == 1) { newPoints = calculate3DCoordinates1(aPoint, (withCoords.getAtom(0)).getPoint3d(), (atomC != null) ? atomC.getPoint3d() : null, nwanted, length, angle); } else if (nwithCoords == 2) { Point3d bPoint = withCoords.getAtom(0).getPoint3d(); Point3d cPoint = withCoords.getAtom(1).getPoint3d(); newPoints = calculate3DCoordinates2(aPoint, bPoint, cPoint, nwanted, length, angle); } else if (nwithCoords == 3) { Point3d bPoint = withCoords.getAtom(0).getPoint3d(); Point3d cPoint = withCoords.getAtom(1).getPoint3d(); newPoints = new Point3d[1]; Point3d dPoint = withCoords.getAtom(2).getPoint3d(); newPoints[0] = calculate3DCoordinates3(aPoint, bPoint, cPoint, dPoint, length); } //logger.debug("...Ready"); return newPoints; } /** * Calculates substituent points. Calculate substituent points for (0) zero * ligands of aPoint. The resultant points are randomly oriented: (i) 1 points * required; +x,0,0 (ii) 2 points: use +x,0,0 and -x,0,0 (iii) 3 points: * equilateral triangle in xy plane (iv) 4 points x,x,x, x,-x,-x, -x,x,-x, * -x,-x,x where 3x**2 = bond length * *@param aPoint to which substituents are added *@param nwanted number of points to calculate (1-4) *@param length from aPoint *@return Point3d[] nwanted points (or zero if failed) */ public Point3d[] calculate3DCoordinates0(Point3d aPoint, int nwanted, double length) { Point3d points[] = new Point3d[0]; if (nwanted == 1) { points = new Point3d[1]; points[0] = new Point3d(aPoint); points[0].add(new Vector3d(length, 0.0, 0.0)); } else if (nwanted == 2) { points[0] = new Point3d(aPoint); points[0].add(new Vector3d(length, 0.0, 0.0)); points[1] = new Point3d(aPoint); points[1].add(new Vector3d(-length, 0.0, 0.0)); } else if (nwanted == 3) { points[0] = new Point3d(aPoint); points[0].add(new Vector3d(length, 0.0, 0.0)); points[1] = new Point3d(aPoint); points[1].add(new Vector3d(-length * 0.5, -length * 0.5 * Math.sqrt(3.0), 0.0f)); points[2] = new Point3d(aPoint); points[2].add(new Vector3d(-length * 0.5, length * 0.5 * Math.sqrt(3.0), 0.0f)); } else if (nwanted == 4) { double dx = length / Math.sqrt(3.0); points[0] = new Point3d(aPoint); points[0].add(new Vector3d(dx, dx, dx)); points[1] = new Point3d(aPoint); points[1].add(new Vector3d(dx, -dx, -dx)); points[2] = new Point3d(aPoint); points[2].add(new Vector3d(-dx, -dx, dx)); points[3] = new Point3d(aPoint); points[3].add(new Vector3d(-dx, dx, -dx)); } return points; } /** * Calculate new point(s) X in a B-A system to form B-A-X. Use C as reference * for * staggering about the B-A bond (1a) 1 ligand(B) of refAtom (A) which * itself has a ligand (C) (i) 1 points required; vector along AB vector (ii) * 2 points: 2 vectors in ABC plane, staggered and eclipsed wrt C (iii) 3 * points: 1 staggered wrt C, the others +- gauche wrt C If C is null, a * random non-colinear C is generated * *@param aPoint to which substituents are added *@param nwanted number of points to calculate (1-3) *@param length A-X length *@param angle B-A-X angle *@param bPoint Description of the Parameter *@param cPoint Description of the Parameter *@return Point3d[] nwanted points (or zero if failed) */ public Point3d[] calculate3DCoordinates1( Point3d aPoint, Point3d bPoint, Point3d cPoint, int nwanted, double length, double angle ) { Point3d points[] = new Point3d[nwanted]; // BA vector Vector3d ba = new Vector3d(aPoint); ba.sub(bPoint); ba.normalize(); // if no cPoint, generate a random reference if (cPoint == null) { Vector3d cVector = getNonColinearVector(ba); cPoint = new Point3d(cVector); } // CB vector Vector3d cb = new Vector3d(bPoint); cb.sub(cPoint); cb.normalize(); // if A, B, C colinear, replace C by random point double cbdotba = cb.dot(ba); if (cbdotba > 0.999999) { Vector3d cVector = getNonColinearVector(ba); cPoint = new Point3d(cVector); cb = new Vector3d(bPoint); cb.sub(cPoint); } // cbxba = c x b Vector3d cbxba = new Vector3d(); cbxba.cross(cb, ba); cbxba.normalize(); // create three perp axes ba, cbxba, and ax Vector3d ax = new Vector3d(); ax.cross(cbxba, ba); ax.normalize(); double drot = Math.PI * 2.0 / (double) nwanted; for (int i = 0; i < nwanted; i++) { double rot = (double) i * drot; points[i] = new Point3d(aPoint); Vector3d vx = new Vector3d(ba); vx.scale(-Math.cos(angle) * length); Vector3d vy = new Vector3d(ax); vy.scale(Math.cos(rot) * length); Vector3d vz = new Vector3d(cbxba); vz.scale(Math.sin(rot) * length); points[i].add(vx); points[i].add(vy); points[i].add(vz); } /*ax = null; cbxba = null; ba = null; cb = null;*/ return points; } /** * Calculate new point(s) X in a B-A-C system, it forms a B-A(-C)-X * system. (2) 2 ligands(B, C) of refAtom A (i) 1 points required; vector in * ABC plane bisecting AB, AC. If ABC is linear, no points (ii) 2 points: 2 * points X1, X2, X1-A-X2 = angle about 2i vector * *@param aPoint to which substituents are added *@param bPoint first ligand of A *@param cPoint second ligand of A *@param nwanted number of points to calculate (1-2) *@param length A-X length *@param angle B-A-X angle *@return Point3d[] nwanted points (or zero if failed) */ public Point3d[] calculate3DCoordinates2( Point3d aPoint, Point3d bPoint, Point3d cPoint, int nwanted, double length, double angle) { //logger.debug("3DCoordinates2"); Point3d newPoints[] = new Point3d[0]; double ang2 = angle / 2.0; Vector3d ba = new Vector3d(aPoint); ba.sub(bPoint); Vector3d ca = new Vector3d(aPoint); ca.sub(cPoint); Vector3d baxca = new Vector3d(); baxca.cross(ba, ca); if (baxca.length() < 0.00000001) { ; // linear } else if (nwanted == 1) { newPoints = new Point3d[1]; Vector3d ax = new Vector3d(ba); ax.add(ca); ax.normalize(); ax.scale(length); newPoints[0] = new Point3d(aPoint); newPoints[0].add(ax); } else if (nwanted >= 2) { newPoints = new Point3d[2]; Vector3d ax = new Vector3d(ba); ax.add(ca); ax.normalize(); baxca.normalize(); baxca.scale(Math.sin(ang2) * length); ax.scale(Math.cos(ang2) * length); newPoints[0] = new Point3d(aPoint); newPoints[0].add(ax); newPoints[0].add(baxca); newPoints[1] = new Point3d(aPoint); newPoints[1].add(ax); newPoints[1].sub(baxca); } baxca = null; ba = null; ca = null; return newPoints; } /** * Calculate new point X in a B-A(-D)-C system. It forms a B-A(-D)(-C)-X * system. (3) 3 ligands(B, C, D) of refAtom A (i) 1 points required; if A, B, * C, D coplanar, no points. else vector is resultant of BA, CA, DA * *@param aPoint to which substituents are added *@param bPoint first ligand of A *@param cPoint second ligand of A *@param dPoint third ligand of A *@param length A-X length *@return Point3d nwanted points (or null if failed (coplanar)) */ public Point3d calculate3DCoordinates3( Point3d aPoint, Point3d bPoint, Point3d cPoint, Point3d dPoint, double length) { //logger.debug("3DCoordinates3"); Vector3d bc = new Vector3d(bPoint); bc.sub(cPoint); Vector3d dc = new Vector3d(dPoint); dc.sub(cPoint); Vector3d ca = new Vector3d(cPoint); ca.sub(aPoint); Vector3d n1 = new Vector3d(); Vector3d n2 = new Vector3d(); n1.cross(bc, dc); n1.normalize(); n1.scale(length); Vector3d ax = new Vector3d(aPoint); ax.add(n1); ax.sub(aPoint); Vector3d ax2 = new Vector3d(aPoint); ax2.add(n2); ax2.sub(aPoint); Point3d point = new Point3d(aPoint); double dotProduct = ca.dot(ax); double angle = Math.acos((dotProduct) / (ax.length() * ca.length())); if (angle < 1.5) { n2.cross(dc, bc); n2.normalize(); n2.scale(length); point.add(n2); } else { point.add(n1); } bc = null; dc = null; ca = null; n1 = null; n2 = null; return point; } /** * Calculate new point in B-A-C system. It forms B-A(-X)-C system, where A is * sp2 * *@param aPoint central point A (Point3d) *@param bPoint B (Point3d) *@param cPoint C (Point3d) *@param length bond length *@param angle angle between B(C)-A-X *@return new Point (Point3d) */ public Point3d calculate3DCoordinatesSP2_1(Point3d aPoint, Point3d bPoint, Point3d cPoint, double length, double angle) { //logger.debug("3DCoordinatesSP2_1"); Vector3d ba = new Vector3d(bPoint); ba.sub(aPoint); Vector3d ca = new Vector3d(cPoint); ca.sub(aPoint); Vector3d n1 = new Vector3d(); n1.cross(ba, ca); n1.normalize(); Vector3d n2 = rotate(ba, n1, angle); n2.normalize(); n2.scale(length); Point3d point = new Point3d(aPoint); point.add(n2); n1 = null; n2 = null; ba = null; ca = null; return point; } /** * Calculate two new points in B-A system. It forms B-A(-X)(-X) system, where
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -