Revert "Fix 525"

This commit is contained in:
Daniel Williams 2020-02-15 09:23:01 -05:00 committed by GitHub
parent 64514ed514
commit 95d497827d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 415 additions and 183 deletions

View File

@ -2,6 +2,7 @@ package net.sf.openrocket.aerodynamics;
import static net.sf.openrocket.util.MathUtil.pow2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
@ -22,7 +23,6 @@ import net.sf.openrocket.rocketcomponent.InstanceMap;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.PolyInterpolator;
@ -96,6 +96,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
// Calculate non-axial force data
AerodynamicForces total = calculateNonAxialForces(configuration, conditions, map, warnings);
// Calculate friction data
total.setFrictionCD(calculateFrictionDrag(configuration, conditions, map, warnings));
total.setPressureCD(calculatePressureDrag(configuration, conditions, map, warnings));
@ -173,6 +174,7 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
if (calcMap == null)
buildCalcMap(configuration);
if( ! isContinuous( configuration.getRocket() ) ){
warnings.add( Warning.DIAMETER_DISCONTINUITY);
}

View File

@ -55,6 +55,24 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
separations.reset(fcid);
}
/**
* {@inheritDoc}
* not strictly accurate, but this should provide an acceptable estimate for total vehicle size
*/
@Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
Coordinate[] instanceLocations = this.getInstanceLocations();
double x_min = instanceLocations[0].x;
double x_max = x_min + this.length;
double r_max = 0;
addBound(bounds, x_min, r_max);
addBound(bounds, x_max, r_max);
return bounds;
}
/**
* Check whether the given type can be added to this component. A Stage allows
* only BodyComponents to be added.

View File

@ -10,7 +10,6 @@ import net.sf.openrocket.motor.MotorConfiguration;
import net.sf.openrocket.motor.MotorConfigurationSet;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
@ -297,7 +296,52 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
private static double getFilledVolume(double r, double l) {
return Math.PI * r * r * l;
}
/**
* Adds bounding coordinates to the given set. The body tube will fit within the
* convex hull of the points.
*
* Currently the points are simply a rectangular box around the body tube.
*/
@Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
double x_min_shape = 0;
double x_max_shape = this.length;
double r_max_shape = getOuterRadius();
Coordinate[] locs = this.getLocations();
// not strictly accurate, but this should provide an acceptable estimate for total vehicle size
double x_min_inst = Double.MAX_VALUE;
double x_max_inst = Double.MIN_VALUE;
double r_max_inst = 0.0;
// refactor: get component inherent bounds
for (Coordinate cur : locs) {
double x_cur = cur.x;
double r_cur = MathUtil.hypot(cur.y, cur.z);
if (x_min_inst > x_cur) {
x_min_inst = x_cur;
}
if (x_max_inst < x_cur) {
x_max_inst = x_cur;
}
if (r_cur > r_max_inst) {
r_max_inst = r_cur;
}
}
// combine the position bounds with the inherent shape bounds
double x_min = x_min_shape + x_min_inst;
double x_max = x_max_shape + x_max_inst;
double r_max = r_max_shape + r_max_inst;
addBoundingBox(bounds, x_min, x_max, r_max);
return bounds;
}
/**
* Check whether the given type can be added to this component. BodyTubes allow any
* InternalComponents or ExternalComponents, excluding BodyComponents, to be added.

View File

@ -9,7 +9,6 @@ import org.slf4j.LoggerFactory;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.rocketcomponent.position.AxialPositionable;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
@ -47,6 +46,14 @@ public abstract class ComponentAssembly extends RocketComponent implements Axia
public double getAxialOffset() {
return getAxialOffset( this.axialMethod );
}
/**
* Null method (ComponentAssembly has no bounds of itself).
*/
@Override
public Collection<Coordinate> getComponentBounds() {
return Collections.emptyList();
}
/**
* Null method (ComponentAssembly has no mass of itself).
@ -100,17 +107,6 @@ public abstract class ComponentAssembly extends RocketComponent implements Axia
}
return outerRadius;
}
/**
* We'll find the bounding box of a component by iterating an
* InstanceMap, not by performing a treewalk of the component.
* So, anything subclassed from a ComponentAssembly will just
* return an empty bounding box
*/
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox();
}
/**
* Components have no aerodynamic effect, so return false.

View File

@ -709,16 +709,53 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
BoundingBox singleFinBounds= new BoundingBox().update(getFinPoints());
final double finLength = singleFinBounds.max.x;
final double finHeight = singleFinBounds.max.y;
/*
BoundingBox compBox = new BoundingBox().update(getComponentLocations());
BoundingBox finSetBox = new BoundingBox( compBox.min.sub( 0, finHeight, finHeight ),
compBox.max.add( finLength, finHeight, finHeight ));
return finSetBox;
*/
return new BoundingBox(0.0, finLength, finHeight);
}
/**
* Adds bounding coordinates to the given set. The body tube will fit within the
* convex hull of the points.
*
* Currently the points are simply a rectangular box around the body tube.
*/
@Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
// should simply return this component's bounds in this component's body frame.
double x_min = Double.MAX_VALUE;
double x_max = Double.MIN_VALUE;
double r_max = 0.0;
for (Coordinate point : getFinPoints()) {
double hypot = MathUtil.hypot(point.y, point.z);
double x_cur = point.x;
if (x_min > x_cur) {
x_min = x_cur;
}
if (x_max < x_cur) {
x_max = x_cur;
}
if (r_max < hypot) {
r_max = hypot;
}
}
Coordinate location = this.getLocations()[0];
x_max += location.x;
if( parent instanceof SymmetricComponent){
r_max += ((SymmetricComponent)parent).getRadius(0);
}
addBoundingBox(bounds, x_min, x_max, r_max);
return bounds;
}
@Override

