started fleshing out RailButton class

This commit is contained in:
Daniel_M_Williams 2015-11-21 15:07:17 -05:00
parent d43381d70c
commit f1b89d2bb3

View File

@ -7,76 +7,144 @@ 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.BugException;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
/**
* WARNING! This class is stubbed out, partially implemented, but DEFINITELY not ready for use.
* WARNING: This class is only partially implemented. Recomend a bit of testing before you attach it to the GUI.
* @author widget (Daniel Williams)
*
*/
public abstract class RailButton extends ExternalComponent implements LineInstanceable {
public class RailButton extends ExternalComponent implements LineInstanceable {
private static final Translator trans = Application.getTranslator();
private double radius;
private double thickness;
// NOTE: Rail Button ARE NOT STANDARD -- They vary by manufacturer, and model.
// These presets have appropriate dimensions for each rail size, given the Rail Buttons contribute so little to flying properties.
public static final RailButton ROUND_1010 = make1010Button();
public static final RailButton ROUND_1515 = make1515Button();
/*
* Rail Button Dimensions (side view)
*
*
* <= outer dia =>
* v
* ^ [[[[[[]]]]]] lipThickness
* height >||||||<= inner dia ^
* v |||||| v
* [[[[[[]]]]]] standoff
* ================ ^
* (body)
*
*/
protected double outerDiameter;
protected double height;
protected double innerDiameter;
protected double thickness;
// Standoff is defined as the distance from the body surface to this components reference point
// Note: the reference point for Rail Button Components is in the center bottom of the button.
protected double standoff;
protected final static double MINIMUM_STANDOFF= 0.001;
private double radialDirection = 0;
private int instanceCount = 1;
private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0];
/* These are calculated when the component is first attached to any Rocket */
private double shiftY, shiftZ;
public RailButton() {
super(Position.MIDDLE);
radius = 0.01 / 2;
thickness = 0.001;
length = 0.03;
public RailButton( final double id, final double od, final double ht ) {
this( od, id, ht, ht/4, ht/4);
}
// @Override
// public double getOuterRadius() {
// return radius;
// }
//
// @Override
// public void setOuterRadius(double radius) {
// if (MathUtil.equals(this.radius, radius))
public RailButton( final double od, final double id, final double h, final double _thickness, final double _standoff ) {
super(Position.MIDDLE);
this.innerDiameter = id;
this.outerDiameter = od;
this.height = h-_standoff;
this.thickness = _thickness;
this.setStandoff( _standoff);
this.instanceSeparation = od*2;
}
private static final RailButton make1010Button(){
final double id = 0.008; // guess
final double od = 0.0097;
final double ht = 0.0097;
final double thickness = 0.002; // guess
final double standoff = 0.002; // guess
RailButton rb1010 = new RailButton( od, id, ht, thickness, standoff);
rb1010.setMassOverridden(true);
rb1010.setOverrideMass(0.0019);
return rb1010;
}
private static final RailButton make1515Button(){
final double id = 0.012; // guess
final double od = 0.016;
final double ht = 0.0173;
final double thickness = 0.0032; // guess
final double standoff = 0.0032; // guess
RailButton rb1010 = new RailButton( od, id, ht, thickness, standoff);
rb1010.setMassOverridden(true);
rb1010.setOverrideMass(0.0077);
return rb1010;
}
public double getStandoff(){
return this.standoff;
}
public double getOuterRadius() {
return this.outerDiameter;
}
public double getInnerDiameter() {
return this.innerDiameter;
}
public double getTotalHeight() {
return this.height+this.standoff;
}
public double getThickness() {
return this.thickness;
}
public void setStandoff( final double newStandoff){
this.standoff = Math.max( newStandoff, RailButton.MINIMUM_STANDOFF );
}
public void setInnerDiameter( final double newID ){
this.innerDiameter = newID;
}
public void setOuterDiameter( final double newOD ){
this.outerDiameter = newOD;
}
public void setTotalHeight( final double newHeight ) {
this.height = newHeight-this.standoff;
}
public void setThickness( final double newThickness ) {
this.thickness = newThickness;
}
// public void setThickness(double thickness) {
// if (MathUtil.equals(this.thickness, thickness))
// return;
// this.radius = radius;
// this.thickness = Math.min(this.thickness, this.radius);
// this.thickness = MathUtil.clamp(thickness, 0, radius);
// clearPreset();
// fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
// }
// @Override
// public double getInnerRadius() {
// return radius - thickness;
// }
//
// @Override
// public void setInnerRadius(double innerRadius) {
// setOuterRadius(innerRadius + thickness);
// }
//
// @Override
// public double getThickness() {
// return thickness;
// }
public void setThickness(double thickness) {
if (MathUtil.equals(this.thickness, thickness))
return;
this.thickness = MathUtil.clamp(thickness, 0, radius);
clearPreset();
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
public double getRadialDirection() {
return radialDirection;
@ -91,33 +159,18 @@ public abstract class RailButton extends ExternalComponent implements LineInstan
}
public void setLength(double length) {
if (MathUtil.equals(this.length, length))
return;
this.length = length;
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public boolean isAfter() {
return false;
}
@Override
public void setRelativePosition(RocketComponent.Position position) {
super.setRelativePosition(position);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@Override
public void setPositionValue(double value) {
super.setPositionValue(value);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
//
// @Override
// public void setPositionValue(double value) {
// super.setPositionValue(value);
// fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
// }
@Override
public Coordinate[] getInstanceOffsets(){
@ -131,22 +184,22 @@ public abstract class RailButton extends ExternalComponent implements LineInstan
return toReturn;
}
@Override
protected void loadFromPreset(ComponentPreset preset) {
if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
double outerDiameter = preset.get(ComponentPreset.OUTER_DIAMETER);
this.radius = outerDiameter / 2.0;
if (preset.has(ComponentPreset.INNER_DIAMETER)) {
double innerDiameter = preset.get(ComponentPreset.INNER_DIAMETER);
this.thickness = (outerDiameter - innerDiameter) / 2.0;
}
}
super.loadFromPreset(preset);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
// @Override
// protected void loadFromPreset(ComponentPreset preset) {
// if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
// double outerDiameter = preset.get(ComponentPreset.OUTER_DIAMETER);
// this.radius = outerDiameter / 2.0;
// if (preset.has(ComponentPreset.INNER_DIAMETER)) {
// double innerDiameter = preset.get(ComponentPreset.INNER_DIAMETER);
// this.thickness = (outerDiameter - innerDiameter) / 2.0;
// }
// }
//
// super.loadFromPreset(preset);
//
// fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
// }
//
@Override
public Type getPresetType() {
@ -170,55 +223,99 @@ public abstract class RailButton extends ExternalComponent implements LineInstan
public void componentChanged(ComponentChangeEvent e) {
super.componentChanged(e);
/*
* shiftY and shiftZ must be computed here since calculating them
* in shiftCoordinates() would cause an infinite loop due to .toRelative
*/
RocketComponent body;
double parentRadius;
for (body = this.getParent(); body != null; body = body.getParent()) {
if (body instanceof SymmetricComponent)
break;
}
if (body == null) {
parentRadius = 0;
} else {
SymmetricComponent s = (SymmetricComponent) body;
double x1, x2;
x1 = this.toRelative(Coordinate.NUL, body)[0].x;
x2 = this.toRelative(new Coordinate(length, 0, 0), body)[0].x;
x1 = MathUtil.clamp(x1, 0, body.getLength());
x2 = MathUtil.clamp(x2, 0, body.getLength());
parentRadius = Math.max(s.getRadius(x1), s.getRadius(x2));
}
shiftY = Math.cos(radialDirection) * (parentRadius + radius);
shiftZ = Math.sin(radialDirection) * (parentRadius + radius);
// /*
// * shiftY and shiftZ must be computed here since calculating them
// * in shiftCoordinates() would cause an infinite loop due to .toRelative
// */
// RocketComponent body;
// double parentRadius;
//
// for (body = this.getParent(); body != null; body = body.getParent()) {
// if (body instanceof SymmetricComponent)
// break;
// }
//
// if (body == null) {
// parentRadius = 0;
// } else {
// SymmetricComponent s = (SymmetricComponent) body;
// double x1, x2;
// x1 = this.toRelative(Coordinate.NUL, body)[0].x;
// x2 = this.toRelative(new Coordinate(length, 0, 0), body)[0].x;
// x1 = MathUtil.clamp(x1, 0, body.getLength());
// x2 = MathUtil.clamp(x2, 0, body.getLength());
// parentRadius = Math.max(s.getRadius(x1), s.getRadius(x2));
// }
//
// shiftY = Math.cos(radialDirection) * (parentRadius + radius);
// shiftZ = Math.sin(radialDirection) * (parentRadius + radius);
//
// System.out.println("Computed shift: y="+shiftY+" z="+shiftZ);
}
@Override
public double getComponentVolume() {
return length * Math.PI * (MathUtil.pow2(radius) - MathUtil.pow2(radius - thickness));
final double volOuter = Math.PI*Math.pow( outerDiameter/2, 2)*thickness;
final double volInner = Math.PI*Math.pow( innerDiameter/2, 2)*(height - thickness - standoff);
final double volStandoff = Math.PI*Math.pow( outerDiameter/2, 2)*standoff;
return (volOuter+
volInner+
volStandoff);
}
@Override
public double getInstanceSeparation(){
return this.instanceSeparation;
}
@Override
public void setInstanceSeparation(final double _separation){
this.instanceSeparation = _separation;
}
@Override
public void setInstanceCount( final int newCount ){
if( 0 < newCount ){
this.instanceCount = newCount;
}
}
@Override
public int getInstanceCount(){
return this.instanceCount;
}
@Override
public String getPatternName(){
return (this.getInstanceCount() + "-Line");
}
@Override
public Collection<Coordinate> getComponentBounds() {
ArrayList<Coordinate> set = new ArrayList<Coordinate>();
addBound(set, 0, radius);
addBound(set, length, radius);
return set;
}
@Override
public Coordinate getComponentCG() {
return new Coordinate(length / 2, 0, 0, getComponentMass());
// Math.PI and density are assumed constant through calcualtion, and thus may be factored out.
final double volumeInner = Math.pow( innerDiameter/2, 2)*(height - thickness - standoff);
final double volumeOuter = Math.pow( outerDiameter/2, 2)*thickness;
final double volumeStandoff = Math.pow( outerDiameter/2, 2)*standoff;
final double totalVolume = volumeInner + volumeOuter + volumeStandoff;
final double heightCM = (volumeInner*( this.height - this.thickness/2) + volumeOuter*( this.height-this.thickness)/2 - volumeStandoff*(this.standoff/2))/totalVolume;
if( heightCM > this.height ){
throw new BugException(" bug found while computing the CG of a RailButton: "+this.getName()+"\n height of CG: "+heightCM);
}
final double CMy = Math.cos(this.radialDirection)*heightCM;
final double CMz = Math.sin(this.radialDirection)*heightCM;
return new Coordinate( 0, CMy, CMz, getComponentMass());
}
@Override
@ -252,33 +349,4 @@ public abstract class RailButton extends ExternalComponent implements LineInstan
return false;
}
@Override
public double getInstanceSeparation(){
return this.instanceSeparation;
}
@Override
public void setInstanceSeparation(final double _separation){
this.instanceSeparation = _separation;
}
@Override
public void setInstanceCount( final int newCount ){
if( 0 < newCount ){
this.instanceCount = newCount;
}
}
@Override
public int getInstanceCount(){
return this.instanceCount;
}
@Override
public String getPatternName(){
return (this.getInstanceCount() + "-Line");
}
}