All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.actelion.research.share.gui.ChemistryGeometryHelper Maven / Gradle / Ivy

There is a newer version: 2024.11.2
Show newest version
/*
* Copyright (c) 1997 - 2016
* Actelion Pharmaceuticals Ltd.
* Gewerbestrasse 16
* CH-4123 Allschwil, Switzerland
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
*    list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
* 3. Neither the name of the the copyright holder nor the
*    names of its contributors may be used to endorse or promote products
*    derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

package com.actelion.research.share.gui;

import com.actelion.research.chem.AbstractDepictor;
import com.actelion.research.chem.ExtendedMolecule;
import com.actelion.research.chem.Molecule;
import com.actelion.research.chem.StereoMolecule;
import com.actelion.research.chem.reaction.Reaction;
import com.actelion.research.gui.generic.GenericRectangle;

import java.awt.*;


public class ChemistryGeometryHelper
{
    public static final int REACTION_TYPE_NOMOLS = 0;
    public static final int REACTION_TYPE_NOPRODUCTS = 1;
    public static final int REACTION_TYPE_REACTANTS = 2;
    public static final int REACTION_TYPE_NORMAL = 3;

    public static int getReactionType(Reaction r)
    {
        int mols = r.getMolecules();
        int nr = r.getReactants();
        int np = r.getProducts();
        if (mols == 0)
            return REACTION_TYPE_NOMOLS;
        else if (nr == 0)
            return REACTION_TYPE_REACTANTS;
        else if (np == 0)
            return REACTION_TYPE_NOPRODUCTS;
        else
            return REACTION_TYPE_NORMAL;
    }

    public static GenericRectangle getBoundingRect(Reaction r, boolean includearrows)
    {
        GenericRectangle res = null;
        if (r == null)
            return null;
        int nr = r.getReactants();
        int np = r.getProducts();
        int m = r.getMolecules();
        double width = 0;
        double avgwidth = 0;

        for (int i = 0; i < m; i++) {
            ExtendedMolecule mol = r.getMolecule(i);
            int nb = mol.getAllBonds();
            GenericRectangle d = getBoundingRect(mol);
//			System.out.println("getBoundingRect " + i + "=" + d);
            if (res == null) {
                if (d != null && nb > 0) {
                    res = d;
                    width += d.getWidth();
                } else {
//					System.out.println("Empty bounding rect for molecule " + i);
                }
            } else {
                if (d != null && nb > 0) {
                    res = res.union(d);
                    width += d.getWidth();
                } else {
//					System.out.println("Empty bounding rect for molecule " + i);
                }
            }
        }
        if (includearrows && nr == 0 && m > 0) {
            avgwidth = width / m;
            res = new GenericRectangle(res.getX() - avgwidth, res.getY(), res.getWidth() + avgwidth, res.getHeight());
        } else if (includearrows && np == 0 && m > 0) {
            avgwidth = width / m;
            res = new GenericRectangle(res.getX(), res.getY(), res.getWidth() + avgwidth, res.getHeight());
        }
//		System.out.println("Reaction av bnd length: " + width + " getBoundingBox " + res);

        return res;
    }

    public static GenericRectangle getBoundingRect(ExtendedMolecule m)
    {
        double xmax = Double.MIN_VALUE;
        double ymax = Double.MIN_VALUE;
        double xmin = Double.MAX_VALUE;
        double ymin = Double.MAX_VALUE;

        if (m == null)
            return null;

        int na = m.getAllAtoms();
        double bl = 0;
//        if (na > 1)
            bl = m.getAverageBondLength();
        for (int i = 0; i < na; i++) {
            xmax = Math.max(xmax, m.getAtomX(i));
            xmin = Math.min(xmin, m.getAtomX(i));
            ymax = Math.max(ymax, m.getAtomY(i));
            ymin = Math.min(ymin, m.getAtomY(i));
        }

        return (na > 0) ? new GenericRectangle(xmin, ymin, Math.max(xmax - xmin, bl), Math.max(ymax - ymin, bl)) : null;
    }


    public static double getAverageBondLength(Reaction r)
    {
        int rn = r.getMolecules();
        double avg = 0;
        double t = 0;
        for (int i = 0; i < rn; i++) {
            StereoMolecule molecule = r.getMolecule(i);
            if (molecule.getAllAtoms() > 1)
                t += molecule.getAverageBondLength();
        }
        if (rn > 0)
            return t / rn;
        else
            return 0;
    }



    public static  void setAverageBondLength(Reaction rxn, double bndlen)
    {
        double dx = 0;
        int len = rxn.getMolecules();
        for (int fragment=0; fragment scV)
                scale = scV;

//            System.out.printf("Scaleinto scale %s\n",scale);
            ChemistryGeometryHelper.transformReaction(reaction, 0, 0, scH);
        }
    }

    public static void scaleInto(Reaction reaction, double x, double y, double width, double height, double arrowSize)
    {

        if (width > arrowSize * 2) {


            ExtendedMolecule[] reactants = getReactants(reaction);
            ExtendedMolecule[] products = getProducts(reaction);

            double sumWidth = 0, sumHeight = 0;
            int numMols = reaction.getMolecules();
            for (int i = 0; i < numMols; i++) {
                ExtendedMolecule m = reaction.getMolecule(i);
                if (m.getAllAtoms() > 1)
                {
                    GenericRectangle r = ChemistryGeometryHelper.getBoundingRect(m);
                    if (r != null) {
                        //                    System.out.printf("MoleculeID %s bounds: %s\n",System.identityHashCode(m),r);
                        sumHeight += r.getHeight();
                        sumWidth += r.getWidth();
                    }
                }
            }

            if (sumHeight == 0 || sumWidth == 0)
                return;

            double scH = width/sumWidth;
            double scV = height/sumHeight;

            double scale = scH;
            if  (scH > scV)
                scale = scV;

            double avbl = getAverageBondLength(reaction);
         //   setAverageBondLength(reaction,avbl);

            double w = (width - arrowSize) / 2;
            double h = height;
//            System.out.printf("Scale = %s vs %s\n",AbstractDepictor.cOptAvBondLen/avbl,scale);
            scale = Math.min(AbstractDepictor.cOptAvBondLen/avbl,scale);
//            if (reactants.length <= 1 && products.length <= 1)
//                scale /= 4;
            {

                GenericRectangle rb = getBoundingRect(reactants);
//                System.out.printf("W/h before scaling prods %s\n",rb);
                transformMolecules(reactants, 0, 0, scale);
                rb = getBoundingRect(reactants);
                double dx = x - rb.x + (w - rb.getWidth()) / 2;
                double dy = y - rb.y + (h - rb.getHeight()) / 2;
//                System.out.printf("W/h after scaling reactants %s,%s $s\n",dx,dy,rb);
                transformMolecules(reactants, dx, dy, 1);
            }

            {
                GenericRectangle pb = getBoundingRect(products);
//                System.out.printf("W/h before scaling prods %s\n",pb);
                transformMolecules(products, 0, 0, scale);
                pb = getBoundingRect(products);
                double dx = x + w + arrowSize - pb.x + (w - pb.getWidth()) / 2;
                double dy = y - pb.y + (h - pb.getHeight()) / 2;
//                System.out.printf("W/h after scaling prods %s,%s %s\n",dx,dy,pb);
                transformMolecules(products, dx, dy, 1);
            }

        }
    }

    public static void scaleIntoOld(Reaction reaction, double x, double y, double width, double height, double arrowSize)
    {

        if (width > arrowSize * 2) {
            ExtendedMolecule[] reactants = getReactants(reaction);
            ExtendedMolecule[] products = getProducts(reaction);

            GenericRectangle rb = getBoundingRect(reactants);
            GenericRectangle pb = getBoundingRect(products);

            System.out.printf("Reactants bounds %s %s %s\n",width,rb.getWidth(),reactants.length);
            System.out.printf("Product bounds %s %s\n",height,pb.getHeight());

            // left and right space
            double w = (width - arrowSize) / 2;
            double h = height;
            double scaleHorizontal = w / Math.max(rb.getWidth(), pb.getWidth());
            double scaleVertical = h / Math.max(rb.getHeight(), pb.getHeight());
                    System.out.printf("Scaling %f vs %f\n", scaleHorizontal, scaleVertical);

            double scale;
            if (scaleHorizontal < scaleVertical) {   // scale on x-dimension
                scale = w / Math.max((float) rb.getWidth(), (float) pb.getWidth()) ;
                //            System.out.printf("Scaling horiz %f\n", scale);
            } else {                                // scale on y-dimension
                scale = h / Math.max((float) rb.getHeight(), (float) pb.getHeight()) ;
                //            System.out.printf("Scaling vert %f\n", scale);
            }

            double avbl = getAverageBondLength(reaction);
//            double sc = AbstractDepictor.cOptAvBondLen/avbl;
            scale = Math.min(AbstractDepictor.cOptAvBondLen/avbl,scale);
//            scale *=  10;
//            System.out.printf("Scale = %s\n",scale);
//            if (reactants.length <= 1 && products.length <= 1)
//                scale /= 4;
            {

                transformMolecules(reactants, 0, 0, scale);
                rb = getBoundingRect(reactants);
                double dx = x - rb.x + (w - rb.getWidth()) / 2;
                double dy = y - rb.y + (h - rb.getHeight()) / 2;
                transformMolecules(reactants, dx, dy, 1);
            }

            {
                transformMolecules(products, 0, 0, scale);
                pb = getBoundingRect(products);
                double dx = x + w + arrowSize - pb.x + (w - pb.getWidth()) / 2;
                double dy = y - pb.y + (h - pb.getHeight()) / 2;
                transformMolecules(products, dx, dy, 1);
            }

        }
    }


    public static ExtendedMolecule[] getReactants(Reaction r)
    {
        ExtendedMolecule[] ret = new ExtendedMolecule[r.getReactants()];
        for (int i = 0; i < ret.length; i++) {
            ret[i] = r.getReactant(i);
        }
        return ret;
    }

    public static ExtendedMolecule[] getProducts(Reaction r)
    {
        ExtendedMolecule[] ret = new ExtendedMolecule[r.getProducts()];
        for (int i = 0; i < ret.length; i++) {
            ret[i] = r.getProduct(i);
        }
        return ret;
    }

    public static GenericRectangle getBoundingRect(ExtendedMolecule[] mols)
    {
        if (mols == null || mols.length == 0) {
            return new GenericRectangle(0,0,0,0);
        }

        GenericRectangle r = getBoundingRect(mols[0]);
        for (int i = 1; i < mols.length; i++) {
            GenericRectangle t = getBoundingRect(mols[i]);
            if (t != null) {
                if (r == null)
                    r = t;
                else
                    r = r.union(getBoundingRect(mols[i]));
            }
        }
        if (r == null)
            r = new GenericRectangle(0,0,0,0);
        return r;
    }



    public static void arrangeReaction(Reaction rxn,Dimension size)
    {
        double cx = 0,cy=0;
        if (rxn != null) {
            int len = rxn.getMolecules();
            if (len > 0) {
                double avBndLen = getAverageBondLength(rxn);
                setAverageBondLength(rxn,avBndLen);

                for (int fragment=0; fragment




© 2015 - 2024 Weber Informatics LLC | Privacy Policy