|
47 | 47 | import java.io.IOException; |
48 | 48 | import java.util.ArrayList; |
49 | 49 | import java.util.Arrays; |
| 50 | +import java.util.Collection; |
50 | 51 | import java.util.Iterator; |
51 | 52 | import java.util.List; |
52 | 53 | import java.util.Map; |
@@ -254,6 +255,39 @@ public static void rotate(IAtomContainer atomCon, Point2d center, double angle) |
254 | 255 | } |
255 | 256 | } |
256 | 257 |
|
| 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 | + |
257 | 291 | /** |
258 | 292 | * Rotates a 3D point about a specified line segment by a specified angle. |
259 | 293 | * |
@@ -1683,22 +1717,30 @@ public static double getBondLengthAverage(IReaction reaction) { |
1683 | 1717 | * @throws java.lang.IllegalArgumentException unset coordinates or no bonds |
1684 | 1718 | */ |
1685 | 1719 | 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(); |
1691 | 1730 | final IAtom atom1 = bond.getBegin(); |
1692 | 1731 | final IAtom atom2 = bond.getEnd(); |
1693 | 1732 | Point2d p1 = atom1.getPoint2d(); |
1694 | 1733 | Point2d p2 = atom2.getPoint2d(); |
1695 | 1734 | if (p1 == null || p2 == null) |
1696 | 1735 | 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 | + } |
1699 | 1741 | } |
1700 | | - Arrays.sort(lengths, 0, nBonds); |
1701 | | - return lengths[nBonds / 2]; |
| 1742 | + Arrays.sort(lengths, 0, count); |
| 1743 | + return lengths[count / 2]; |
1702 | 1744 | } |
1703 | 1745 |
|
1704 | 1746 | /** |
|
0 commit comments