[refactor] switched 2D figure rendering over to new, simpler system

This commit is contained in:
Daniel_M_Williams 2019-01-20 14:46:57 -05:00
parent 0711cb785b
commit 577b09c4e9
17 changed files with 180 additions and 284 deletions

View File

@ -58,7 +58,7 @@ public class PrintableNoseCone extends AbstractPrintable<NoseCone> {
*/
@Override
protected void draw(Graphics2D g2) {
RocketComponentShape[] compShapes = TransitionShapes.getShapesSide(target, Transformation.rotate_x(0d), new Coordinate(0,0,0), PrintUnit.METERS.toPoints(1));
RocketComponentShape[] compShapes = TransitionShapes.getShapesSide(target, Transformation.IDENTITY, PrintUnit.METERS.toPoints(1));
if (compShapes != null && compShapes.length > 0) {
Rectangle r = compShapes[0].shape.getBounds();

View File

@ -4,15 +4,12 @@ import java.awt.Shape;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
public class BodyTubeShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation){
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
BodyTube tube = (BodyTube)component;
@ -20,22 +17,19 @@ public class BodyTubeShapes extends RocketComponentShape {
double radius = tube.getOuterRadius();
Shape[] s = new Shape[1];
s[0] = TubeShapes.getShapesSide( transformation, componentAbsoluteLocation, length, radius );
s[0] = TubeShapes.getShapesSide( transformation, length, radius );
return RocketComponentShape.toArray(s, component);
}
public static RocketComponentShape[] getShapesBack(
RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
BodyTube tube = (BodyTube)component;
double radius = tube.getOuterRadius();
Shape[] s = new Shape[1];
s[0] = TubeShapes.getShapesBack( transformation, componentAbsoluteLocation, radius);
s[0] = TubeShapes.getShapesBack( transformation, radius);
return RocketComponentShape.toArray(s, component);
}

View File

@ -6,7 +6,6 @@ import java.util.ArrayList;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.Transformation;
@ -15,11 +14,10 @@ import net.sf.openrocket.util.Transformation;
public class FinSetShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(RocketComponent component,
Transformation transformation,
Coordinate instanceAbsoluteLocation ){
public static RocketComponentShape[] getShapesSide( final RocketComponent component,
final Transformation transformation){
final FinSet finset = (FinSet) component;
// this supplied transformation includes:
// - baseRotationTransformation
// - mount-radius transformtion
@ -47,40 +45,37 @@ public class FinSetShapes extends RocketComponentShape {
ArrayList<RocketComponentShape> shapeList = new ArrayList<>();
// Make fin polygon
shapeList.add(new RocketComponentShape(generatePath(instanceAbsoluteLocation, finPoints), finset));
shapeList.add(new RocketComponentShape(generatePath(finPoints), finset));
// Make fin polygon
shapeList.add(new RocketComponentShape(generatePath(instanceAbsoluteLocation, tabPoints), finset));
shapeList.add(new RocketComponentShape(generatePath(tabPoints), finset));
// Make fin polygon
shapeList.add(new RocketComponentShape(generatePath(instanceAbsoluteLocation, rootPoints), finset));
shapeList.add(new RocketComponentShape(generatePath(rootPoints), finset));
return shapeList.toArray(new RocketComponentShape[0]);
}
public static RocketComponentShape[] getShapesBack(
RocketComponent component,
Transformation transformation,
Coordinate location) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
FinSet finset = (FinSet) component;
Shape[] toReturn;
if (MathUtil.equals(finset.getCantAngle(), 0)) {
toReturn = uncantedShapesBack(finset, transformation, location);
toReturn = uncantedShapesBack(finset, transformation);
} else {
toReturn = cantedShapesBack(finset, transformation, location);
toReturn = cantedShapesBack(finset, transformation);
}
return RocketComponentShape.toArray(toReturn, finset);
}
private static Path2D.Float generatePath(final Coordinate c0, final Coordinate[] points){
private static Path2D.Float generatePath(final Coordinate[] points){
Path2D.Float finShape = new Path2D.Float();
for( int i = 0; i < points.length; i++){
Coordinate curPoint = c0.add(points[i]);
Coordinate curPoint = points[i];
if (i == 0)
finShape.moveTo(curPoint.x, curPoint.y);
else
@ -90,8 +85,7 @@ public class FinSetShapes extends RocketComponentShape {
}
private static Shape[] uncantedShapesBack(FinSet finset,
Transformation transformation,
Coordinate finFront) {
Transformation transformation) {
double thickness = finset.getThickness();
double height = finset.getSpan();
@ -110,13 +104,13 @@ public class FinSetShapes extends RocketComponentShape {
Coordinate a;
Path2D.Double p = new Path2D.Double();
a = finFront.add( c[0] );
a = c[0];
p.moveTo(a.z, a.y);
a = finFront.add( c[1] );
a = c[1];
p.lineTo(a.z, a.y);
a = finFront.add( c[2] );
a = c[2];
p.lineTo(a.z, a.y);
a = finFront.add( c[3] );
a = c[3];
p.lineTo(a.z, a.y);
p.closePath();
@ -126,8 +120,7 @@ public class FinSetShapes extends RocketComponentShape {
// TODO: LOW: Jagged shapes from back draw incorrectly.
private static Shape[] cantedShapesBack(FinSet finset,
Transformation transformation,
Coordinate location) {
Transformation transformation) {
int i;
int fins = finset.getFinCount();
double thickness = finset.getThickness();
@ -179,15 +172,15 @@ public class FinSetShapes extends RocketComponentShape {
s = new Shape[fins*2];
for (int fin=0; fin<fins; fin++) {
s[2*fin] = makePolygonBack(sidePoints,finset,transformation, location);
s[2*fin+1] = makePolygonBack(backPoints,finset,transformation, location);
s[2*fin] = makePolygonBack(sidePoints,finset,transformation);
s[2*fin+1] = makePolygonBack(backPoints,finset,transformation);
}
} else {
s = new Shape[fins];
for (int fin=0; fin<fins; fin++) {
s[fin] = makePolygonBack(sidePoints,finset,transformation, location);
s[fin] = makePolygonBack(sidePoints,finset,transformation);
}
}
@ -195,11 +188,11 @@ public class FinSetShapes extends RocketComponentShape {
return s;
}
private static Shape makePolygonBack(Coordinate[] array, FinSet finset,
Transformation t, Coordinate location) {
private static Shape makePolygonBack(Coordinate[] array, FinSet finset, final Transformation t) {
Path2D.Float p;
Coordinate compCenter = location;
Coordinate compCenter = t.transform(Coordinate.ZERO);
// Make polygon
p = new Path2D.Float();
for (int i=0; i < array.length; i++) {

View File

@ -10,32 +10,26 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
public class LaunchLugShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
RocketComponent component,
Transformation transformation,
Coordinate instanceAbsoluteLocation) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
LaunchLug lug = (LaunchLug)component;
double length = lug.getLength();
double radius = lug.getOuterRadius();
Shape[] s = new Shape[]{
TubeShapes.getShapesSide( transformation, instanceAbsoluteLocation, length, radius )
TubeShapes.getShapesSide( transformation, length, radius )
};
return RocketComponentShape.toArray(s, component);
}
public static RocketComponentShape[] getShapesBack(
RocketComponent component,
Transformation transformation,
Coordinate instanceAbsoluteLocation) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
LaunchLug lug = (LaunchLug)component;
double radius = lug.getOuterRadius();
Shape[] s = new Shape[]{TubeShapes.getShapesBack( transformation, instanceAbsoluteLocation, radius)};
Shape[] s = new Shape[]{TubeShapes.getShapesBack( transformation, radius)};
return RocketComponentShape.toArray(s, component);
}

View File

@ -8,6 +8,9 @@ import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.util.Random;
import net.sf.openrocket.rocketcomponent.MassComponent;
import net.sf.openrocket.rocketcomponent.MassObject;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.Transformation;
@ -15,22 +18,19 @@ import net.sf.openrocket.util.Transformation;
public class MassComponentShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
net.sf.openrocket.rocketcomponent.MassComponent.MassComponentType type = ((net.sf.openrocket.rocketcomponent.MassComponent)component).getMassComponentType();
MassComponent.MassComponentType type = ((MassComponent)component).getMassComponentType();
double length = tube.getLength();
double radius = tube.getRadius();
double arc = Math.min(length, 2*radius) * 0.7;
Coordinate start = transformation.transform( componentAbsoluteLocation);
Shape[] s = new Shape[1];
s[0] = new RoundRectangle2D.Double(start.x, (start.y-radius), length, 2*radius, arc, arc);
final Coordinate start = transformation.transform(Coordinate.ZERO);
Shape[] s = {new RoundRectangle2D.Double(start.x, (start.y-radius), length, 2*radius, arc, arc)};
switch (type) {
case ALTIMETER:
@ -61,21 +61,16 @@ public class MassComponentShapes extends RocketComponentShape {
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
double or = tube.getRadius();
Coordinate[] start = new Coordinate[]{transformation.transform( componentAbsoluteLocation )};
Shape[] s = new Shape[start.length];
for (int i=0; i < start.length; i++) {
s[i] = new Ellipse2D.Double((start[i].z-or),(start[i].y-or),2*or,2*or);
}
final Coordinate start = transformation.transform(Coordinate.ZERO);
Shape[] s = {new Ellipse2D.Double((start.z-or),(start.y-or),2*or,2*or)};
return RocketComponentShape.toArray(s, component);
}

View File

@ -4,48 +4,40 @@ import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import net.sf.openrocket.rocketcomponent.MassObject;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
public class MassObjectShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate instanceOffset) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
MassObject tube = (MassObject)component;
double length = tube.getLength();
double radius = tube.getRadius();
double arc = Math.min(length, 2*radius) * 0.7;
Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
Shape[] s = new Shape[start.length];
for (int i=0; i < start.length; i++) {
s[i] = new RoundRectangle2D.Double(start[i].x,(start[i].y-radius),
length,2*radius,arc,arc);
}
Coordinate start = transformation.transform(Coordinate.ZERO);
Shape[] s = {new RoundRectangle2D.Double(start.x, (start.y-radius), length, 2*radius, arc, arc)};
return RocketComponentShape.toArray(s, component);
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate instanceOffset) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
MassObject tube = (MassObject)component;
double or = tube.getRadius();
Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
final Coordinate start = transformation.transform(Coordinate.ZERO);
Shape[] s = new Shape[start.length];
for (int i=0; i < start.length; i++) {
s[i] = new Ellipse2D.Double((start[i].z-or),(start[i].y-or),2*or,2*or);
}
Shape[] s = {new Ellipse2D.Double((start.z-or), (start.y-or), 2*or, 2*or)};
return RocketComponentShape.toArray(s, component);
}

View File

@ -1,5 +1,6 @@
package net.sf.openrocket.gui.rocketfigure;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
@ -12,36 +13,31 @@ import java.awt.geom.RoundRectangle2D;
public class ParachuteShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
double length = tube.getLength();
double radius = tube.getRadius();
double arc = Math.min(length, 2*radius) * 0.7;
Coordinate[] start = new Coordinate[]{transformation.transform( componentAbsoluteLocation)};
Coordinate start = transformation.transform( Coordinate.ZERO);
Shape[] s = new Shape[start.length];
for (int i=0; i < start.length; i++) {
s[i] = new RoundRectangle2D.Double(start[i].x, (start[i].y-radius), length, 2*radius, arc, arc);
}
Shape[] s = new Shape[1];
s[0] = new RoundRectangle2D.Double(start.x, (start.y-radius), length, 2*radius, arc, arc);
return RocketComponentShape.toArray( addSymbol(s), component);
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate instanceOffset) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
double or = tube.getRadius();
Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
Coordinate[] start = transformation.transform(tube.toAbsolute(Coordinate.ZERO));
Shape[] s = new Shape[start.length];
for (int i=0; i < start.length; i++) {

View File

@ -14,11 +14,8 @@ import net.sf.openrocket.util.Transformation;
public class RailButtonShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
RocketComponent component,
Transformation transformation,
Coordinate instanceAbsoluteLocation) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
RailButton btn = (RailButton)component;
final double rotation_rad = btn.getAngleOffset();
@ -36,6 +33,11 @@ public class RailButtonShapes extends RocketComponentShape {
final double innerHeightcos = innerHeight*cosr;
final double flangeHeightcos = flangeHeight*cosr;
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
System.err.println(String.format("Generating Shapes for RailButtons..."));
System.err.println(String.format(" @ %s", instanceAbsoluteLocation));
Path2D.Double path = new Path2D.Double();
{// central pillar
@ -51,7 +53,7 @@ public class RailButtonShapes extends RocketComponentShape {
path.append( new Ellipse2D.Double( lowerLeft.x, (lowerLeft.y+baseHeightcos), drawWidth, drawHeight), false);
}
{// inner
{// inner flange
final double drawWidth = innerDiameter;
final double drawHeight = innerDiameter*sinr;
final Point2D.Double center = new Point2D.Double( instanceAbsoluteLocation.x, instanceAbsoluteLocation.y + baseHeightcos);
@ -80,12 +82,9 @@ public class RailButtonShapes extends RocketComponentShape {
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate instanceOffset) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.RailButton btn = (net.sf.openrocket.rocketcomponent.RailButton)component;
RailButton btn = (RailButton)component;
final double rotation_rad = btn.getAngleOffset();
final double sinr = Math.sin(rotation_rad);
@ -98,7 +97,8 @@ public class RailButtonShapes extends RocketComponentShape {
final double outerRadius = outerDiameter/2;
final double innerDiameter = btn.getInnerDiameter();
final double innerRadius = innerDiameter/2;
Coordinate[] inst = transformation.transform( btn.getLocations());
Coordinate[] inst = {transformation.transform(Coordinate.ZERO)};
Shape[] s = new Shape[inst.length];
for (int i=0; i < inst.length; i++) {

View File

@ -2,19 +2,16 @@ package net.sf.openrocket.gui.rocketfigure;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.rocketcomponent.RingComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.Transformation;
public class RingComponentShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate instanceAbsoluteLocation) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.RingComponent tube = (net.sf.openrocket.rocketcomponent.RingComponent)component;
Shape[] s;
@ -26,24 +23,22 @@ public class RingComponentShapes extends RocketComponentShape {
if ((outerRadius-innerRadius >= 0.0012) && (innerRadius > 0)) {
// Draw outer and inner
s = new Shape[] {
TubeShapes.getShapesSide(transformation, instanceAbsoluteLocation, length, outerRadius),
TubeShapes.getShapesSide(transformation, instanceAbsoluteLocation, length, innerRadius)
TubeShapes.getShapesSide(transformation, length, outerRadius),
TubeShapes.getShapesSide(transformation, length, innerRadius)
};
} else {
// Draw only outer
s = new Shape[] {
TubeShapes.getShapesSide(transformation, instanceAbsoluteLocation, length, outerRadius)
TubeShapes.getShapesSide(transformation, length, outerRadius)
};
}
return RocketComponentShape.toArray( s, component);
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate instanceAbsoluteLocation) {
net.sf.openrocket.rocketcomponent.RingComponent tube = (net.sf.openrocket.rocketcomponent.RingComponent)component;
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
RingComponent tube = (net.sf.openrocket.rocketcomponent.RingComponent)component;
Shape[] s;
double outerRadius = tube.getOuterRadius();
@ -51,12 +46,12 @@ public class RingComponentShapes extends RocketComponentShape {
if ((outerRadius-innerRadius >= 0.0012) && (innerRadius > 0)) {
s = new Shape[] {
TubeShapes.getShapesBack(transformation, instanceAbsoluteLocation, outerRadius),
TubeShapes.getShapesBack(transformation, instanceAbsoluteLocation, innerRadius)
TubeShapes.getShapesBack(transformation, outerRadius),
TubeShapes.getShapesBack(transformation, innerRadius)
};
}else {
s = new Shape[] {
TubeShapes.getShapesBack(transformation, instanceAbsoluteLocation, outerRadius)
TubeShapes.getShapesBack(transformation, outerRadius)
};
}

View File

@ -3,10 +3,8 @@ package net.sf.openrocket.gui.rocketfigure;
import java.awt.Shape;
import net.sf.openrocket.gui.scalefigure.RocketFigure;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.LineStyle;
import net.sf.openrocket.util.Transformation;
@ -51,20 +49,15 @@ public class RocketComponentShape {
}
public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate instanceOffset) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
// no-op
Application.getExceptionHandler().handleErrorCondition("ERROR: RocketComponent.getShapesSide called with "
+ component);
return new RocketComponentShape[0];
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate instanceOffset) { // no-op
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
// no-op
Application.getExceptionHandler().handleErrorCondition("ERROR: RocketComponent.getShapesBack called with "
+component);
return new RocketComponentShape[0];

View File

@ -1,5 +1,6 @@
package net.sf.openrocket.gui.rocketfigure;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
@ -11,10 +12,8 @@ import java.awt.geom.RoundRectangle2D;
public class ShockCordShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.MassObject massObj = (net.sf.openrocket.rocketcomponent.MassObject)component;
@ -22,8 +21,7 @@ public class ShockCordShapes extends RocketComponentShape {
double radius = massObj.getRadius();
double arc = Math.min(length, 2*radius) * 0.7;
Coordinate start = transformation.transform( componentAbsoluteLocation);
Coordinate start = transformation.transform(Coordinate.ZERO);
Shape[] s = new Shape[1];
s[0] = new RoundRectangle2D.Double(start.x,(start.y-radius),
length,2*radius,arc,arc);
@ -32,17 +30,15 @@ public class ShockCordShapes extends RocketComponentShape {
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
double or = tube.getRadius();
Shape[] s = new Shape[1];
Coordinate start = componentAbsoluteLocation;
Coordinate start = transformation.transform(Coordinate.ZERO);
s[0] = new Ellipse2D.Double((start.z-or),(start.y-or),2*or,2*or);
// Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));

View File

@ -1,5 +1,6 @@
package net.sf.openrocket.gui.rocketfigure;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
@ -11,10 +12,7 @@ import java.awt.geom.RoundRectangle2D;
public class StreamerShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation ) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.MassObject massObj = (net.sf.openrocket.rocketcomponent.MassObject)component;
@ -23,7 +21,7 @@ public class StreamerShapes extends RocketComponentShape {
double arc = Math.min(length, 2*radius) * 0.7;
Shape[] s = new Shape[1];
Coordinate frontCenter = componentAbsoluteLocation;
Coordinate frontCenter = transformation.transform(Coordinate.ZERO);
s[0] = new RoundRectangle2D.Double((frontCenter.x),(frontCenter.y-radius),
length,2*radius,arc,arc);
@ -37,16 +35,14 @@ public class StreamerShapes extends RocketComponentShape {
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
double or = tube.getRadius();
Shape[] s = new Shape[1];
Coordinate center = componentAbsoluteLocation;
Coordinate center = transformation.transform(Coordinate.ZERO);
s[0] = new Ellipse2D.Double((center.z-or),(center.y-or),2*or,2*or);
// Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));

View File

@ -1,5 +1,6 @@
package net.sf.openrocket.gui.rocketfigure;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil;
@ -17,10 +18,8 @@ public class SymmetricComponentShapes extends RocketComponentShape {
// TODO: LOW: Uses only first component of cluster (not currently clusterable)
public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
SymmetricComponent c = (SymmetricComponent) component;
@ -79,7 +78,7 @@ public class SymmetricComponentShapes extends RocketComponentShape {
//System.out.println("here");
final int len = points.size();
Coordinate nose = componentAbsoluteLocation;
Coordinate nose = transformation.transform(Coordinate.ZERO);
// TODO: LOW: curved path instead of linear
Path2D.Double path = new Path2D.Double();

View File

@ -12,24 +12,20 @@ import java.awt.geom.Path2D;
public class TransitionShapes extends RocketComponentShape {
// TODO: LOW: Uses only first component of cluster (not currently clusterable).
public static RocketComponentShape[] getShapesSide(
RocketComponent component,
Transformation transformation,
Coordinate instanceLocation) {
return getShapesSide(component, transformation, instanceLocation, 1.0);
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
return getShapesSide(component, transformation, 1.0);
}
public static RocketComponentShape[] getShapesSide(
RocketComponent component,
Transformation transformation,
Coordinate instanceAbsoluteLocation,
final double scaleFactor) {
final RocketComponent component,
final Transformation transformation,
final double scaleFactor) {
Transition transition = (Transition)component;
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
RocketComponentShape[] mainShapes;
// Simpler shape for conical transition, others use the method from SymmetricComponent
@ -49,27 +45,28 @@ public class TransitionShapes extends RocketComponentShape {
mainShapes = new RocketComponentShape[] { new RocketComponentShape( path, component) };
} else {
mainShapes = SymmetricComponentShapes.getShapesSide(component, transformation, instanceAbsoluteLocation);
mainShapes = SymmetricComponentShapes.getShapesSide(component, transformation);
}
Shape foreShoulder=null, aftShoulder=null;
int arrayLength = mainShapes.length;
if (transition.getForeShoulderLength() > 0.0005) {
Coordinate foreTransitionShoulderCenter = instanceAbsoluteLocation.sub( transition.getForeShoulderLength(), 0, 0);
final Coordinate frontCenter = foreTransitionShoulderCenter; //transformation.transform( foreTransitionShoulderCenter);
final double length = transition.getForeShoulderLength();
final double radius = transition.getForeShoulderRadius();
final double shoulderLength = transition.getForeShoulderLength();
final double shoulderRadius = transition.getForeShoulderRadius();
final Transformation offsetTransform = Transformation.getTranslationTransform(-transition.getForeShoulderLength(), 0, 0);
final Transformation foreShoulderTransform = transformation.applyTransformation(offsetTransform);
foreShoulder = TubeShapes.getShapesSide( transformation, frontCenter, length, radius);
foreShoulder = TubeShapes.getShapesSide( foreShoulderTransform, shoulderLength, shoulderRadius);
arrayLength++;
}
if (transition.getAftShoulderLength() > 0.0005) {
Coordinate aftTransitionShoulderCenter = instanceAbsoluteLocation.add( transition.getLength(), 0, 0);
final Coordinate frontCenter = aftTransitionShoulderCenter; //transformation.transform( aftTransitionShoulderCenter );
final double length = transition.getAftShoulderLength();
final double radius = transition.getAftShoulderRadius();
aftShoulder = TubeShapes.getShapesSide(transformation, frontCenter, length, radius);
final double shoulderLength = transition.getAftShoulderLength();
final double shoulderRadius = transition.getAftShoulderRadius();
final Transformation offsetTransform = Transformation.getTranslationTransform(transition.getLength(), 0, 0);
final Transformation aftShoulderTransform = transformation.applyTransformation(offsetTransform);
aftShoulder = TubeShapes.getShapesSide(aftShoulderTransform, shoulderLength, shoulderRadius);
arrayLength++;
}
if (foreShoulder==null && aftShoulder==null)
@ -92,17 +89,14 @@ public class TransitionShapes extends RocketComponentShape {
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.Transition transition = (net.sf.openrocket.rocketcomponent.Transition)component;
Transition transition = (net.sf.openrocket.rocketcomponent.Transition)component;
double r1 = transition.getForeRadius();
double r2 = transition.getAftRadius();
Coordinate center = componentAbsoluteLocation;
final Coordinate center = transformation.transform(Coordinate.ZERO);
Shape[] s = new Shape[2];
s[0] = new Ellipse2D.Double((center.z-r1),(center.y-r1),2*r1,2*r1);

View File

@ -4,18 +4,17 @@ import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation;
public class TubeFinSetShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
int fins = finset.getFinCount();
double length = finset.getLength();
@ -47,12 +46,9 @@ public class TubeFinSetShapes extends RocketComponentShape {
}
public static RocketComponentShape[] getShapesBack(
net.sf.openrocket.rocketcomponent.RocketComponent component,
Transformation transformation,
Coordinate componentAbsoluteLocation) {
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
net.sf.openrocket.rocketcomponent.TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
TubeFinSet finset = (net.sf.openrocket.rocketcomponent.TubeFinSet)component;
int fins = finset.getFinCount();
double outerradius = finset.getOuterRadius();

View File

@ -10,21 +10,19 @@ import net.sf.openrocket.util.Transformation;
public class TubeShapes extends RocketComponentShape {
public static Shape getShapesSide(
Transformation transformation,
Coordinate instanceAbsoluteLocation,
final double length, final double radius ){
public static Shape getShapesSide( final Transformation transformation, final double length, final double radius ){
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
return new Rectangle2D.Double((instanceAbsoluteLocation.x), //x - the X coordinate of the upper-left corner of the newly constructed Rectangle2D
(instanceAbsoluteLocation.y-radius), // y - the Y coordinate of the upper-left corner of the newly constructed Rectangle2D
length, // w - the width of the newly constructed Rectangle2D
2*radius); // h - the height of the newly constructed Rectangle2D
}
public static Shape getShapesBack(
Transformation transformation,
Coordinate instanceAbsoluteLocation,
final double radius ) {
public static Shape getShapesBack( final Transformation transformation, final double radius ) {
final Coordinate instanceAbsoluteLocation = transformation.transform(Coordinate.ZERO);
return new Ellipse2D.Double((instanceAbsoluteLocation.z-radius), (instanceAbsoluteLocation.y-radius), 2*radius, 2*radius);
}

View File

@ -15,22 +15,21 @@ import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.openrocket.gui.figureelements.FigureElement;
import net.sf.openrocket.gui.rocketfigure.RocketComponentShape;
import net.sf.openrocket.gui.scalefigure.RocketPanel.VIEW_TYPE;
import net.sf.openrocket.gui.util.ColorConversion;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.motor.MotorConfiguration;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent;
@ -192,8 +191,7 @@ public class RocketFigure extends AbstractScaleFigure {
updateCanvasSize();
updateTransform();
figureShapes.clear();
updateShapeTree( this.figureShapes, rocket, this.axialRotation, Coordinate.ZERO);
updateShapes(this.figureShapes);
g2.transform(projection);
@ -336,60 +334,29 @@ public class RocketFigure extends AbstractScaleFigure {
return l.toArray(new RocketComponent[0]);
}
// NOTE: Recursive function
private ArrayList<RocketComponentShape> updateShapeTree(
ArrayList<RocketComponentShape> allShapes, // output parameter
final RocketComponent comp,
final Transformation parentTransform,
final Coordinate parentLocation){
private void updateShapes(ArrayList<RocketComponentShape> allShapes) {
// source input
final FlightConfiguration config = rocket.getSelectedConfiguration();
// allShapes is an output buffer -- it stores all the generated shapes
allShapes.clear();
for(Entry<RocketComponent, ArrayList<InstanceContext>> entry: config.getActiveInstances().entrySet() ) {
final RocketComponent comp = entry.getKey();
final ArrayList<InstanceContext> contextList = entry.getValue();
final int instanceCount = comp.getInstanceCount();
Coordinate[] instanceLocations = comp.getInstanceLocations();
instanceLocations = parentTransform.transform( instanceLocations );
double[] instanceAngles = comp.getInstanceAngles();
if( instanceLocations.length != instanceAngles.length ){
throw new ArrayIndexOutOfBoundsException(String.format("lengths of location array (%d) and angle arrays (%d) differs! (in: %s) ", instanceLocations.length, instanceAngles.length, comp.getName()));
}
// iterate over the aggregated instances *for the whole* tree.
for( int index = 0; instanceCount > index ; ++index ){
final double currentAngle = instanceAngles[index];
Transformation currentTransform = parentTransform;
if( 0.00001 < Math.abs( currentAngle )) {
Transformation currentAngleTransform = Transformation.rotate_x( currentAngle );
currentTransform = currentAngleTransform.applyTransformation( parentTransform );
}
Coordinate currentLocation = parentLocation.add( instanceLocations[index] );
// if(FinSet.class.isAssignableFrom(comp.getClass())) {
// System.err.println(String.format("@%s: %s -- inst: [%d/%d]", comp.getClass().getSimpleName(), comp.getName(), index+1, instanceCount));
//
// // FlightConfiguration config = this.rocket.getSelectedConfiguration();
// // 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
if( this.rocket.getSelectedConfiguration().isComponentActive( comp )){
allShapes = addThisShape( allShapes, this.currentViewType, comp, currentLocation, currentTransform);
}
// recurse into component's children
for( RocketComponent child: comp.getChildren() ){
// draw a tree for each instance subcomponent
updateShapeTree( allShapes, child, currentTransform, currentLocation );
}
}
return allShapes;
for(InstanceContext context: contextList ) {
final Transformation currentTransform = this.axialRotation.applyTransformation(context.transform);
// generate shape for this component, if active
if( context.active ) {
allShapes = addThisShape( allShapes, this.currentViewType, comp, currentTransform);
}
}
}
}
/**
* Gets the shapes required to draw the component.
*
@ -401,12 +368,11 @@ public class RocketFigure extends AbstractScaleFigure {
ArrayList<RocketComponentShape> allShapes, // this is the output parameter
final RocketPanel.VIEW_TYPE viewType,
final RocketComponent component,
final Coordinate instanceOffset,
final Transformation transformation) {
Reflection.Method m;
if(( component instanceof Rocket)||( component instanceof ComponentAssembly )){
// no-op; no shapes here, either.
// no-op; no shapes here
return allShapes;
}
@ -414,12 +380,12 @@ public class RocketFigure extends AbstractScaleFigure {
switch (viewType) {
case SideView:
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesSide",
RocketComponent.class, Transformation.class, Coordinate.class);
RocketComponent.class, Transformation.class);
break;
case BackView:
m = Reflection.findMethod(ROCKET_FIGURE_PACKAGE, component, ROCKET_FIGURE_SUFFIX, "getShapesBack",
RocketComponent.class, Transformation.class, Coordinate.class);
RocketComponent.class, Transformation.class);
break;
default:
@ -433,14 +399,13 @@ public class RocketFigure extends AbstractScaleFigure {
}
RocketComponentShape[] returnValue = (RocketComponentShape[]) m.invokeStatic(component, transformation, instanceOffset);
RocketComponentShape[] returnValue = (RocketComponentShape[]) m.invokeStatic(component, transformation);
for ( RocketComponentShape curShape : returnValue ){
allShapes.add( curShape );
}
return allShapes;
}
/**
* Gets the bounds of the drawn subject in Model-Space