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),
|
||||
"auto",
|
||||
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
|
||||
|
||||
|
@ -7,14 +7,17 @@ import java.util.List;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
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.AxialPositionable;
|
||||
import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
|
||||
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;
|
||||
|
||||
public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
||||
public class TubeFinSet extends ExternalComponent implements AxialPositionable, BoxBounded, RingInstanceable {
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
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 double outerRadius = DEFAULT_RADIUS;
|
||||
protected double thickness = 0.002;
|
||||
|
||||
protected int fins = 6;
|
||||
private AngleMethod angleMethod = AngleMethod.FIXED;
|
||||
protected RadiusMethod radiusMethod = RadiusMethod.RELATIVE;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
@ -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
|
||||
*/
|
||||
@ -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.
|
||||
* This method sets the automatic radius off.
|
||||
*
|
||||
@ -168,7 +173,6 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
||||
return fins;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAfter(){
|
||||
return false;
|
||||
@ -195,7 +199,7 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
||||
* @return The base rotation amount.
|
||||
*/
|
||||
public double getBaseRotation() {
|
||||
return rotation;
|
||||
return getAngleOffset();
|
||||
}
|
||||
|
||||
public double getFinRotation() {
|
||||
@ -207,12 +211,7 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
||||
* @param r The base rotation amount.
|
||||
*/
|
||||
public void setBaseRotation(double r) {
|
||||
r = MathUtil.reduce180(r);
|
||||
if (MathUtil.equals(r, rotation))
|
||||
return;
|
||||
rotation = r;
|
||||
baseRotation = Transformation.rotate_x(rotation);
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
setAngleOffset(r);
|
||||
}
|
||||
|
||||
public Transformation getBaseRotationTransformation() {
|
||||
@ -316,6 +315,14 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
||||
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
|
||||
* 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;
|
||||
|
||||
s = this.getParent();
|
||||
double x = this.getPosition().x;
|
||||
while (s != null) {
|
||||
if (s instanceof SymmetricComponent) {
|
||||
double x = this.getPosition().x;
|
||||
return ((SymmetricComponent) s).getRadius(x);
|
||||
}
|
||||
s = s.getParent();
|
||||
@ -337,4 +344,113 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
|
||||
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) {
|
||||
gl.glPushMatrix();
|
||||
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
|
||||
System.out.println(fs.getBaseRotation());
|
||||
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);
|
||||
gl.glTranslated(0, fs.getOuterRadius(), 0);
|
||||
renderTube(gl, which, fs.getOuterRadius(), fs.getInnerRadius(), fs.getLength());
|
||||
gl.glPopMatrix();
|
||||
gl.glRotated(360.0 / fs.getFinCount(), 1, 0, 0);
|
||||
}
|
||||
gl.glPopMatrix();
|
||||
}
|
||||
|
||||
private void renderMassObject(GL2 gl, MassObject o) {
|
||||
|
@ -10,72 +10,55 @@ import net.sf.openrocket.util.Coordinate;
|
||||
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 {
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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();
|
||||
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)));
|
||||
return RocketComponentShape.toArray(shapes, component);
|
||||
}
|
||||
|
||||
//start = baseRotation.transform(start);
|
||||
|
||||
Shape[] s = new Shape[fins];
|
||||
for (int i=0; i<fins; i++) {
|
||||
s[i] = new Rectangle2D.Double(start[0].x,(start[0].y-outerRadius),length,2*outerRadius);
|
||||
start = finRotation.transform(start);
|
||||
}
|
||||
return RocketComponentShape.toArray(s, component);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of RocketComponentShapes that describe the shape of
|
||||
* the TubeFinSet when viewed from the rear or the rocket. TubeFins will
|
||||
* appear as an Ellipse/Circle from the back 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 back
|
||||
*/
|
||||
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();
|
||||
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)));
|
||||
return RocketComponentShape.toArray(shapes, component);
|
||||
}
|
||||
|
||||
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