I already explained, you can have "spirodegree > 2" (i.e. degree > 4) in
which case it lays things out on top of each other (incorrect). The num
place two "nudge" is to make the bond lengths longer.

Try commenting out the if conditions and use the SMILES I gave last time to
see the effect:

C1CO[Fe]234(O1)OCCO2.C(CO3)O4



On Sat, 30 Nov 2019 at 09:30, 努力努力 <843982...@qq.com> wrote:

> Why do we have special treatment when degree==4 and numplace==2?
> In my understanding, "degree" is the number of bonds connected to
> sharedAtoms, and numPlaced is the number of other Atoms ring except
> sharedAtoms.
> Looking forward to your reply. Thank you!
>
> The source code from CDK is here:
> public void placeSpiroRing(IRing ring, IAtomContainer sharedAtoms, Point2d
> sharedAtomsCenter, Vector2d ringCenterVector, double bondLength) {
>
>         IAtom startAtom = sharedAtoms.getAtom(0);
>         List<IBond> mBonds =
> molecule.getConnectedBondsList(sharedAtoms.getAtom(0));
>         final int degree = mBonds.size();
>         logger.debug("placeSpiroRing: D=", degree);
>
>         // recalculate the ringCentreVector
>         if (degree != 4) {
>
>             int numPlaced = 0;
>             for (IBond bond : mBonds) {
>                 IAtom nbr = bond.getOther(sharedAtoms.getAtom(0));
>                 if (!nbr.getFlag(CDKConstants.ISPLACED))
>                     continue;
>                 numPlaced++;
>             }
>
>             if (numPlaced == 2) {
>                 // nudge the shared atom such that bond lengths will be
>                 // equal
>                 startAtom.getPoint2d().add(ringCenterVector);
>                 sharedAtomsCenter.add(ringCenterVector);
>             }
>
>             double theta = Math.PI-(2 * Math.PI / (degree / 2));
>             rotate(ringCenterVector, theta);
>         }
>
>         double radius = getNativeRingRadius(ring, bondLength);
>         Point2d ringCenter = new Point2d(sharedAtomsCenter);
>         if (degree == 4) {
>             ringCenterVector.normalize();
>             ringCenterVector.scale(radius);
>         } else {
>             // spread things out a little for multiple spiro centres
>             ringCenterVector.normalize();
>             ringCenterVector.scale(2*radius);
>         }
>         ringCenter.add(ringCenterVector);
>         double addAngle = 2 * Math.PI / ring.getRingSize();
>
>         IAtom currentAtom = startAtom;
>         double startAngle = GeometryUtil.getAngle(startAtom.getPoint2d().x
> - ringCenter.x,
>                                                   startAtom.getPoint2d().y
> - ringCenter.y);
>
>         /*
>          * Get one bond connected to the spiro bridge atom. It doesn't
> matter in
>          * which direction we draw.
>          */
>         List rBonds = ring.getConnectedBondsList(startAtom);
>
>         IBond currentBond = (IBond) rBonds.get(0);
>
>         Vector atomsToDraw = new Vector();
>         /*
>          * Store all atoms to draw in consequtive order relative to the
> chosen
>          * bond.
>          */
>         for (int i = 0; i < ring.getBondCount(); i++) {
>             currentBond = ring.getNextBond(currentBond, currentAtom);
>             currentAtom = currentBond.getOther(currentAtom);
>             if (!currentAtom.equals(startAtom))
>                 atomsToDraw.addElement(currentAtom);
>         }
>         logger.debug("currentAtom  " + currentAtom);
>         logger.debug("startAtom  " + startAtom);
>
>         atomPlacer.populatePolygonCorners(atomsToDraw, ringCenter,
> startAngle, addAngle, radius);
>
>     }
> _______________________________________________
> Cdk-user mailing list
> Cdk-user@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/cdk-user
>
_______________________________________________
Cdk-user mailing list
Cdk-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/cdk-user

Reply via email to