📄 abstractcontroller2d.java
字号:
double bondLength; int pointerMarkX; int pointerMarkY; double ringRadius; double angle; double xDiff; double yDiff; double distance1 = 0; double distance2 = 0; IAtom firstAtom; IAtom secondAtom; IAtom spiroAtom; Point2d conAtomsCenter = null; Point2d newPoint1; Point2d newPoint2; RingPlacer ringPlacer = new RingPlacer(); int ringSize = c2dm.getRingSize(); String symbol = c2dm.getDrawElement(); IAtomContainer sharedAtoms = getHighlighted(); if (sharedAtoms.getAtomCount() == 0) { sharedAtoms = sharedAtoms.getBuilder().newAtomContainer(); newRing = sharedAtoms.getBuilder().newRing(ringSize, symbol); if (c2dm.getDrawMode() == Controller2DModel.BENZENERING) { // make newRing a benzene ring newRing.getBond(0).setOrder(2.0); newRing.getBond(2).setOrder(2.0); newRing.getBond(4).setOrder(2.0); makeRingAromatic(newRing); } bondLength = r2dm.getBondLength(); ringRadius = (bondLength / 2) / Math.sin(Math.PI / c2dm.getRingSize()); sharedAtomsCenter = new Point2d(mouseX, mouseY - ringRadius); firstAtom = newRing.getAtom(0); firstAtom.setPoint2d(sharedAtomsCenter); sharedAtoms.addAtom(firstAtom); ringCenterVector = new Vector2d(new Point2d(mouseX, mouseY)); ringCenterVector.sub(sharedAtomsCenter); ringPlacer.placeSpiroRing(newRing, sharedAtoms, sharedAtomsCenter, ringCenterVector, bondLength); IAtomContainer atomCon = ChemModelManipulator.createNewMolecule(chemModel); atomCon.add(newRing); undoRedoContainer.add(newRing); } else if (sharedAtoms.getAtomCount() == 1) { spiroAtom = sharedAtoms.getAtom(0); sharedAtomsCenter = GeometryTools.get2DCenter(sharedAtoms,r2dm.getRenderingCoordinates()); newRing = createAttachRing(sharedAtoms, ringSize, symbol); if (c2dm.getDrawMode() == Controller2DModel.BENZENERING) { // make newRing a benzene ring newRing.getBond(0).setOrder(2.0); newRing.getBond(2).setOrder(2.0); newRing.getBond(4).setOrder(2.0); makeRingAromatic(newRing); } bondLength = r2dm.getBondLength(); conAtomsCenter = getConnectedAtomsCenter(sharedAtoms); if (conAtomsCenter.equals(((Point2d)r2dm.getRenderingCoordinate(spiroAtom)))) { ringCenterVector = new Vector2d(0, 1); } else { ringCenterVector = new Vector2d(sharedAtomsCenter); ringCenterVector.sub(conAtomsCenter); } ringPlacer.placeSpiroRing(newRing, sharedAtoms, sharedAtomsCenter, ringCenterVector, bondLength); // removes the highlighed atom from the ring to add only the new placed // atoms to the AtomContainer. try { newRing.removeAtom(spiroAtom); } catch (Exception exc) { logger.error("Could not remove atom from ring"); logger.debug(exc); } IAtomContainer atomCon = ChemModelManipulator.getRelevantAtomContainer(chemModel, spiroAtom); atomCon.add(newRing); undoRedoContainer.add(newRing); } else if (sharedAtoms.getAtomCount() == 2) { sharedAtomsCenter = GeometryTools.get2DCenter(sharedAtoms,r2dm.getRenderingCoordinates()); // calculate two points that are perpendicular to the highlighted bond // and have a certain distance from the bondcenter firstAtom = sharedAtoms.getAtom(0); secondAtom = sharedAtoms.getAtom(1); xDiff = ((Point2d)r2dm.getRenderingCoordinate(secondAtom)).x - ((Point2d)r2dm.getRenderingCoordinate(firstAtom)).x; yDiff = ((Point2d)r2dm.getRenderingCoordinate(secondAtom)).y - ((Point2d)r2dm.getRenderingCoordinate(firstAtom)).y; bondLength = Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2)); angle = GeometryTools.getAngle(xDiff, yDiff); newPoint1 = new Point2d((Math.cos(angle + (Math.PI / 2)) * bondLength / 4) + sharedAtomsCenter.x, (Math.sin(angle + (Math.PI / 2)) * bondLength / 4) + sharedAtomsCenter.y); newPoint2 = new Point2d((Math.cos(angle - (Math.PI / 2)) * bondLength / 4) + sharedAtomsCenter.x, (Math.sin(angle - (Math.PI / 2)) * bondLength / 4) + sharedAtomsCenter.y); if (wasDragged) { // check which one of the two points is nearest to the endpoint of the pointer // vector that was dragged to make the ringCenterVector point into the right direction. pointerMarkX = r2dm.getPointerVectorEnd().x; pointerMarkY = r2dm.getPointerVectorEnd().y; distance1 = -1 * (Math.sqrt(Math.pow(newPoint1.x - pointerMarkX, 2) + Math.pow(newPoint1.y - pointerMarkY, 2))); distance2 = -1 * (Math.sqrt(Math.pow(newPoint2.x - pointerMarkX, 2) + Math.pow(newPoint2.y - pointerMarkY, 2))); r2dm.setPointerVectorStart(null); r2dm.setPointerVectorEnd(null); } else { // check which one of the two points is nearest to the center of the // connected atoms to make the ringCenterVector point into the right direction. conAtomsCenter = getConnectedAtomsCenter(sharedAtoms); distance1 = Math.sqrt(Math.pow(newPoint1.x - conAtomsCenter.x, 2) + Math.pow(newPoint1.y - conAtomsCenter.y, 2)); distance2 = Math.sqrt(Math.pow(newPoint2.x - conAtomsCenter.x, 2) + Math.pow(newPoint2.y - conAtomsCenter.y, 2)); } ringCenterVector = new Vector2d(sharedAtomsCenter); // no ring is attached if the two ditances are equal //shk3: I removed this condition since it leads to npe and I cannot see why it is necessary. //the npe is if you draw a single bond and want to attach a ring to it. Now the ring is in an arbitrary direction, but this is ok /*if (distance1 == distance2) { logger.warn("don't know where to draw the new Ring"); } else*/ { if (distance1 < distance2) { ringCenterVector.sub(newPoint1); } else if (distance2 < distance1) { ringCenterVector.sub(newPoint2); } else{ ringCenterVector.sub(newPoint2); } IAtomContainer atomCon = ChemModelManipulator.getRelevantAtomContainer(chemModel, firstAtom); // construct a new Ring that contains the highlighted bond an its two atoms newRing = createAttachRing(sharedAtoms, ringSize, symbol); if (c2dm.getDrawMode() == Controller2DModel.BENZENERING) { // make newRing a benzene ring IBond existingBond = atomCon.getBond(firstAtom, secondAtom); if (existingBond.getOrder() == 1.0) { if (existingBond.getFlag(CDKConstants.ISAROMATIC)) { newRing.getBond(2).setOrder(2.0); newRing.getBond(4).setOrder(2.0); } else { newRing.getBond(1).setOrder(2.0); newRing.getBond(3).setOrder(2.0); newRing.getBond(5).setOrder(2.0); } } else { newRing.getBond(2).setOrder(2.0); newRing.getBond(4).setOrder(2.0); } makeRingAromatic(newRing); } // place the new atoms of the new ring to the right position ringPlacer.placeFusedRing(newRing, sharedAtoms, sharedAtomsCenter, ringCenterVector, bondLength); // removes the highlighed bond and its atoms from the ring to add only // the new placed atoms to the AtomContainer. try { newRing.remove(sharedAtoms); } catch (Exception exc) { logger.error("Could not remove atom from ring"); logger.debug(exc); } atomCon.add(newRing); } } double highlightRadius = r2dm.getHighlightRadius(); for (int i = 0; i < newRing.getAtomCount(); i++) { IAtom atom=newRing.getAtom(i); r2dm.setRenderingCoordinate(atom,new Point2d(atom.getPoint2d())); } for (int i = 0; i < newRing.getAtomCount(); i++) { IAtom atom=newRing.getAtom(i); r2dm.setRenderingCoordinate(atom,new Point2d(atom.getPoint2d())); centerAtom(atom,chemModel); //We make sure atoms don't overlap //Solution is a bit crude, we would need to find an unoccupied place (and even the bond display should be optimized) IAtom inrange=getAtomInRange((int)((Point2d)r2dm.getRenderingCoordinate(atom)).x, (int)((Point2d)r2dm.getRenderingCoordinate(atom)).y, atom); if(inrange!=null && Math.sqrt(Math.pow(((Point2d)r2dm.getRenderingCoordinate(inrange)).x - ((Point2d)r2dm.getRenderingCoordinate(atom)).x, 2) + Math.pow(((Point2d)r2dm.getRenderingCoordinate(inrange)).y - ((Point2d)r2dm.getRenderingCoordinate(atom)).y, 2)) < highlightRadius/4){ ((Point2d)r2dm.getRenderingCoordinate(atom)).x-=highlightRadius/4; ((Point2d)r2dm.getRenderingCoordinate(atom)).y-=highlightRadius/4; } } this.updateMoleculeCoordinates(); this.updateAtoms(ChemModelManipulator.getRelevantAtomContainer(chemModel, newRing.getAtom(0)), sharedAtoms.atoms()); this.updateAtoms(ChemModelManipulator.getRelevantAtomContainer(chemModel, newRing.getAtom(0)), newRing.atoms()); undoRedoContainer.add(newRing); UndoableEdit edit = new AddAtomsAndBondsEdit(chemModel, undoRedoContainer, "Added Ring",c2dm); undoRedoHandler.postEdit(edit); r2dm.fireChange(); fireChange(); } private void eraseSelection() { IAtomContainer undoRedoContainer = chemModel.getBuilder().newAtomContainer(); String type = null; IAtom highlightedAtom = r2dm.getHighlightedAtom(); IBond highlightedBond = r2dm.getHighlightedBond(); if (highlightedAtom != null && (r2dm.getSelectedPart()==null || !r2dm.getSelectedPart().contains(highlightedAtom))) { logger.info("User asks to delete an Atom"); IAtomContainer container = ChemModelManipulator.getRelevantAtomContainer(chemModel, highlightedAtom); IElectronContainer[] eContainer = AtomContainerManipulator.getElectronContainerArray(container.getConnectedElectronContainersList(highlightedAtom)); for (int i=0; i<eContainer.length; i++) { undoRedoContainer.addBond((IBond) eContainer[i]); } logger.debug("Atoms before delete: ", container.getAtomCount()); Iterator atoms = container.getConnectedAtomsList(highlightedAtom).iterator(); ChemModelManipulator.removeAtomAndConnectedElectronContainers(chemModel, highlightedAtom); updateAtoms(container, atoms); undoRedoContainer.addAtom(highlightedAtom); if (type == null) { type = "Remove Atom"; } else { type = "Remove Substructure"; } logger.debug("Atoms before delete: ", container.getAtomCount()); } else if (highlightedBond != null && (r2dm.getSelectedPart()==null || !r2dm.getSelectedPart().contains(highlightedBond))){ logger.info("User asks to delete a Bond"); ChemModelManipulator.removeElectronContainer(chemModel, highlightedBond); undoRedoContainer.addBond(highlightedBond); if (type == null) { type = "Remove Bond"; } else { type = "Remove Substructure"; } // update atoms java.util.Iterator atoms = highlightedBond.atoms(); IAtomContainer container = ChemModelManipulator.getRelevantAtomContainer(chemModel, highlightedBond.getAtom(0)); updateAtoms(container, atoms); } else if(r2dm.getSelectedPart()!=null && (r2dm.getSelectedPart().getAtomCount()>0 || r2dm.getSelectedPart().getBondCount()>0)){ logger.info("User asks to delete selected part"); IAtomContainer containerToUpdate = ChemModelManipulator.getRelevantAtomContainer(chemModel, r2dm.getSelectedPart().getAtom(0)); for(int i=0;i<r2dm.getSelectedPart().getAtomCount();i++){ undoRedoContainer.addAtom(r2dm.getSelectedPart().getAtom(i)); for(int k=0;k<ChemModelManipulator.getRelevantAtomContainer(chemModel,r2dm.getSelectedPart().getAtom(i)).getConnectedBondsCount(r2dm.getSelectedPart().getAtom(i));k++){ undoRedoContainer.addBond((IBond)ChemModelManipulator.getRelevantAtomContainer(chemModel,r2dm.getSelectedPart().getAtom(i)).getConnectedBondsList(r2dm.getSelectedPart().getAtom(i)).get(k)); } ChemModelManipulator.removeAtomAndConnectedElectronContainers(chemModel,r2dm.getSelectedPart().getAtom(i)); } type = "Remove Substructure"; // update atoms updateAtoms(containerToUpdate, containerToUpdate.atoms()); }else{ logger.warn("Cannot deleted if nothing is highlighted"); return; } /* * PRESERVE THIS. This notifies the * the listener responsible for * undo and redo storage that it * should store this change of an atom symbol */ isUndoableChange = true; /* * --- */ UndoableEdit edit = new RemoveAtomsAndBondsEdit(chemModel, undoRedoContainer, type); undoRedoHandler.postEdit(edit); r2dm.fireChange(); fireChange(); } private void drawBond(int mouseX, int mouseY) { this.updateMoleculeCoordinates(); logger.debug("mouseReleased->drawbond"); IAtom atomInRange; IAtom newAtom1 = null; IAtom newAtom2 = null; IBond newBond = null; int startX = r2dm.getPointerVectorStart().x; int startY = r2dm.getPointerVectorStart().y; IBond bondInRange = r2dm.getHighlightedBond(); //atomInRange = r2dm.getHighlightedAtom(); //Bond bondInRange = getBondInRange(mouseX, mouseY); /* * IMPORTANT: I don't use getHighlighteAtom() * here because of the special case of * only one atom on the screen. * In this case, this atom will not detected * if the mouse hasn't moved after it's creation */ atomInRange = getAtomInRange(mouseX, mouseY); if (bondInRange != null) {// update atoms IAtomContainer container = ChemModelManipulator.getRelevantAtomContainer(chemModel, bondInRange.getAtom(0)); updateAtoms(container, bondInRange.atoms()); HashMap changedBonds = new HashMap(); double formerBondOrder = bondInRange.getOrder(); if (c2dm.getDrawMode() == Controller2DModel.DRAWBOND){ if(bondInRange.getStereo()!=CDKConstants.STEREO_BOND_NONE){ bondInRange.setStereo(CDKConstants.STEREO_BOND_NONE); }else{ // increase Bond order double order = bondInRange.getOrder(); if (order >= CDKConstants.BONDORDER_TRIPLE) { bondInRange.setOrder(CDKConstants.BONDORDER_SINGLE); } else { bondInRange.setOrder(order + 1.0); // this is tricky as it depends on the fact that the // constants are unidistant, i.e. {1.0, 2.0, 3.0}. } } }else if(c2dm.getDrawMode() == Controller2DModel.DOWN_BOND){ // toggle bond stereo double stereo = bondInRange.getStereo(); if (stereo == CDKConstants.STEREO_BOND_DOWN) { bondInRange.setStereo(CDKConstants.STEREO_BOND_DOWN_INV); } else if (stereo == CDKConstants.STEREO_BOND_DOWN_INV) { bondInRange.setStereo(CDKConstants.STEREO_BOND_NONE); } else { bondInRange.setStereo(CDKConstants.STEREO_BOND_DOWN); } bondInRange.setOrder(1); }else{ // toggle bond stereo double stereo = bondInRange.getStereo(); if (stereo == CDKConstants.STEREO_BOND_UP) { bondInRange.setStereo(CDKConstants.STEREO_BOND_UP_INV); } else if (stereo == CDKConstants.STEREO_BOND_UP_INV) { bondInRange.setStereo(CDKConstants.STEREO_BOND_NONE); } else { bondInRange.setStereo(CDKConstants.STEREO_BOND_UP); } bondInRange.setOrder(1); } /* * PRESERVE THIS. This notifies the * the listener responsible for * undo and redo storage that it * should store this change of an atom symbol */ if (bondInRange.getOrder() != formerBondOrder) { double[] bondOrders = new double[2]; bondOrders[0] = bondInRange.getOrder(); bondOrders[1] = formerBondOrder; changedBonds.put(bondInRange, bondOrders); } isUndoableChange = true; /* * ---
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -