Revert "Fix 525"
This commit is contained in:
parent
64514ed514
commit
95d497827d
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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() {
|
||||
|
@ -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());
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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) ) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
1
openrocket.log
Normal file
@ -0,0 +1 @@
|
||||
Error: Unable to access jarfile OpenRocket.jar
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user