//first, we get rid of the phantom arrow
chemModelRelay.setPhantomArrow(null, null);
chemModelRelay.updateView();
//for each molecule, we need to look if the majority of
// its atoms are to the left or right or on the arrow
IAtomContainerSet moleculeSet = super.chemModelRelay.getChemModel().getMoleculeSet();
if (moleculeSet.getAtomContainerCount() == 0 || (moleculeSet.getAtomContainerCount() == 1 && moleculeSet.getAtomContainer(0).getAtomCount() == 0)) {
return;
}
final Vector2d unit = newUnitVector(startPoint, endPoint);
final Vector2d perp = new Vector2d(unit.y, -unit.x);
List<IAtomContainer> reactants = new ArrayList<IAtomContainer>(2);
List<IAtomContainer> products = new ArrayList<IAtomContainer>(2);
// determine the reactants and products of a reaction we do this by
// taking the perpendicular vector and testing where atoms lie with
// respect to the start and end of the arrow. The following diagram
// may help visualise what the startPos and endPos values are.
//
// startPos < 0 startPos > 0
// endPost < 0 endPost > 0
// ^ ^
// | |
// --------------------->
//
for (IAtomContainer container : moleculeSet.atomContainers()) {
// count the number of atoms before and after the arrow for this molecule
int beforeStart = 0;
int afterEnd = 0;
for (final IAtom atom : container.atoms()){
final Point2d p = atom.getPoint2d();
// sign( (Bx-Ax)*(Y-Ay) - (By-Ay)*(X-Ax) )
final double endPos = (perp.x) * (p.y - endPoint.y) - (perp.y) * (p.x - endPoint.x);
final double startPos = (perp.x) * (p.y - startPoint.y) - (perp.y) * (p.x - startPoint.x);
if (endPos > 0)
afterEnd++;
if (startPos < 0)
beforeStart++;
}
if (beforeStart > afterEnd) {
reactants.add(container);
}
else if (beforeStart < afterEnd) {
products.add(container);
} else {
//TODO catalysts in general
}
}
// don't create a new reaction
if (reactants.isEmpty() && products.isEmpty())
return;
// do reaction creation
IReactionSet reactionSet = super.chemModelRelay.getChemModel().getReactionSet();
if (reactionSet == null) {
reactionSet = new ReactionChain(); //reactionSet = super.chemModelRelay.getChemModel().getBuilder().newInstance(IReactionSet.class);
super.chemModelRelay.getChemModel().setReactionSet(reactionSet);
}
IReaction reaction = moleculeSet.getBuilder().newInstance(IReaction.class);
((ReactionChain) reactionSet).addReaction(reaction, reactionSet.getReactionCount()); //reactionSet.addReaction(reaction);
reaction.setID(ReactionHub.newReactionId(chemModelRelay));
for (IAtomContainer reactant : reactants) {
ReactionHub.makeReactantInExistingReaction((ControllerHub) super.chemModelRelay,