Logo Search packages:      
Sourcecode: cdk version File versions  Download package

void org::openscience::cdk::layout::AtomPlacer::distributePartners ( IAtom  atom,
IAtomContainer  placedNeighbours,
Point2d  sharedAtomsCenter,
IAtomContainer  unplacedNeighbours,
double  bondLength,
HashMap  renderingCoordinates 
) [inline]

Distribute the bonded atoms (neighbours) of an atom such that they fill the remaining space around an atom in a geometrically nice way. IMPORTANT: This method is not supposed to handle the case of one or no place neighbor. In the case of one placed neigbor, the chain placement methods should be used.

Parameters:
atom The atom whose partners are to be placed
placedNeighbours The atoms which are already placed
unplacedNeighbours The partners to be placed
bondLength The standared bond length for the newly placed Atoms
sharedAtomsCenter The 2D centre of the placed Atoms

Definition at line 165 of file AtomPlacer.java.

References org::openscience::cdk::tools::LoggingTool::debug(), org::openscience::cdk::interfaces::IAtomContainer::getAtom(), org::openscience::cdk::interfaces::IAtomContainer::getAtomCount(), org::openscience::cdk::interfaces::IAtomContainer::getAtomNumber(), org::openscience::cdk::interfaces::IAtom::getPoint2d(), molecule, and populatePolygonCorners().

    {
        double occupiedAngle = 0;
        //double smallestDistance = Double.MAX_VALUE;
        //IAtom[] nearestAtoms = new IAtom[2];
        IAtom[] sortedAtoms = null;
        double startAngle = 0.0;
        double addAngle = 0.0;
        double radius = 0.0;
        double remainingAngle = 0.0;
        /*
         *  calculate the direction away from the already placed partners of atom
         */
        //Point2d sharedAtomsCenter = sharedAtoms.get2DCenter();
        Vector2d sharedAtomsCenterVector = new Vector2d(sharedAtomsCenter);

        Vector2d newDirection = new Vector2d(atom.getPoint2d());
        if(renderingCoordinates!=null && renderingCoordinates.get(atom)!=null)
            newDirection = new Vector2d((Point2d)renderingCoordinates.get(atom));
        Vector2d occupiedDirection = new Vector2d(sharedAtomsCenter);
        occupiedDirection.sub(newDirection);
        logger.debug("distributePartners->occupiedDirection.lenght(): " + occupiedDirection.length());
        Vector atomsToDraw = new Vector();

        logger.debug("Number of shared atoms: ", placedNeighbours.getAtomCount());

        /*
         *    IMPORTANT: This method is not supposed to handle the
         *    case of one or no place neighbor. In the case of
         *    one placed neigbor, the chain placement methods
         *    should be used.
         */
        if (placedNeighbours.getAtomCount() == 1)
        {
            logger.debug("Only one neighbour...");
            for (int f = 0; f < unplacedNeighbours.getAtomCount(); f++)
            {
                atomsToDraw.addElement(unplacedNeighbours.getAtom(f));
            }

            addAngle = Math.PI * 2 / (unplacedNeighbours.getAtomCount() + placedNeighbours.getAtomCount());
            /*
             *  IMPORTANT: At this point we need a calculation of the
             *  start angle.
             *  Not done yet.
             */
            IAtom placedAtom = placedNeighbours.getAtom(0);
//                double xDiff = atom.getX2d() - placedAtom.getX2d();
//                double yDiff = atom.getY2d() - placedAtom.getY2d();
            double xDiff = placedAtom.getPoint2d().x - atom.getPoint2d().x;
            double yDiff = placedAtom.getPoint2d().y - atom.getPoint2d().y;
            if(renderingCoordinates!=null){
                if(renderingCoordinates.get(atom)==null)
                    renderingCoordinates.put(atom,atom.getPoint2d());
                xDiff = ((Point2d)renderingCoordinates.get(placedAtom)).x - ((Point2d)renderingCoordinates.get(atom)).x;
                yDiff = ((Point2d)renderingCoordinates.get(placedAtom)).y - ((Point2d)renderingCoordinates.get(atom)).y;
            }

            logger.debug("distributePartners->xdiff: " + Math.toDegrees(xDiff));
            logger.debug("distributePartners->ydiff: " + Math.toDegrees(yDiff));
            startAngle = GeometryToolsInternalCoordinates.getAngle(xDiff, yDiff);
            //- (Math.PI / 2.0);
            logger.debug("distributePartners->angle: " + Math.toDegrees(startAngle));

            populatePolygonCorners(atomsToDraw, new Point2d(renderingCoordinates==null ? atom.getPoint2d() : ((Point2d)renderingCoordinates.get(atom))), startAngle, addAngle, bondLength,renderingCoordinates);
            return;
        } else if (placedNeighbours.getAtomCount() == 0)
        {
            logger.debug("First atom...");
            for (int f = 0; f < unplacedNeighbours.getAtomCount(); f++)
            {
                atomsToDraw.addElement(unplacedNeighbours.getAtom(f));
            }

            addAngle = Math.PI * 2.0 / unplacedNeighbours.getAtomCount();
            /*
             * IMPORTANT: At this point we need a calculation of the
             * start angle. Not done yet.
             */
            startAngle = 0.0;
            populatePolygonCorners(atomsToDraw, new Point2d(renderingCoordinates==null ? atom.getPoint2d() : ((Point2d)renderingCoordinates.get(atom))), startAngle, addAngle, bondLength,renderingCoordinates);
            return;
        }

        /*
         *  if the least hindered side of the atom is clearly defined (bondLength / 10 is an arbitrary value that seemed reasonable)
         */
        //newDirection.sub(sharedAtomsCenterVector);
        sharedAtomsCenterVector.sub(newDirection);
        newDirection = sharedAtomsCenterVector;
        newDirection.normalize();
        newDirection.scale(bondLength);
        newDirection.negate();
        logger.debug("distributePartners->newDirection.lenght(): " + newDirection.length());
        Point2d distanceMeasure = new Point2d(atom.getPoint2d());
        distanceMeasure.add(newDirection);

        /*
         *  get the two sharedAtom partners with the smallest distance to the new center
         */
        sortedAtoms = AtomContainerManipulator.getAtomArray(placedNeighbours);
        if(renderingCoordinates!=null)
            GeometryTools.sortBy2DDistance(sortedAtoms, distanceMeasure,renderingCoordinates);
        else
            GeometryToolsInternalCoordinates.sortBy2DDistance(sortedAtoms, distanceMeasure);
        Vector2d closestPoint1 = new Vector2d(sortedAtoms[0].getPoint2d());
        Vector2d closestPoint2 = new Vector2d(sortedAtoms[1].getPoint2d());
        closestPoint1.sub(new Vector2d(atom.getPoint2d()));
        closestPoint2.sub(new Vector2d(atom.getPoint2d()));
        if(renderingCoordinates!=null){
            GeometryTools.sortBy2DDistance(sortedAtoms, distanceMeasure, renderingCoordinates);
            closestPoint1 = new Vector2d(((Point2d)renderingCoordinates.get(sortedAtoms[0])));
            closestPoint2 = new Vector2d(((Point2d)renderingCoordinates.get(sortedAtoms[1])));
            closestPoint1.sub(new Vector2d(((Point2d)renderingCoordinates.get(atom))));
            closestPoint2.sub(new Vector2d(((Point2d)renderingCoordinates.get(atom))));
        }
        occupiedAngle = closestPoint1.angle(occupiedDirection);
        occupiedAngle += closestPoint2.angle(occupiedDirection);

        double angle1 = GeometryTools.getAngle(sortedAtoms[0].getPoint2d().x - atom.getPoint2d().x, sortedAtoms[0].getPoint2d().y - atom.getPoint2d().y);
        double angle2 = GeometryTools.getAngle(sortedAtoms[1].getPoint2d().x - atom.getPoint2d().x, sortedAtoms[1].getPoint2d().y - atom.getPoint2d().y);
        double angle3 = GeometryTools.getAngle(distanceMeasure.x - atom.getPoint2d().x, distanceMeasure.y - atom.getPoint2d().y);
        if(renderingCoordinates!=null){
            angle1 = GeometryTools.getAngle(((Point2d)renderingCoordinates.get(sortedAtoms[0])).x - ((Point2d)renderingCoordinates.get(atom)).x, ((Point2d)renderingCoordinates.get(sortedAtoms[0])).y - ((Point2d)renderingCoordinates.get(atom)).y);
            angle2 = GeometryTools.getAngle(((Point2d)renderingCoordinates.get(sortedAtoms[1])).x - ((Point2d)renderingCoordinates.get(atom)).x, ((Point2d)renderingCoordinates.get(sortedAtoms[1])).y - ((Point2d)renderingCoordinates.get(atom)).y);
            angle3 = GeometryTools.getAngle(distanceMeasure.x - ((Point2d)renderingCoordinates.get(atom)).x, distanceMeasure.y - ((Point2d)renderingCoordinates.get(atom)).y);
        }
        if (debug)
        {
            try
            {
                logger.debug("distributePartners->sortedAtoms[0]: ", (molecule.getAtomNumber(sortedAtoms[0]) + 1));
                logger.debug("distributePartners->sortedAtoms[1]: ", (molecule.getAtomNumber(sortedAtoms[1]) + 1));
                logger.debug("distributePartners->angle1: ", Math.toDegrees(angle1));
                logger.debug("distributePartners->angle2: ", Math.toDegrees(angle2));
            } catch (Exception exc) {
                logger.debug(exc);
            }
        }
        IAtom startAtom = null;

        if (angle1 > angle3)
        {
            if (angle1 - angle3 < Math.PI)
            {
                startAtom = sortedAtoms[1];
            } else
            {
                // 12 o'clock is between the two vectors
                startAtom = sortedAtoms[0];
            }

        } else
        {
            if (angle3 - angle1 < Math.PI)
            {
                startAtom = sortedAtoms[0];
            } else
            {
                // 12 o'clock is between the two vectors
                startAtom = sortedAtoms[1];
            }
        }
        remainingAngle = (2 * Math.PI) - occupiedAngle;
        addAngle = remainingAngle / (unplacedNeighbours.getAtomCount() + 1);
        if (debug)
        {
            try
            {
                logger.debug("distributePartners->startAtom: " + (molecule.getAtomNumber(startAtom) + 1));
                logger.debug("distributePartners->remainingAngle: " + Math.toDegrees(remainingAngle));
                logger.debug("distributePartners->addAngle: " + Math.toDegrees(addAngle));
                logger.debug("distributePartners-> partners.getAtomCount(): " + unplacedNeighbours.getAtomCount());
            } catch (Exception exc)
            {
                logger.debug(exc);
            }

        }
        for (int f = 0; f < unplacedNeighbours.getAtomCount(); f++)
        {
            atomsToDraw.addElement(unplacedNeighbours.getAtom(f));
        }
        radius = bondLength;
        startAngle = GeometryTools.getAngle(startAtom.getPoint2d().x - atom.getPoint2d().x, startAtom.getPoint2d().y - atom.getPoint2d().y);
        if(renderingCoordinates!=null){
            startAngle = GeometryTools.getAngle(((Point2d)renderingCoordinates.get(startAtom)).x - ((Point2d)renderingCoordinates.get(atom)).x, ((Point2d)renderingCoordinates.get(startAtom)).y - ((Point2d)renderingCoordinates.get(atom)).y);
        }
        logger.debug("Before check: distributePartners->startAngle: " + startAngle);
//        if (startAngle < (Math.PI + 0.001) && startAngle > (Math.PI
//            -0.001))
//        {
//            startAngle = Math.PI/placedNeighbours.getAtomCount();
//        }
        logger.debug("After check: distributePartners->startAngle: " + startAngle);
        populatePolygonCorners(atomsToDraw, renderingCoordinates==null ? new Point2d(atom.getPoint2d()) : ((Point2d)renderingCoordinates.get(atom)), startAngle, addAngle, radius);

    }


Generated by  Doxygen 1.6.0   Back to index