bunch of changes along the way to fixing length calculation

This commit is contained in:
JoePfeiffer 2019-06-04 08:37:26 -06:00
parent b5cde10824
commit 719576cc62
17 changed files with 159 additions and 104 deletions

View File

@ -59,7 +59,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
* {@inheritDoc}
* not strictly accurate, but this should provide an acceptable estimate for total vehicle size
*/
@Override
/* @Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
Coordinate[] instanceLocations = this.getInstanceLocations();
@ -72,7 +72,7 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
return bounds;
}
*/
/**
* Check whether the given type can be added to this component. A Stage allows
* only BodyComponents to be added.

View File

@ -10,6 +10,7 @@ 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;
@ -304,44 +305,15 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
*
* Currently the points are simply a rectangular box around the body tube.
*/
@Override
/* @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();
Collection<Coordinate> bounds = new ArrayList<Coordinate>(2);
addBoundingBox(bounds, 0, length, 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,6 +9,7 @@ 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;
@ -46,14 +47,6 @@ 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).
@ -107,6 +100,17 @@ 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

@ -2,6 +2,7 @@ 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
@ -35,6 +36,15 @@ 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,6 +8,7 @@ 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,12 +188,16 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, C
return length * Math.PI * (MathUtil.pow2(radius) - MathUtil.pow2(radius - thickness));
}
@Override
/* @Override
public Collection<Coordinate> getComponentBounds() {
ArrayList<Coordinate> set = new ArrayList<Coordinate>();
addBound(set, 0, radius);
addBound(set, length, radius);
return set;
ArrayList<Coordinate> bounds = new ArrayList<Coordinate>(2);
addBoundingBox(bounds, 0, length, radius);
return bounds;
}
*/
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox(0, length, radius);
}
@Override

View File

@ -133,13 +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,33 +44,6 @@ 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

@ -46,7 +46,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
// not strictly accurate, but this should provide an acceptable estimate for total vehicle size
@Override
/* @Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
double x_min = Double.MAX_VALUE;
@ -71,6 +71,7 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
return bounds;
}
*/
/**
* Check whether the given type can be added to this component. A Stage allows

View File

@ -11,6 +11,7 @@ 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;
@ -232,6 +233,13 @@ 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) {
@ -287,7 +295,7 @@ 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;
@ -302,7 +310,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
set.add(new Coordinate(-r, totalHeight_m, -r));
return set;
}
*/
@Override
public Coordinate getComponentCG() {
// Math.PI and density are assumed constant through calculation, and thus may be factored out.

View File

@ -162,13 +162,13 @@ public abstract class RingComponent extends StructuralComponent implements Coaxi
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
@Override
/* @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() {
@ -195,7 +195,6 @@ public abstract class RingComponent extends StructuralComponent implements Coaxi
getMaterial().getDensity()) * getInstanceCount();
}
@Override
public double getLongitudinalUnitInertia() {
return ringLongitudinalUnitInertia(getOuterRadius(), getInnerRadius(), getLength());

View File

@ -19,6 +19,7 @@ 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;
@ -222,14 +223,13 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
/**
* Return a collection of bounding coordinates. The coordinates must be such that
* the component is fully enclosed in their convex hull.
* Return bounding box of component.
*
* 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 Collection<Coordinate> getComponentBounds();
public abstract BoundingBox getBoundingBox();
/**
* Return true if the component may have an aerodynamic effect on the rocket.
@ -1902,7 +1902,9 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
/**
* 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.
* 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.
*/
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

@ -2,6 +2,7 @@ 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;
@ -82,9 +83,6 @@ public class Sleeve extends RingComponent {
thickness = t;
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
}
@Override
public void setInnerRadiusAutomatic(boolean auto) {

View File

@ -8,6 +8,7 @@ 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;
@ -138,7 +139,7 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
/**
* Adds component bounds at a number of points between 0...length.
*/
@Override
/* @Override
public Collection<Coordinate> getComponentBounds() {
List<Coordinate> list = new ArrayList<Coordinate>(20);
for (int n = 0; n <= 5; n++) {
@ -147,10 +148,18 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
addBound(list, x, r);
}
return list;
}*/
/**
* Are there any components whose max diameter isn't at either the
* fore or aft end? I don't know of any.
*/
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox(0, getLength(),
Math.max(getForeRadius(), getAftRadius()));
}
@Override
protected void loadFromPreset(ComponentPreset preset) {
if ( preset.has(ComponentPreset.THICKNESS) ) {

View File

@ -10,6 +10,7 @@ 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;
@ -435,7 +436,7 @@ public class Transition extends SymmetricComponent {
@Override
/* @Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = super.getComponentBounds();
if (foreShoulderLength > 0.001)
@ -443,6 +444,24 @@ public class Transition extends SymmetricComponent {
if (aftShoulderLength > 0.001)
addBound(bounds, getLength() + aftShoulderLength, aftShoulderRadius);
return bounds;
}*/
/**
* 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()));
}
@Override

View File

@ -10,6 +10,7 @@ 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,15 +306,18 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
return false;
}
@Override
/* @Override
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));
List<Coordinate> bounds = new ArrayList<Coordinate>(2);
addBoundingBox(bounds, 0, length, outerRadius);
return bounds;
}*/
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox(0, length, outerRadius);
}
/**

View File

@ -17,6 +17,11 @@ 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);

View File

@ -25,6 +25,7 @@ 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;
@ -121,12 +122,57 @@ public class ComponentRenderer {
} else if ( c instanceof ParallelStage ) {
} else if ( c instanceof PodSet ) {
} else {
renderOther(gl, c);
renderBoundingBox(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()) {
@ -137,7 +183,7 @@ public class ComponentRenderer {
}
gl.glEnd();
}
*/
private void renderTransition(GL2 gl, Transition t, Surface which) {
if (which == Surface.OUTSIDE || which == Surface.INSIDE) {