Merge pull request #621 from wolsen/fix-tube-fin-display
Fix TubeFinSet 2D rendering
This commit is contained in:
commit
6b609809e0
@ -294,6 +294,10 @@ class DocumentConfig {
|
|||||||
Reflection.findMethod(TubeFinSet.class, "setOuterRadius", double.class),
|
Reflection.findMethod(TubeFinSet.class, "setOuterRadius", double.class),
|
||||||
"auto",
|
"auto",
|
||||||
Reflection.findMethod(TubeFinSet.class, "setOuterRadiusAutomatic", boolean.class)));
|
Reflection.findMethod(TubeFinSet.class, "setOuterRadiusAutomatic", boolean.class)));
|
||||||
|
setters.put("TubeFinSet:instancecount", new IntSetter(
|
||||||
|
Reflection.findMethod(TubeFinSet.class, "setInstanceCount", int.class)));
|
||||||
|
setters.put("TubeFinSet:angleoffset", new AnglePositionSetter() );
|
||||||
|
setters.put("TubeFinSet:radiusoffset", new RadiusPositionSetter() );
|
||||||
|
|
||||||
// InternalComponent - nothing
|
// InternalComponent - nothing
|
||||||
|
|
||||||
|
@ -7,14 +7,17 @@ import java.util.List;
|
|||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.preset.ComponentPreset;
|
import net.sf.openrocket.preset.ComponentPreset;
|
||||||
import net.sf.openrocket.preset.ComponentPreset.Type;
|
import net.sf.openrocket.preset.ComponentPreset.Type;
|
||||||
|
import net.sf.openrocket.rocketcomponent.position.AngleMethod;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||||
import net.sf.openrocket.rocketcomponent.position.AxialPositionable;
|
import net.sf.openrocket.rocketcomponent.position.AxialPositionable;
|
||||||
|
import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
|
import net.sf.openrocket.util.BoundingBox;
|
||||||
import net.sf.openrocket.util.Coordinate;
|
import net.sf.openrocket.util.Coordinate;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
import net.sf.openrocket.util.Transformation;
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
public class TubeFinSet extends ExternalComponent implements AxialPositionable, BoxBounded, RingInstanceable {
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
private final static double DEFAULT_RADIUS = 0.025;
|
private final static double DEFAULT_RADIUS = 0.025;
|
||||||
@ -22,18 +25,20 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
|||||||
private boolean autoRadius = true; // Radius chosen automatically based on parent component
|
private boolean autoRadius = true; // Radius chosen automatically based on parent component
|
||||||
private double outerRadius = DEFAULT_RADIUS;
|
private double outerRadius = DEFAULT_RADIUS;
|
||||||
protected double thickness = 0.002;
|
protected double thickness = 0.002;
|
||||||
|
private AngleMethod angleMethod = AngleMethod.FIXED;
|
||||||
protected int fins = 6;
|
protected RadiusMethod radiusMethod = RadiusMethod.RELATIVE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotation angle of the first fin. Zero corresponds to the positive y-axis.
|
* Rotation angle of the first fin. Zero corresponds to the positive y-axis.
|
||||||
*/
|
*/
|
||||||
protected double rotation = 0;
|
private double firstFinOffsetRadians = 0;
|
||||||
|
|
||||||
|
protected int fins = 6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotation about the x-axis by angle this.rotation.
|
* Rotation about the x-axis by angle this.rotation.
|
||||||
*/
|
*/
|
||||||
protected Transformation baseRotation = Transformation.rotate_x(rotation);
|
protected Transformation baseRotation = Transformation.IDENTITY; // initially, rotate by 0 radians.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotation about the x-axis by 2*PI/fins.
|
* Rotation about the x-axis by 2*PI/fins.
|
||||||
@ -64,7 +69,7 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the outer radius of the body tube.
|
* Return the outer radius of the tube-fin
|
||||||
*
|
*
|
||||||
* @return the outside radius of the tube
|
* @return the outside radius of the tube
|
||||||
*/
|
*/
|
||||||
@ -100,7 +105,7 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the outer radius of the body tube. If the radius is less than the wall thickness,
|
* Set the outer radius of the tube-fin. If the radius is less than the wall thickness,
|
||||||
* the wall thickness is decreased accordingly of the value of the radius.
|
* the wall thickness is decreased accordingly of the value of the radius.
|
||||||
* This method sets the automatic radius off.
|
* This method sets the automatic radius off.
|
||||||
*
|
*
|
||||||
@ -168,7 +173,6 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
|||||||
return fins;
|
return fins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAfter(){
|
public boolean isAfter(){
|
||||||
return false;
|
return false;
|
||||||
@ -195,7 +199,7 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
|||||||
* @return The base rotation amount.
|
* @return The base rotation amount.
|
||||||
*/
|
*/
|
||||||
public double getBaseRotation() {
|
public double getBaseRotation() {
|
||||||
return rotation;
|
return getAngleOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getFinRotation() {
|
public double getFinRotation() {
|
||||||
@ -207,12 +211,7 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
|||||||
* @param r The base rotation amount.
|
* @param r The base rotation amount.
|
||||||
*/
|
*/
|
||||||
public void setBaseRotation(double r) {
|
public void setBaseRotation(double r) {
|
||||||
r = MathUtil.reduce180(r);
|
setAngleOffset(r);
|
||||||
if (MathUtil.equals(r, rotation))
|
|
||||||
return;
|
|
||||||
rotation = r;
|
|
||||||
baseRotation = Transformation.rotate_x(rotation);
|
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transformation getBaseRotationTransformation() {
|
public Transformation getBaseRotationTransformation() {
|
||||||
@ -316,6 +315,14 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
|||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BoundingBox getInstanceBoundingBox() {
|
||||||
|
BoundingBox box = new BoundingBox();
|
||||||
|
box.update(new Coordinate(0, -outerRadius, -outerRadius));
|
||||||
|
box.update(new Coordinate(length, outerRadius, outerRadius));
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the radius of the BodyComponent the fin set is situated on. Currently
|
* Return the radius of the BodyComponent the fin set is situated on. Currently
|
||||||
* only supports SymmetricComponents and returns the radius at the starting point of the
|
* only supports SymmetricComponents and returns the radius at the starting point of the
|
||||||
@ -327,9 +334,9 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
|||||||
RocketComponent s;
|
RocketComponent s;
|
||||||
|
|
||||||
s = this.getParent();
|
s = this.getParent();
|
||||||
|
double x = this.getPosition().x;
|
||||||
while (s != null) {
|
while (s != null) {
|
||||||
if (s instanceof SymmetricComponent) {
|
if (s instanceof SymmetricComponent) {
|
||||||
double x = this.getPosition().x;
|
|
||||||
return ((SymmetricComponent) s).getRadius(x);
|
return ((SymmetricComponent) s).getRadius(x);
|
||||||
}
|
}
|
||||||
s = s.getParent();
|
s = s.getParent();
|
||||||
@ -337,4 +344,113 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInstanceCount() {
|
||||||
|
return getFinCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInstanceCount(int newCount) {
|
||||||
|
setFinCount(newCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPatternName() {
|
||||||
|
return (this.getInstanceCount() + "-tubefin-ring");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getBoundingRadius() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRadius(RadiusMethod method, double radius) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAngleOffset(double angleRadians) {
|
||||||
|
final double reducedAngle = MathUtil.reducePI(angleRadians);
|
||||||
|
if (MathUtil.equals(reducedAngle, firstFinOffsetRadians))
|
||||||
|
return;
|
||||||
|
firstFinOffsetRadians = reducedAngle;
|
||||||
|
|
||||||
|
if (MathUtil.equals(this.firstFinOffsetRadians, 0)) {
|
||||||
|
baseRotation = Transformation.IDENTITY;
|
||||||
|
} else {
|
||||||
|
baseRotation = Transformation.rotate_x(firstFinOffsetRadians);
|
||||||
|
}
|
||||||
|
|
||||||
|
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AngleMethod getAngleMethod() {
|
||||||
|
return this.angleMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getAngleOffset() {
|
||||||
|
return this.firstFinOffsetRadians;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAngleMethod(AngleMethod newAngleMethod) {
|
||||||
|
mutex.verify();
|
||||||
|
this.angleMethod = newAngleMethod;
|
||||||
|
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getInstanceAngleIncrement() {
|
||||||
|
return ( 2*Math.PI / getFinCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] getInstanceAngles() {
|
||||||
|
final double angleIncrementRadians = getInstanceAngleIncrement();
|
||||||
|
|
||||||
|
double[] result = new double[getFinCount()];
|
||||||
|
for (int finNumber=0; finNumber < getFinCount(); ++finNumber) {
|
||||||
|
double additionalOffset = angleIncrementRadians * finNumber;
|
||||||
|
result[finNumber] = MathUtil.reduce2PI(firstFinOffsetRadians + additionalOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Coordinate[] getInstanceOffsets() {
|
||||||
|
checkState();
|
||||||
|
|
||||||
|
final double bodyRadius = this.getBodyRadius();
|
||||||
|
|
||||||
|
// already includes the base rotation
|
||||||
|
final double[] angles = getInstanceAngles();
|
||||||
|
|
||||||
|
Coordinate[] toReturn = new Coordinate[this.fins];
|
||||||
|
for (int instanceNumber = 0; instanceNumber < this.fins; instanceNumber++) {
|
||||||
|
final Coordinate raw = new Coordinate( 0, bodyRadius, 0);
|
||||||
|
final Coordinate rotated = Transformation.getAxialRotation(angles[instanceNumber]).transform(raw);
|
||||||
|
toReturn[instanceNumber] = rotated;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRadiusOffset(double radius) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRadiusMethod(RadiusMethod method) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -317,16 +317,9 @@ public class ComponentRenderer {
|
|||||||
private void renderTubeFins(GL2 gl, TubeFinSet fs, Surface which) {
|
private void renderTubeFins(GL2 gl, TubeFinSet fs, Surface which) {
|
||||||
gl.glPushMatrix();
|
gl.glPushMatrix();
|
||||||
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
|
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
|
||||||
System.out.println(fs.getBaseRotation());
|
gl.glTranslated(0, fs.getOuterRadius(), 0);
|
||||||
gl.glRotated(fs.getBaseRotation() * (180.0 / Math.PI), 1, 0, 0);
|
|
||||||
for( int i = 0; i< fs.getFinCount(); i++ ) {
|
|
||||||
gl.glPushMatrix();
|
|
||||||
gl.glTranslated(0, fs.getOuterRadius() + fs.getBodyRadius(), 0);
|
|
||||||
renderTube(gl, which, fs.getOuterRadius(), fs.getInnerRadius(), fs.getLength());
|
renderTube(gl, which, fs.getOuterRadius(), fs.getInnerRadius(), fs.getLength());
|
||||||
gl.glPopMatrix();
|
gl.glPopMatrix();
|
||||||
gl.glRotated(360.0 / fs.getFinCount(), 1, 0, 0);
|
|
||||||
}
|
|
||||||
gl.glPopMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderMassObject(GL2 gl, MassObject o) {
|
private void renderMassObject(GL2 gl, MassObject o) {
|
||||||
|
@ -10,72 +10,55 @@ import net.sf.openrocket.util.Coordinate;
|
|||||||
import net.sf.openrocket.util.Transformation;
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The TubeFinSetShapes is used for retrieving shapes of the TubeFins on a
|
||||||
|
* Rocket from multiple view points. The returned shapes will be translated
|
||||||
|
* and transformed to the correct locations for rendering the rocket in the
|
||||||
|
* 2D view space.
|
||||||
|
*/
|
||||||
public class TubeFinSetShapes extends RocketComponentShape {
|
public class TubeFinSetShapes extends RocketComponentShape {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of RocketcomponentShapes that describe the shape of
|
||||||
|
* the TubeFinSet when viewed from the side of the rocket. TubeFins will
|
||||||
|
* appear as a Rectangle from the side view
|
||||||
|
*
|
||||||
|
* @param component the TubeFinSet to get the shapes for
|
||||||
|
* @param transformation the transformation to apply to the shapes
|
||||||
|
* @return an array of RocketComponentShapes that are used to draw the TubeFinSet from the side.
|
||||||
|
*/
|
||||||
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
|
||||||
|
final TubeFinSet finSet = (TubeFinSet) component;
|
||||||
|
final double outerRadius = finSet.getOuterRadius();
|
||||||
|
final double length = finSet.getLength();
|
||||||
|
final Coordinate location = transformation.transform(new Coordinate(0, outerRadius, 0));
|
||||||
|
|
||||||
TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
|
final Shape[] shapes = new Shape[] {
|
||||||
|
new Rectangle2D.Double(location.x, (location.y-outerRadius), length, 2*outerRadius)
|
||||||
|
};
|
||||||
|
|
||||||
int fins = finset.getFinCount();
|
return RocketComponentShape.toArray(shapes, component);
|
||||||
double length = finset.getLength();
|
|
||||||
double outerRadius = finset.getOuterRadius();
|
|
||||||
double bodyRadius = finset.getBodyRadius();
|
|
||||||
// old version - Oct, 19 2015
|
|
||||||
//Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
|
|
||||||
//instanceOffsets = component.shiftCoordinates(instanceOffsets);
|
|
||||||
|
|
||||||
// new version
|
|
||||||
Coordinate[] start = transformation.transform( component.getLocations());
|
|
||||||
|
|
||||||
Transformation baseRotation = finset.getBaseRotationTransformation();
|
|
||||||
Transformation finRotation = finset.getFinRotationTransformation();
|
|
||||||
|
|
||||||
// Translate & rotate the coordinates
|
|
||||||
for (int i=0; i<start.length; i++) {
|
|
||||||
start[i] = baseRotation.transform(transformation.transform(start[i].add(0,bodyRadius+outerRadius,0)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//start = baseRotation.transform(start);
|
/**
|
||||||
|
* Returns an array of RocketComponentShapes that describe the shape of
|
||||||
Shape[] s = new Shape[fins];
|
* the TubeFinSet when viewed from the rear or the rocket. TubeFins will
|
||||||
for (int i=0; i<fins; i++) {
|
* appear as an Ellipse/Circle from the back view.
|
||||||
s[i] = new Rectangle2D.Double(start[0].x,(start[0].y-outerRadius),length,2*outerRadius);
|
*
|
||||||
start = finRotation.transform(start);
|
* @param component the TubeFinSet to get the shapes for
|
||||||
}
|
* @param transformation the transformation to apply to the shapes
|
||||||
return RocketComponentShape.toArray(s, component);
|
* @return an array of RocketComponentShapes that are used to draw the
|
||||||
}
|
* TubeFinSet from the back
|
||||||
|
*/
|
||||||
|
|
||||||
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
|
||||||
|
final TubeFinSet finSet = (TubeFinSet) component;
|
||||||
|
final double outerRadius = finSet.getOuterRadius();
|
||||||
|
final Coordinate location = transformation.transform(new Coordinate(0, outerRadius, 0));
|
||||||
|
|
||||||
TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
|
final Shape[] shapes = new Shape[] {
|
||||||
|
new Ellipse2D.Double((location.z - outerRadius), (location.y - outerRadius), (2 * outerRadius), (2 * outerRadius))
|
||||||
|
};
|
||||||
|
|
||||||
int fins = finset.getFinCount();
|
return RocketComponentShape.toArray(shapes, component);
|
||||||
double outerradius = finset.getOuterRadius();
|
|
||||||
double bodyradius = finset.getBodyRadius();
|
|
||||||
|
|
||||||
// old version - Oct, 19 2015
|
|
||||||
//Coordinate[] instanceOffsets = new Coordinate[]{ transformation.transform( componentAbsoluteLocation )};
|
|
||||||
//instanceOffsets = component.shiftCoordinates(instanceOffsets);
|
|
||||||
|
|
||||||
// new version
|
|
||||||
Coordinate[] start = transformation.transform( component.getLocations());
|
|
||||||
|
|
||||||
Transformation baseRotation = finset.getBaseRotationTransformation();
|
|
||||||
Transformation finRotation = finset.getFinRotationTransformation();
|
|
||||||
|
|
||||||
// Translate & rotate the coordinates
|
|
||||||
for (int i=0; i<start.length; i++) {
|
|
||||||
start[i] = baseRotation.transform(transformation.transform(start[i].add(0,bodyradius+outerradius,0)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape[] s = new Shape[fins];
|
|
||||||
for (int i=0; i < fins; i++) {
|
|
||||||
s[i] = new Ellipse2D.Double((start[0].z-outerradius),(start[0].y-outerradius),2*outerradius,2*outerradius);
|
|
||||||
start = finRotation.transform(start);
|
|
||||||
}
|
|
||||||
return RocketComponentShape.toArray(s, component);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user