class LengthOverBreadthDescriptor extends AbstractMolecularDescriptor implements IMolecularDescriptor {

    @Override
    public DescriptorValue calculate(IAtomContainer atomContainer) {
        if (!GeometryUtil.has3DCoordinates(atomContainer))
            return getDummyDescriptorValue(new CDKException("Molecule must have 3D coordinates"));

        double angle = 10.0;
        double maxLOB = 0;
        double minArea = 1e6;
        double mmLOB = 0;

        double lob, bol, area;
        double[] xyzRanges;

        double[][] coords = new double[atomContainer.getAtomCount()][3];
        for (int i = 0; i < atomContainer.getAtomCount(); i++) {
            coords[i][0] = atomContainer.getAtom(i).getPoint3d().x;
            coords[i][1] = atomContainer.getAtom(i).getPoint3d().y;
            coords[i][2] = atomContainer.getAtom(i).getPoint3d().z;
        }

        // get the com
        Point3d com = GeometryUtil.get3DCentreOfMass(atomContainer);
        if (com == null) 
            return getDummyDescriptorValue(new CDKException("Error in center of mass calculation, has exact mass been set on all atoms?"));

        // translate everything to COM
        for (int i = 0; i < coords.length; i++) {
            coords[i][0] -= com.x;
            coords[i][1] -= com.y;
            coords[i][2] -= com.z;
        }

        int nangle = (int) (90 / angle);
        for (int i = 0; i < nangle; i++) {
            rotateZ(coords, Math.PI / 180.0 * angle);
            try {
                xyzRanges = extents(atomContainer, coords, true);
            } catch (CDKException e) {
                return getDummyDescriptorValue(e);
            }
            lob = xyzRanges[0] / xyzRanges[1];
            bol = 1.0 / lob;
            if (lob < bol) {
                double tmp = lob;
                lob = bol;
                bol = tmp;
            }
            area = xyzRanges[0] * xyzRanges[1];
            if (lob > maxLOB) maxLOB = lob;
            if (area < minArea) {
                minArea = area;
                mmLOB = lob;
            }
        }

        DoubleArrayResult result = new DoubleArrayResult(2);
        result.add(maxLOB);
        result.add(mmLOB);

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), result,
                getDescriptorNames());
    }

    public  LengthOverBreadthDescriptor();

}