Skip to content

Commit 57c008b

Browse files
committed
Nicely handle spiro rings in higher order molecular geometries when there is a configuration specified.
1 parent 0ac85ff commit 57c008b

File tree

2 files changed

+371
-71
lines changed

2 files changed

+371
-71
lines changed

base/standard/src/main/java/org/openscience/cdk/geometry/GeometryUtil.java

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import java.io.IOException;
4848
import java.util.ArrayList;
4949
import java.util.Arrays;
50+
import java.util.Collection;
5051
import java.util.Iterator;
5152
import java.util.List;
5253
import java.util.Map;
@@ -254,6 +255,39 @@ public static void rotate(IAtomContainer atomCon, Point2d center, double angle)
254255
}
255256
}
256257

258+
/**
259+
* Reflect a collection of atoms in the line formed by the two specified points (beg,end).
260+
*
261+
* @param atoms the atoms
262+
* @param beg the begin point of a line
263+
* @param end the end point of a line
264+
*/
265+
public static void reflect(Collection<IAtom> atoms, Point2d beg, Point2d end) {
266+
double dx = end.x - beg.x;
267+
double dy = end.y - beg.y;
268+
269+
double a = (dx * dx - dy * dy) / (dx * dx + dy * dy);
270+
double b = 2 * dx * dy / (dx * dx + dy * dy);
271+
for (IAtom atom : atoms) {
272+
Point2d p = atom.getPoint2d();
273+
double x = a * (p.x - beg.x) + b * (p.y - beg.y) + beg.x;
274+
double y = b * (p.x - beg.x) - a * (p.y - beg.y) + beg.y;
275+
p.x = x;
276+
p.y = y;
277+
}
278+
}
279+
280+
/**
281+
* Reflect a collection of atoms in the line formed by the specified bond.
282+
*
283+
* @param atoms the atoms
284+
* @param bond the bond at which to reflect
285+
*/
286+
public static void reflect(Collection<IAtom> atoms, IBond bond) {
287+
reflect(atoms, bond.getBegin().getPoint2d(), bond.getEnd().getPoint2d());
288+
}
289+
290+
257291
/**
258292
* Rotates a 3D point about a specified line segment by a specified angle.
259293
*
@@ -1683,22 +1717,30 @@ public static double getBondLengthAverage(IReaction reaction) {
16831717
* @throws java.lang.IllegalArgumentException unset coordinates or no bonds
16841718
*/
16851719
public static double getBondLengthMedian(final IAtomContainer container) {
1686-
if (container.getBondCount() == 0) throw new IllegalArgumentException("Container has no bonds.");
1687-
int nBonds = 0;
1688-
double[] lengths = new double[container.getBondCount()];
1689-
for (int i = 0; i < container.getBondCount(); i++) {
1690-
final IBond bond = container.getBond(i);
1720+
return getBondLengthMedian(container.bonds(), container.getBondCount());
1721+
}
1722+
1723+
public static double getBondLengthMedian(final Iterable<IBond> bonds, int cap) {
1724+
Iterator<IBond> iter = bonds.iterator();
1725+
if (!iter.hasNext()) throw new IllegalArgumentException("No bonds");
1726+
int count = 0;
1727+
double[] lengths = new double[cap];
1728+
while (iter.hasNext()) {
1729+
final IBond bond = iter.next();
16911730
final IAtom atom1 = bond.getBegin();
16921731
final IAtom atom2 = bond.getEnd();
16931732
Point2d p1 = atom1.getPoint2d();
16941733
Point2d p2 = atom2.getPoint2d();
16951734
if (p1 == null || p2 == null)
16961735
throw new IllegalArgumentException("An atom has no 2D coordinates.");
1697-
if (p1.x != p2.x || p1.y != p2.y)
1698-
lengths[nBonds++] = p1.distance(p2);
1736+
if (p1.x != p2.x || p1.y != p2.y) {
1737+
if (count == lengths.length)
1738+
lengths = Arrays.copyOf(lengths, count);
1739+
lengths[count++] = p1.distance(p2);
1740+
}
16991741
}
1700-
Arrays.sort(lengths, 0, nBonds);
1701-
return lengths[nBonds / 2];
1742+
Arrays.sort(lengths, 0, count);
1743+
return lengths[count / 2];
17021744
}
17031745

17041746
/**

0 commit comments

Comments
 (0)