Skip to content

Commit 58edb81

Browse files
committed
Aromatic donuts.
1 parent 05b5a6b commit 58edb81

File tree

2 files changed

+59
-12
lines changed

2 files changed

+59
-12
lines changed

display/renderbasic/src/main/java/org/openscience/cdk/renderer/generators/standard/StandardBondGenerator.java

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import com.google.common.primitives.Ints;
2929
import org.openscience.cdk.config.Elements;
30+
import org.openscience.cdk.geometry.GeometryUtil;
3031
import org.openscience.cdk.graph.Cycles;
3132
import org.openscience.cdk.interfaces.IAtom;
3233
import org.openscience.cdk.interfaces.IAtomContainer;
@@ -55,13 +56,16 @@
5556
import javax.vecmath.Vector2d;
5657
import java.awt.Color;
5758
import java.awt.Font;
59+
import java.awt.Shape;
5860
import java.util.ArrayList;
5961
import java.util.Arrays;
6062
import java.util.Collections;
6163
import java.util.Comparator;
6264
import java.util.HashMap;
65+
import java.util.HashSet;
6366
import java.util.List;
6467
import java.util.Map;
68+
import java.util.Set;
6569

6670
import static org.openscience.cdk.interfaces.IBond.Order.SINGLE;
6771
import static org.openscience.cdk.interfaces.IBond.Order.UNSET;
@@ -112,6 +116,7 @@ final class StandardBondGenerator {
112116
private final Color foreground, annotationColor;
113117
private final boolean fancyBoldWedges, fancyHashedWedges;
114118
private final double annotationDistance, annotationScale;
119+
private final boolean aromaticDonuts = true;
115120
private final Font font;
116121
private final ElementGroup annotations;
117122
private final boolean forceDelocalised;
@@ -182,9 +187,37 @@ static IRenderingElement[] generateBonds(IAtomContainer container, AtomSymbol[]
182187
elements[i] = bondGenerator.generate(bond);
183188
}
184189
}
190+
if (bondGenerator.aromaticDonuts) {
191+
IRenderingElement donuts = bondGenerator.generateDonuts();
192+
if (donuts != null) {
193+
elements = Arrays.copyOf(elements, elements.length + 1);
194+
elements[elements.length-1] = donuts;
195+
}
196+
}
185197
return elements;
186198
}
187199

