[fix] FreeformFinSet now displays correctly.

This commit is contained in:
Daniel_M_Williams 2018-09-30 09:33:59 -04:00
parent 166d358c14
commit 6793eaaa04
2 changed files with 64 additions and 104 deletions

View File

@ -6,133 +6,88 @@ import java.util.ArrayList;
import net.sf.openrocket.rocketcomponent.FinSet; import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
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 FinSetShapes extends RocketComponentShape { public class FinSetShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(RocketComponent component,
public static RocketComponentShape[] getShapesSide( Transformation transformation,
RocketComponent component, Coordinate instanceAbsoluteLocation ){
Transformation transformation, final FinSet finset = (FinSet) component;
Coordinate componentAbsoluteLocation) { // this supplied transformation includes:
FinSet finset = (FinSet)component; // - baseRotationTransformation
// - mount-radius transformtion
// - component-center offset transformation
// - component-instance offset transformation
/**
* this supplied location contains the *instance* location... but is expected to contain the *component* location. (?)
* also, this requires changing machinery beyond this class. :(
*/
final Transformation cantRotation = finset.getCantRotation();
final Transformation compositeTransform = cantRotation.applyTransformation( transformation);
int finCount = finset.getFinCount();
// TODO: MEDIUM: sloping radius
final double rFront = finset.getFinFront().y;
Transformation cantRotation = finset.getCantRotation();
Transformation baseRotation = new Transformation(finset.getBaseRotation(), 0, 0); // rotation about x-axis
Transformation radialTranslation = new Transformation( 0, rFront, 0);
Transformation finRotation = finset.getFinRotationTransformation();
Transformation compositeTransform = baseRotation
.applyTransformation( radialTranslation)
.applyTransformation( cantRotation)
.applyTransformation( transformation);
Coordinate finSetFront = componentAbsoluteLocation;
Coordinate finPoints[] = finset.getFinPoints(); Coordinate finPoints[] = finset.getFinPoints();
Coordinate tabPoints[] = finset.getTabPoints(); Coordinate tabPoints[] = finset.getTabPoints();
Coordinate basePoints[] = finset.getRootPoints(); Coordinate rootPoints[] = finset.getRootPoints();
// Translate & rotate points into place // Translate & rotate points into place
finPoints = compositeTransform.transform( finPoints ); finPoints = compositeTransform.transform( finPoints );
tabPoints = compositeTransform.transform( tabPoints); tabPoints = compositeTransform.transform( tabPoints);
basePoints = compositeTransform.transform( basePoints ); rootPoints = compositeTransform.transform( rootPoints );
// Generate shapes // Generate shapes
ArrayList<RocketComponentShape> shapeList = new ArrayList<>(); ArrayList<RocketComponentShape> shapeList = new ArrayList<>();
for (int finNum=0; finNum<finCount; finNum++) {
Coordinate curPoint; // Make fin polygon
shapeList.add(new RocketComponentShape(generatePath(instanceAbsoluteLocation, finPoints), finset));
// Make fin polygon
Path2D.Float finShape = new Path2D.Float();
for (int i=0; i<finPoints.length; i++) {
curPoint = finSetFront.add(finPoints[i]);
if (i==0)
finShape.moveTo(curPoint.x, curPoint.y);
else
finShape.lineTo(curPoint.x, curPoint.y);
}
shapeList.add( new RocketComponentShape( finShape, finset));
// draw fin-body intersection line // Make fin polygon
double angle_rad = finset.getBaseRotation() + ((double)finNum) / ((double)finCount) *2*Math.PI; shapeList.add(new RocketComponentShape(generatePath(instanceAbsoluteLocation, tabPoints), finset));
// only draw body-root intersection line if it's not hidden-- i.e. is not at {0,PI/2,PI,3/2*PI} angles
final boolean drawRoot= (0.05 < Math.abs( angle_rad % (Math.PI/2.0))); // Make fin polygon
boolean simpleRoot = finset.isRootStraight( ); shapeList.add(new RocketComponentShape(generatePath(instanceAbsoluteLocation, rootPoints), finset));
if( drawRoot){
if( simpleRoot){
// draws a straight-line connection from the end back to the start
finShape.closePath();
}else{
// this implies a curved fin-body intersection
// ... which is more complicated.
Path2D.Float rootShape = new Path2D.Float();
for (int i=0; i< basePoints.length; i++) {
curPoint = finSetFront.add( basePoints[i]);
if (i==0)
rootShape.moveTo(curPoint.x, curPoint.y);
else
rootShape.lineTo(curPoint.x, curPoint.y);
}
shapeList.add( new RocketComponentShape( rootShape, finset));
}
}
// Make tab polygon
Path2D.Float tabShape = new Path2D.Float();
if( 0 < tabPoints.length ){
for (int i=0; i<tabPoints.length; i++) {
curPoint = finSetFront.add(tabPoints[i]);
if (i==0)
tabShape.moveTo(curPoint.x, curPoint.y);
else
tabShape.lineTo(curPoint.x, curPoint.y);
}
// the fin tab / body surface line should lay on the fin-root line above
shapeList.add( new RocketComponentShape( tabShape, finset));
}
// Rotate fin, tab coordinates
finPoints = finRotation.transform(finPoints);
tabPoints = finRotation.transform(tabPoints);
basePoints = finRotation.transform( basePoints);
}
return shapeList.toArray(new RocketComponentShape[0]); return shapeList.toArray(new RocketComponentShape[0]);
} }
public static RocketComponentShape[] getShapesBack( public static RocketComponentShape[] getShapesBack(
RocketComponent component, RocketComponent component,
Transformation transformation, Transformation transformation,
Coordinate location) { Coordinate location) {
FinSet finset = (FinSet)component; FinSet finset = (FinSet) component;
Shape[] toReturn; Shape[] toReturn;
if (MathUtil.equals(finset.getCantAngle(),0)){ if (MathUtil.equals(finset.getCantAngle(), 0)) {
toReturn = uncantedShapesBack(finset, transformation, location); toReturn = uncantedShapesBack(finset, transformation, location);
}else{ } else {
toReturn = cantedShapesBack(finset, transformation, location); toReturn = cantedShapesBack(finset, transformation, location);
} }
return RocketComponentShape.toArray( toReturn, finset); return RocketComponentShape.toArray(toReturn, finset);
}
private static Path2D.Float generatePath(final Coordinate c0, final Coordinate[] points){
Path2D.Float finShape = new Path2D.Float();
for( int i = 0; i < points.length; i++){
Coordinate curPoint = c0.add(points[i]);
if (i == 0)
finShape.moveTo(curPoint.x, curPoint.y);
else
finShape.lineTo(curPoint.x, curPoint.y);
}
return finShape;
} }
private static Shape[] uncantedShapesBack(FinSet finset, private static Shape[] uncantedShapesBack(FinSet finset,
Transformation transformation, Transformation transformation,

View File

@ -29,6 +29,7 @@ import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.motor.Motor; import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorConfiguration; import net.sf.openrocket.motor.MotorConfiguration;
import net.sf.openrocket.rocketcomponent.ComponentAssembly; import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration; import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Rocket;
@ -360,13 +361,17 @@ public class RocketFigure extends AbstractScaleFigure {
Coordinate currentLocation = parentLocation.add( instanceLocations[index] ); Coordinate currentLocation = parentLocation.add( instanceLocations[index] );
// System.err.println(String.format("@%s: %s -- inst: [%d/%d]", comp.getClass().getSimpleName(), comp.getName(), index+1, instanceCount)); // if(FinSet.class.isAssignableFrom(comp.getClass())) {
// System.err.println(String.format(" -- stage: %d, active: %b, config: (%d) %s", comp.getStageNumber(), this.getConfiguration().isComponentActive(comp), this.getConfiguration().instanceNumber, this.getConfiguration().getId())); // System.err.println(String.format("@%s: %s -- inst: [%d/%d]", comp.getClass().getSimpleName(), comp.getName(), index+1, instanceCount));
// System.err.println(String.format(" -- %s + %s = %s", parentLocation.toString(), instanceLocations[index].toString(), currentLocation.toString())); //
// if( 0.00001 < Math.abs( currentAngle )) { // // FlightConfiguration config = this.rocket.getSelectedConfiguration();
// System.err.println(String.format(" -- at: %6.4f radians", currentAngle)); // // System.err.println(String.format(" -- stage: %d, active: %b, config: (%d) %s", comp.getStageNumber(), config.isComponentActive(comp), config.instanceNumber, config.getId()));
// } // System.err.println(String.format(" -- %s + %s = %s", parentLocation.toString(), instanceLocations[index].toString(), currentLocation.toString()));
// if( 0.00001 < Math.abs( currentAngle )) {
// System.err.println(String.format(" -- at: %6.4f radians", currentAngle));
// }
// }
// generate shape for this component, if active // generate shape for this component, if active
if( this.rocket.getSelectedConfiguration().isComponentActive( comp )){ if( this.rocket.getSelectedConfiguration().isComponentActive( comp )){
allShapes = addThisShape( allShapes, this.currentViewType, comp, currentLocation, currentTransform); allShapes = addThisShape( allShapes, this.currentViewType, comp, currentLocation, currentTransform);