View File

@ -63,7 +63,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
final protected HashMap<MotorConfigurationId, MotorConfiguration> motors = new HashMap<MotorConfigurationId, MotorConfiguration>();
private int boundsModID = -1;
private BoundingBox cachedBoundingBox = new BoundingBox();
private BoundingBox cachedBounds = new BoundingBox();
private double cachedLength = -1;
private int refLengthModID = -1;
@ -501,6 +501,18 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
return isComponentActive( (RocketComponent) c);
}
/**
* Return the bounds of the current configuration. The bounds are cached.
*
* @return a <code>Collection</code> containing coordinates bounding the rocket.
*
* @deprecated Migrate to <FlightConfiguration>.getBoundingBox(), when practical.
*/
@Deprecated
public Collection<Coordinate> getBounds() {
return getBoundingBox().toCollection();
}
/**
* Return the bounding box of the current configuration.
*
@ -508,34 +520,22 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
*/
public BoundingBox getBoundingBox() {
if (rocket.getModID() != boundsModID) {
calculateBoundingBox();
calculateBounds();
}
return cachedBoundingBox;
return cachedBounds;
}
private void calculateBoundingBox(){
private void calculateBounds(){
BoundingBox bounds = new BoundingBox();
// iterate through all components
final InstanceMap imap = this.getActiveInstances();
for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
final RocketComponent comp = entry.getKey();
if (this.isComponentActive(comp)) {
// iterate across all componenent instances
final ArrayList<InstanceContext> contextList = entry.getValue();
for(InstanceContext context: contextList ) {
BoundingBox instanceBox = new BoundingBox(context.transform.transform(comp.getBoundingBox().min),
context.transform.transform(comp.getBoundingBox().max));
bounds.update(instanceBox);
}
}
for (RocketComponent component : this.getActiveComponents()) {
BoundingBox componentBounds = new BoundingBox().update(component.getComponentBounds());
bounds.update( componentBounds );
}
boundsModID = rocket.getModID();
cachedLength = bounds.span().x;
cachedBoundingBox.update( bounds );
cachedBounds.update( bounds );
}
/**
@ -546,7 +546,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
*/
public double getLength() {
if (rocket.getModID() != boundsModID) {
calculateBoundingBox();
calculateBounds();
}
return cachedLength;
}
@ -567,7 +567,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
FlightConfiguration clone = new FlightConfiguration( this.rocket, this.fcid );
clone.setName(configurationName);
clone.cachedBoundingBox = this.cachedBoundingBox.clone();
clone.cachedBounds = this.cachedBounds.clone();
clone.modID = this.modID;
clone.boundsModID = -1;
clone.refLengthModID = -1;
@ -594,7 +594,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
cloneMotor.getMount().setMotorConfig(cloneMotor, copyId);
}
copy.cachedBoundingBox = this.cachedBoundingBox.clone();
copy.cachedBounds = this.cachedBounds.clone();
copy.modID = this.modID;
copy.boundsModID = -1;
copy.refLengthModID = -1;