200+
IRenderingElement generateDonuts() {
201+
ElementGroup group = new ElementGroup();
202+
Set<IAtomContainer> rings = new HashSet<>(ringMap.values());
203+
for (IAtomContainer ring : rings) {
204+
if (ring.getBondCount() <= 8) {
205+
Point2d p2 = GeometryUtil.get2DCenter(ring);
206+
if (ring.getBondCount() == 5) {
207+
TextOutline to = new TextOutline("–", font).resize(1/scale, -1/scale);
208+
to = to.translate(p2.x-to.getCenter().getX(),
209+
p2.y-to.getCenter().getY());
210+
// group.add(GeneralPath.shapeOf(to.getOutline(), foreground));
211+
}
212+
double s = GeometryUtil.getBondLengthMedian(ring);
213+
double n = ring.getBondCount();
214+
double r = s / (2*Math.tan(Math.PI/n));
215+
// group.add(new OvalElement(p2.x, p2.y, r-separation, false, foreground));
216+
}
217+
}
218+
return group;
219+
}
220+
188221
/**
189222
* Generate a rendering element for a given bond.
190223
*
@@ -203,14 +236,23 @@ IRenderingElement generate(IBond bond) {
203236

204237
switch (order) {
205238
case SINGLE:
206-
if (bond.isAromatic() && forceDelocalised)
207-
elem = generateDoubleBond(bond, true);
208-
else
239+
// TODO check small ring!
240+
if (bond.isAromatic()) {
241+
if (forceDelocalised && !aromaticDonuts) {
242+
elem = generateDoubleBond(bond, true);
243+
} else
244+
elem = generateSingleBond(bond, atom1, atom2);
245+
} else
209246
elem = generateSingleBond(bond, atom1, atom2);
210247
break;
211248
case DOUBLE:
212-
elem = generateDoubleBond(bond,
213-
bond.isAromatic() && forceDelocalised);
249+
if (bond.isAromatic()) {
250+
if (forceDelocalised && aromaticDonuts)
251+
elem = generateSingleBond(bond, atom1, atom2);
252+
else
253+
elem = generateDoubleBond(bond, forceDelocalised);
254+
} else
255+
elem = generateDoubleBond(bond, false);
214256
break;
215257
case TRIPLE:
216258
elem = generateTripleBond(bond, atom1, atom2);
@@ -608,10 +650,10 @@ IRenderingElement generateWavyBond(final IAtom from, final IAtom to) {
608650
* Generates a double bond rendering element by deciding how best to display it.
609651
*
610652
* @param bond the bond to render
611-
* @param dashed the second line should be dashed
653+
* @param arom the second line should be dashed
612654
* @return rendering element
613655
*/
614-
private IRenderingElement generateDoubleBond(IBond bond, boolean dashed) {
656+
private IRenderingElement generateDoubleBond(IBond bond, boolean arom) {
615657

616658
final boolean cyclic = ringMap.containsKey(bond);
617659

@@ -643,9 +685,9 @@ private IRenderingElement generateDoubleBond(IBond bond, boolean dashed) {
643685
final int wind1 = winding(atom1Bonds.get(0), bond);
644686
final int wind2 = winding(bond, atom2Bonds.get(0));
645687
if (wind1 > 0) {
646-
return generateOffsetDoubleBond(bond, atom1, atom2, atom1Bonds.get(0), atom2Bonds, dashed);
688+
return generateOffsetDoubleBond(bond, atom1, atom2, atom1Bonds.get(0), atom2Bonds, arom);
647689
} else if (wind2 > 0) {
648-
return generateOffsetDoubleBond(bond, atom2, atom1, atom2Bonds.get(0), atom1Bonds, dashed);
690+
return generateOffsetDoubleBond(bond, atom2, atom1, atom2Bonds.get(0), atom1Bonds, arom);
649691
} else {
650692
// special case, offset line is drawn on the opposite side for
651693
// when concave in macro cycle
@@ -654,7 +696,7 @@ private IRenderingElement generateDoubleBond(IBond bond, boolean dashed) {
654696
// a --- b
655697
// / \
656698
// -- x x --
657-
return generateOffsetDoubleBond(bond, atom1, atom2, atom1Bonds.get(0), atom2Bonds, true, dashed);
699+
return generateOffsetDoubleBond(bond, atom1, atom2, atom1Bonds.get(0), atom2Bonds, true, arom);
658700
}
659701
} else if (!(hasDisplayedSymbol(atom1) && hasDisplayedSymbol(atom2))) {
660702
if (atom1Bonds.size() == 1 && atom2Bonds.isEmpty())
@@ -672,7 +714,7 @@ else if (atom2Bonds.size() == 1)
672714
else
673715
return generateCenteredDoubleBond(bond, atom1, atom2, atom1Bonds, atom2Bonds);
674716
} else {
675-
if (dashed) {
717+
if (arom) {
676718
return generateDashedBond(atom1, atom2);
677719
} else {
678720
return generateCenteredDoubleBond(bond, atom1, atom2, atom1Bonds, atom2Bonds);
@@ -1561,7 +1603,7 @@ static int winding(IBond bond1, IBond bond2) {
15611603
*/
15621604
static Map<IBond, IAtomContainer> ringPreferenceMap(IAtomContainer container) {
15631605

1564-
final IRingSet relevantRings = Cycles.sssr(container).toRingSet();
1606+
final IRingSet relevantRings = Cycles.edgeShort(container).toRingSet();
15651607
final List<IAtomContainer> rings = AtomContainerSetManipulator.getAllAtomContainers(relevantRings);
15661608

15671609
Collections.sort(rings, new RingBondOffsetComparator());

display/renderbasic/src/main/java/org/openscience/cdk/renderer/generators/standard/StandardGenerator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ public IRenderingElement generate(IAtomContainer container, RendererModel parame
241241
}
242242
}
243243

244+
// donuts for delocalised aromatic
245+
if (bondElements.length > container.getBondCount()) {
246+
frontLayer.add(bondElements[bondElements.length - 1]);
247+
}
248+
244249
// convert the atom symbols to IRenderingElements
245250
for (int i = 0; i < container.getAtomCount(); i++) {
246251
IAtom atom = container.getAtom(i);

0 commit comments

Comments
 (0)