package net.sf.openrocket.unit; import java.util.Iterator; import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.SymmetricComponent; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.MathUtil; public class CaliberUnit extends GeneralUnit { public static final double DEFAULT_CALIBER = 0.01; private final Configuration configuration; private final Rocket rocket; private int rocketModId = -1; private int configurationModId = -1; private double caliber = -1; public CaliberUnit(Configuration configuration) { super(1.0, "cal"); this.configuration = configuration; if (configuration == null) { this.rocket = null; } else { this.rocket = configuration.getRocket(); } } public CaliberUnit(Rocket rocket) { super(1.0, "cal"); this.configuration = null; this.rocket = rocket; } public CaliberUnit(double reference) { super(1.0, "cal"); this.configuration = null; this.rocket = null; this.caliber = reference; if (reference <= 0) { throw new IllegalArgumentException("Illegal reference = " + reference); } } @Override public double fromUnit(double value) { checkCaliber(); return value * caliber; } @Override public double toUnit(double value) { checkCaliber(); return value / caliber; } private void checkCaliber() { if (configuration != null && configuration.getModID() != configurationModId) { caliber = -1; configurationModId = configuration.getModID(); } if (rocket != null && rocket.getModID() != rocketModId) { caliber = -1; rocketModId = rocket.getModID(); } if (caliber < 0) { if (configuration != null) { caliber = calculateCaliber(configuration); } else if (rocket != null) { caliber = calculateCaliber(rocket); } else { throw new BugException("Both rocket and configuration are null"); } } } /** * Calculate the caliber of a rocket configuration. * * @param config the rocket configuration * @return the caliber of the rocket, or the default caliber. */ public static double calculateCaliber(Configuration config) { return calculateCaliber(config.iterator()); } /** * Calculate the caliber of a rocket. * * @param rocket the rocket * @return the caliber of the rocket, or the default caliber. */ public static double calculateCaliber(Rocket rocket) { return calculateCaliber(rocket.iterator()); } private static double calculateCaliber(Iterator<RocketComponent> iterator) { double cal = 0; while (iterator.hasNext()) { RocketComponent c = iterator.next(); if (c instanceof SymmetricComponent) { double r1 = ((SymmetricComponent) c).getForeRadius() * 2; double r2 = ((SymmetricComponent) c).getAftRadius() * 2; cal = MathUtil.max(cal, r1, r2); } } if (cal < 0.0001) cal = DEFAULT_CALIBER; return cal; } }