View File

@ -1,10 +1,10 @@
package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.Transformation;

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.rocketcomponent;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.rocketcomponent.position.AxialPositionable;
import net.sf.openrocket.util.BoundingBox;
/**
* A component internal to the rocket. Internal components have no effect on the
@ -36,15 +35,6 @@ public abstract class InternalComponent extends RocketComponent implements Axial
return false;
}
/**
* An internal component can't extend beyond the bounding box established by external components
* Return an empty bounding box to simplify methods calling us.
*/
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox();
}
/**
* Is massive.
* @return <code>true</code>

View File

@ -8,7 +8,6 @@ import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.ComponentPreset.Type;
import net.sf.openrocket.rocketcomponent.position.*;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
@ -187,10 +186,13 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, C
public double getComponentVolume() {
return length * Math.PI * (MathUtil.pow2(radius) - MathUtil.pow2(radius - thickness));
}
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox(0, length, radius);
public Collection<Coordinate> getComponentBounds() {
ArrayList<Coordinate> set = new ArrayList<Coordinate>();
addBound(set, 0, radius);
addBound(set, length, radius);
return set;
}
@Override

View File

@ -133,4 +133,13 @@ public abstract class MassObject extends InternalComponent {
public final double getRotationalUnitInertia() {
return pow2(radius) / 2;
}
@Override
public final Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> c = new ArrayList<Coordinate>();
addBound(c, 0, radius);
addBound(c, length, radius);
return c;
}
}

View File

@ -44,6 +44,33 @@ public class ParallelStage extends AxialStage implements FlightConfigurableCompo
return trans.get("BoosterSet.BoosterSet");
}
// not strictly accurate, but this should provide an acceptable estimate for total vehicle size
@Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
double x_min = Double.MAX_VALUE;
double x_max = Double.MIN_VALUE;
double r_max = 0;
Coordinate[] instanceLocations = this.getComponentLocations();
for (Coordinate currentInstanceLocation : instanceLocations) {
if (x_min > (currentInstanceLocation.x)) {
x_min = currentInstanceLocation.x;
}
if (x_max < (currentInstanceLocation.x + this.length)) {
x_max = currentInstanceLocation.x + this.length;
}
if (r_max < (this.getRadiusOffset())) {
r_max = this.getRadiusOffset();
}
}
addBound(bounds, x_min, r_max);
addBound(bounds, x_max, r_max);
return bounds;
}
/**
* Check whether the given type can be added to this component. A Stage allows
* only BodyComponents to be added.

View File

@ -45,6 +45,33 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
}
// not strictly accurate, but this should provide an acceptable estimate for total vehicle size
@Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
double x_min = Double.MAX_VALUE;
double x_max = Double.MIN_VALUE;
double r_max = 0;
Coordinate[] instanceLocations = this.getComponentLocations();
for (Coordinate currentInstanceLocation : instanceLocations) {
if (x_min > (currentInstanceLocation.x)) {
x_min = currentInstanceLocation.x;
}
if (x_max < (currentInstanceLocation.x + this.length)) {
x_max = currentInstanceLocation.x + this.length;
}
if (r_max < (this.getRadiusOffset())) {
r_max = this.getRadiusOffset();
}
}
addBound(bounds, x_min, r_max);
addBound(bounds, x_max, r_max);
return bounds;
}
/**
* Check whether the given type can be added to this component. A Stage allows
* only BodyComponents to be added.

View File

@ -11,7 +11,6 @@ import net.sf.openrocket.rocketcomponent.position.AnglePositionable;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.rocketcomponent.position.AxialPositionable;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
@ -233,13 +232,6 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public Type getPresetType() {
return ComponentPreset.Type.RAIL_BUTTON;
}
@Override
public BoundingBox getBoundingBox() {
final double r = outerDiameter_m / 2.0;
return new BoundingBox(new Coordinate(-r, -r, 0),
new Coordinate(r, r, totalHeight_m));
}
@Override
public void componentChanged(ComponentChangeEvent e) {
@ -295,6 +287,21 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public String getPatternName(){
return (this.getInstanceCount() + "-Line");
}
@Override
public Collection<Coordinate> getComponentBounds() {
final double r = outerDiameter_m / 2.0;
ArrayList<Coordinate> set = new ArrayList<Coordinate>();
set.add(new Coordinate(r, totalHeight_m, r));
set.add(new Coordinate(r, totalHeight_m, -r));
set.add(new Coordinate(r, 0, r));
set.add(new Coordinate(r, 0, -r));
set.add(new Coordinate(-r, 0, r));
set.add(new Coordinate(-r, 0, -r));
set.add(new Coordinate(-r, totalHeight_m, r));
set.add(new Coordinate(-r, totalHeight_m, -r));
return set;
}
@Override
public Coordinate getComponentCG() {

View File

@ -162,6 +162,14 @@ public abstract class RingComponent extends StructuralComponent implements Coaxi
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
@Override
public Collection<Coordinate> getComponentBounds() {
List<Coordinate> bounds = new ArrayList<Coordinate>();
addBound(bounds, 0, getOuterRadius());
addBound(bounds, length, getOuterRadius());
return bounds;
}
@Override
public Coordinate getComponentCG() {
Coordinate cg = Coordinate.ZERO;
@ -187,6 +195,7 @@ public abstract class RingComponent extends StructuralComponent implements Coaxi
getMaterial().getDensity()) * getInstanceCount();
}
@Override
public double getLongitudinalUnitInertia() {
return ringLongitudinalUnitInertia(getOuterRadius(), getInnerRadius(), getLength());

View File

@ -19,7 +19,6 @@ import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.ChangeSource;
import net.sf.openrocket.util.Color;
@ -223,13 +222,14 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
/**
* Return bounding box of component.
* Return a collection of bounding coordinates. The coordinates must be such that
* the component is fully enclosed in their convex hull.
*
* Note: this function gets the bounds only for this component. Subchildren must be called individually.
*
* @return a collection of coordinates that bound the component.
*/
public abstract BoundingBox getBoundingBox();
public abstract Collection<Coordinate> getComponentBounds();
/**
* Return true if the component may have an aerodynamic effect on the rocket.
@ -1902,9 +1902,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
/**
* Helper method to add two points on opposite corners of a box
* around the component centerline. This box will be (x_max -
* x_min) long, and 2*r wide/high.
* Helper method to add two points on opposite corners of a box around the rocket centerline. This box will be (x_max - x_min) long, and 2*r wide/high.
*/
protected static final void addBoundingBox(Collection<Coordinate> bounds, double x_min, double x_max, double r) {
bounds.add(new Coordinate(x_min, -r, -r));

View File

@ -1,4 +1,3 @@
// this class is only used by the Android application
package net.sf.openrocket.rocketcomponent;
import java.util.Collection;
@ -8,6 +7,20 @@ import net.sf.openrocket.util.Coordinate;
public abstract class RocketUtils {
public static double getLength(Rocket rocket) {
return rocket.getSelectedConfiguration().getLength();
double length = 0;
Collection<Coordinate> bounds = rocket.getSelectedConfiguration().getBounds();
if (!bounds.isEmpty()) {
double minX = Double.POSITIVE_INFINITY, maxX = Double.NEGATIVE_INFINITY;
for (Coordinate c : bounds) {
if (c.x < minX)
minX = c.x;
if (c.x > maxX)
maxX = c.x;
}
length = maxX - minX;
}
return length;
}
}

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.rocketcomponent;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
@ -83,6 +82,9 @@ public class Sleeve extends RingComponent {
thickness = t;
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
@Override
public void setInnerRadiusAutomatic(boolean auto) {

View File

@ -8,7 +8,6 @@ import java.util.List;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
@ -134,17 +133,24 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
clearPreset();
}
/**
* Are there any components whose max diameter isn't at either the
* fore or aft end? I don't know of any.
* Adds component bounds at a number of points between 0...length.
*/
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox(0, getLength(),
Math.max(getForeRadius(), getAftRadius()));
public Collection<Coordinate> getComponentBounds() {
List<Coordinate> list = new ArrayList<Coordinate>(20);
for (int n = 0; n <= 5; n++) {
double x = n * length / 5;
double r = getRadius(x);
addBound(list, x, r);
}
return list;
}
@Override
protected void loadFromPreset(ComponentPreset preset) {
if ( preset.has(ComponentPreset.THICKNESS) ) {

View File

@ -10,7 +10,6 @@ import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.ComponentPreset.Type;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
@ -434,22 +433,16 @@ public class Transition extends SymmetricComponent {
return Math.max(getRadius(x) - thickness, 0);
}
/**
* bounding box of transition
*
* It's tempting to ignore the shoulders (if any) on the grounds
* that they will be covered by the fore and aft body tubes, but
* including them won't cause any errors
*
* we will assume the maximum radius will occur at either the fore
* or aft end -- this is true for the transitions that are
* currently allowed, but could conceivably change in the future
*/
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox(-getForeShoulderLength(),
getLength() + getAftShoulderLength(),
Math.max(getForeRadius(), getAftRadius()));
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = super.getComponentBounds();
if (foreShoulderLength > 0.001)
addBound(bounds, -foreShoulderLength, foreShoulderRadius);
if (aftShoulderLength > 0.001)
addBound(bounds, getLength() + aftShoulderLength, aftShoulderRadius);
return bounds;
}
@Override

View File

@ -10,7 +10,6 @@ import net.sf.openrocket.preset.ComponentPreset.Type;
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.rocketcomponent.position.AxialPositionable;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.Transformation;
@ -305,10 +304,16 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
// TODO Auto-generated method stub
return false;
}
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox(0, length, outerRadius);
public Collection<Coordinate> getComponentBounds() {
List<Coordinate> bounds = new ArrayList<Coordinate>();
double r = getBodyRadius();
addBound(bounds, 0, 2 * (r + outerRadius));
addBound(bounds, length, 2 * (r + outerRadius));
return bounds;
}
/**

View File

@ -130,7 +130,11 @@ public class SimulationStatus implements Monitorable {
}
}
if (!Double.isNaN(lugPosition)) {
double maxX = this.configuration.getBoundingBox().max.x;
double maxX = 0;
for (Coordinate c : this.configuration.getBounds()) {
if (c.x > maxX)
maxX = c.x;
}
if (maxX >= lugPosition) {
length = Math.max(0, length - (maxX - lugPosition));
}

View File

@ -17,11 +17,6 @@ public class BoundingBox {
this.min = _min.clone();
this.max = _max.clone();
}
public BoundingBox(double xmin, double xmax, double rad) {
min = new Coordinate(xmin, -rad, -rad);
max = new Coordinate(xmax, rad, rad);
}
public void clear() {
min = Coordinate.MAX.setWeight( 0.0);
@ -118,14 +113,8 @@ public class BoundingBox {
update_z_max(other.max.z);
return this;
}
public Coordinate span() {
Coordinate tmp = max.sub( min );
return new Coordinate(Math.max(tmp.x, 0.0),
Math.max(tmp.y, 0.0),
Math.max(tmp.z, 0.0),
Math.max(tmp.weight, 0.0));
}
public Coordinate span() { return max.sub( min ); }
public Coordinate[] toArray() {
return new Coordinate[] { this.min, this.max };

1
openrocket.log Normal file
View File

@ -0,0 +1 @@
Error: Unable to access jarfile OpenRocket.jar

View File

@ -49,7 +49,6 @@ import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
@ -469,21 +468,64 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
redrawExtras = true;
}
@SuppressWarnings("unused")
private static class Bounds {
double xMin, xMax, xSize;
double yMin, yMax, ySize;
double zMin, zMax, zSize;
double rMax;
}
private Bounds cachedBounds = null;
/**
* Calculates the bounds for the current configuration
*
* @return
*/
private Bounds calculateBounds() {
if (cachedBounds != null) {
return cachedBounds;
} else {
final Bounds b = new Bounds();
final FlightConfiguration configuration = rkt.getSelectedConfiguration();
final Collection<Coordinate> bounds = configuration.getBounds();
for (Coordinate c : bounds) {
b.xMax = Math.max(b.xMax, c.x);
b.xMin = Math.min(b.xMin, c.x);
b.yMax = Math.max(b.yMax, c.y);
b.yMin = Math.min(b.yMin, c.y);
b.zMax = Math.max(b.zMax, c.z);
b.zMin = Math.min(b.zMin, c.z);
double r = MathUtil.hypot(c.y, c.z);
b.rMax = Math.max(b.rMax, r);
}
b.xSize = b.xMax - b.xMin;
b.ySize = b.yMax - b.yMin;
b.zSize = b.zMax - b.zMin;
cachedBounds = b;
return b;
}
}
private void setupView(final GL2 gl, final GLU glu) {
gl.glLoadIdentity();
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION,
lightPosition, 0);
// Get the bounding box
final BoundingBox b = rkt.getSelectedConfiguration().getBoundingBox();
// Get the bounds
final Bounds b = calculateBounds();
// Calculate the distance needed to fit the bounds in both the X and Y
// direction
// Add 10% for space around it.
final double dX = (b.max.x * 1.2 / 2.0)
final double dX = (b.xSize * 1.2 / 2.0)
/ Math.tan(Math.toRadians(fovX / 2.0));
final double dY = (b.max.y * 2.0 * 1.2 / 2.0)
final double dY = (b.rMax * 2.0 * 1.2 / 2.0)
/ Math.tan(Math.toRadians(fovY / 2.0));
// Move back the greater of the 2 distances
@ -493,8 +535,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
gl.glRotated(roll * (180.0 / Math.PI), 1, 0, 0);
// Center the rocket in the view.
// gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0);
gl.glTranslated((b.min.x - b.max.x) / 2.0, 0, 0);
gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0);
//Change to LEFT Handed coordinates
gl.glScaled(1, 1, -1);
@ -513,6 +554,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
*/
public void updateFigure() {
log.debug("3D Figure Updated");
cachedBounds = null;
if (canvas != null) {
((GLAutoDrawable) canvas).invoke(true, new GLRunnable() {
@Override

View File

@ -2,6 +2,7 @@ package net.sf.openrocket.gui.figure3d;
import java.awt.Point;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
@ -27,7 +28,6 @@ import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.InstanceMap;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;

View File

@ -25,7 +25,6 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.rocketcomponent.Transition.Shape;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
@ -122,57 +121,12 @@ public class ComponentRenderer {
} else if ( c instanceof ParallelStage ) {
} else if ( c instanceof PodSet ) {
} else {
renderBoundingBox(gl, c);
renderOther(gl, c);
}
}
/**
* If I don't have a method to render an object, I'll render its bounding box
*/
private void renderBoundingBox(GL2 gl, RocketComponent c) {
BoundingBox box = c.getBoundingBox();
// rectangle at forward end
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(box.min.x, box.min.y, box.min.z);
gl.glVertex3d(box.min.x, box.max.y, box.min.z);
gl.glVertex3d(box.min.x, box.max.y, box.max.z);
gl.glVertex3d(box.min.x, box.max.x, box.min.z);
gl.glEnd();
// rectangle at aft end
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(box.max.x, box.min.y, box.min.z);
gl.glVertex3d(box.max.x, box.max.y, box.min.z);
gl.glVertex3d(box.max.x, box.max.y, box.max.z);
gl.glVertex3d(box.max.x, box.max.x, box.min.z);
gl.glEnd();
// connect forward and aft rectangles
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(box.min.x, box.min.y, box.min.z);
gl.glVertex3d(box.max.x, box.min.y, box.min.z);
gl.glEnd();
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(box.min.x, box.max.y, box.min.z);
gl.glVertex3d(box.max.x, box.max.y, box.min.z);
gl.glEnd();
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(box.min.x, box.min.y, box.max.z);
gl.glVertex3d(box.max.x, box.min.y, box.max.z);
gl.glEnd();
gl.glBegin(GL.GL_LINES);
gl.glVertex3d(box.min.x, box.max.y, box.max.z);
gl.glVertex3d(box.max.x, box.max.y, box.max.z);
gl.glEnd();
}
/*
private void renderOther(GL2 gl, RocketComponent c) {
gl.glBegin(GL.GL_LINES);
for (Coordinate cc : c.getComponentBounds()) {
@ -183,7 +137,7 @@ public class ComponentRenderer {
}
gl.glEnd();
}
*/
private void renderTransition(GL2 gl, Transition t, Surface which) {
if (which == Surface.OUTSIDE || which == Surface.INSIDE) {

View File

@ -52,7 +52,6 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Color;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
@ -93,6 +92,7 @@ public class PhotoPanel extends JPanel implements GLEventListener {
@Override
public boolean run(final GLAutoDrawable drawable) {
PhotoPanel.this.configuration = doc.getSelectedConfiguration();
cachedBounds = null;
rr = new RealisticRenderer(doc);
rr.init(drawable);
@ -246,11 +246,11 @@ public class PhotoPanel extends JPanel implements GLEventListener {
draw(drawable, 0);
if (p.isMotionBlurred()) {
BoundingBox b = configuration.getBoundingBox();
Bounds b = calculateBounds();
float m = .6f;
int c = 10;
float d = (float) (b.max.x - b.min.x) / 25.0f;
float d = (float) b.xSize / 25.0f;
gl.glAccum(GL2.GL_LOAD, m);
@ -391,11 +391,11 @@ public class PhotoPanel extends JPanel implements GLEventListener {
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_SPECULAR,
new float[] { color[0], color[1], color[2], 1 }, 0);
BoundingBox b = configuration.getBoundingBox();
Bounds b = calculateBounds();
gl.glLightf(GLLightingFunc.GL_LIGHT2,
GLLightingFunc.GL_QUADRATIC_ATTENUATION, 20f);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_POSITION,
new float[] { (float) (b.max.x + .1f), 0, 0, 1 }, 0);
new float[] { (float) (b.xMax + .1f), 0, 0, 1 }, 0);
gl.glEnable(GLLightingFunc.GL_LIGHT2);
} else {
gl.glDisable(GLLightingFunc.GL_LIGHT2);
@ -478,14 +478,56 @@ public class PhotoPanel extends JPanel implements GLEventListener {
ratio = (double) w / (double) h;
}
@SuppressWarnings("unused")
private static class Bounds {
double xMin, xMax, xSize;
double yMin, yMax, ySize;
double zMin, zMax, zSize;
double rMax;
}
private Bounds cachedBounds = null;
/**
* Calculates the bounds for the current configuration
*
* @return
*/
private Bounds calculateBounds() {
if (cachedBounds != null) {
return cachedBounds;
} else {
final Bounds b = new Bounds();
final Collection<Coordinate> bounds = configuration.getBounds();
for (Coordinate c : bounds) {
b.xMax = Math.max(b.xMax, c.x);
b.xMin = Math.min(b.xMin, c.x);
b.yMax = Math.max(b.yMax, c.y);
b.yMin = Math.min(b.yMin, c.y);
b.zMax = Math.max(b.zMax, c.z);
b.zMin = Math.min(b.zMin, c.z);
double r = MathUtil.hypot(c.y, c.z);
b.rMax = Math.max(b.rMax, r);
}
b.xSize = b.xMax - b.xMin;
b.ySize = b.yMax - b.yMin;
b.zSize = b.zMax - b.zMin;
cachedBounds = b;
return b;
}
}
private void setupModel(final GL2 gl) {
// Get the bounds
final Bounds b = calculateBounds();
gl.glRotated(-p.getPitch() * (180.0 / Math.PI), 0, 0, 1);
gl.glRotated(p.getYaw() * (180.0 / Math.PI), 0, 1, 0);
gl.glRotated(p.getRoll() * (180.0 / Math.PI), 1, 0, 0);
// Center the rocket in the view.
final BoundingBox b = configuration.getBoundingBox();
gl.glTranslated((b.min.x - b.max.x) / 2.0, 0, 0);
gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0);
}
}

View File

@ -61,6 +61,10 @@ public class RocketInfo implements FigureElement {
private float line = 0;
private float x1, x2, y1, y2;
public RocketInfo(FlightConfiguration configuration) {
this.configuration = configuration;
this.stabilityUnits = UnitGroup.stabilityUnits(configuration);

View File

@ -14,6 +14,7 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Map.Entry;
@ -33,7 +34,6 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate;

View File

@ -67,12 +67,12 @@ import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.simulation.listeners.system.ApogeeEndListener;
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.ChangeSource;
import net.sf.openrocket.util.Chars;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.StateChangeListener;
import net.sf.openrocket.unit.UnitGroup;
/**
@ -607,7 +607,18 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
figure3d.setCP(cp);
// Length bound is assumed to be tight
double length = curConfig.getLength();
double length = 0;
Collection<Coordinate> bounds = curConfig.getBounds();
if (!bounds.isEmpty()) {
double minX = Double.POSITIVE_INFINITY, maxX = Double.NEGATIVE_INFINITY;
for (Coordinate c : bounds) {
if (c.x < minX)
minX = c.x;
if (c.x > maxX)
maxX = c.x;
}
length = maxX - minX;
}
double diameter = Double.NaN;
for (RocketComponent c : curConfig.getCoreComponents()) {