*
* @return the scale of the diagram
*/
- private double paintRocketDiagram (final int thePageImageableWidth, final int thePageImageableHeight, final PdfContentByte theCanvas, final PrintFigure theFigure, final FigureElement theCp, final FigureElement theCg) {
+ private double paintRocketDiagram (final int thePageImageableWidth, final int thePageImageableHeight,
+ final PdfContentByte theCanvas, final PrintFigure theFigure,
+ final FigureElement theCp, final FigureElement theCg) {
theFigure.clearAbsoluteExtra();
theFigure.clearRelativeExtra();
theFigure.addRelativeExtra(theCp);
import java.util.Set;
/**
- * This is the main active object for printing. It performs all actions necessary to create and populate the print file.
+ * This is the main active object for printing. It performs all actions necessary to create and populate the print
+ * file.
*/
public class PrintController {
/**
* Print the selected components to a PDF document.
- *
- * @param doc the OR document
- * @param toBePrinted the user chosen items to print
- * @param outputFile the file being written to
- * @param msn the paper size
+ *
+ * @param doc the OR document
+ * @param toBePrinted the user chosen items to print
+ * @param outputFile the file being written to
+ * @param msn the paper size
*/
public void print (OpenRocketDocument doc, Iterator<PrintableContext> toBePrinted, OutputStream outputFile, MediaSizeName msn) {
Document idoc = new Document(convertWithDefault(msn));
PdfWriter writer = null;
-// OutputStream fileOutputStream = null;
try {
-// fileOutputStream = outputFile;
writer = PdfWriter.getInstance(idoc, outputFile);
writer.setStrictImageSequence(true);
detailVisitor.close();
idoc.newPage();
break;
- /* case PARTS_LIST:
- final ComponentVisitor partsVisitor = new ComponentVisitor(new PartsListVisitorStrategy(idoc,
- writer,
- stages));
- partsVisitor.visit(doc.getRocket());
- partsVisitor.close();
- idoc.newPage();
- break;
- */}
+ /* case PARTS_LIST:
+ final ComponentVisitor partsVisitor = new ComponentVisitor(new PartsListVisitorStrategy(idoc,
+ writer,
+ stages));
+ partsVisitor.visit(doc.getRocket());
+ partsVisitor.close();
+ idoc.newPage();
+ break;
+ */
+ }
}
//Stupid iText throws a really nasty exception if there is no data when close is called.
if (writer.getCurrentDocumentSize() <= 140) {
}
}
}
- */ }
+ */
+ }
private Rectangle convertWithDefault (final MediaSizeName msn) {
Rectangle result = PaperSize.convert(msn);
private GeneralPath polygon = null;
/**
- * The margin.
+ * The X margin.
*/
- private final int margin = 10;
+ private int marginX = 25;
+ /**
+ * The Y margin.
+ */
+ private int marginY = 25;
/**
* Constructor.
}
polygon.closePath();
- setSize(maxX - minX + margin, maxY - minY + margin);
+ if (minX < 0) {
+ marginX += Math.abs(minX);
+ }
+ if (minY < 0) {
+ marginY += Math.abs(minY);
+ }
+ setSize(maxX - minX + marginX, maxY - minY + marginY);
}
/**
* @return an awt image of the fin set
*/
public Image createImage () {
- int width = getWidth() + margin;
- int height = getHeight() + margin;
+ int width = getWidth() + marginX;
+ int height = getHeight() + marginY;
// Create a buffered image in which to draw
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// Create a graphics contents on the buffered image
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
- g2d.translate(margin, margin);
+ g2d.translate(marginX, marginY);
g2d.setPaint(TemplateProperties.getFillColor());
g2d.fill(polygon);
g2d.setPaint(TemplateProperties.getLineColor());
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
import net.sf.openrocket.rocketcomponent.InnerTube;
import net.sf.openrocket.rocketcomponent.LaunchLug;
+import net.sf.openrocket.rocketcomponent.MassObject;
import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.RadiusRingComponent;
import net.sf.openrocket.rocketcomponent.RingComponent;
import java.util.Set;
/**
- * This abstract class contains boilerplate functionality to support visiting the components of a rocket.
- * It is a visitor strategy, not a visitor per se.
+ * This abstract class contains boilerplate functionality to support visiting the components of a rocket. It is a
+ * visitor strategy, not a visitor per se.
*/
public abstract class BaseVisitorStrategy implements ComponentVisitorStrategy {
* The stages selected.
*/
protected Set<Integer> stages;
-
+
/**
* State variable to track the level of hierarchy.
*/
/**
* Constructor.
- *
- * @param doc the iText document
+ *
+ * @param doc the iText document
*/
public BaseVisitorStrategy (Document doc) {
this(doc, null);
/**
* Constructor.
- *
- * @param doc the iText document
- * @param theWriter an iText byte writer
+ *
+ * @param doc the iText document
+ * @param theWriter an iText byte writer
*/
public BaseVisitorStrategy (Document doc, PdfWriter theWriter) {
this(doc, theWriter, new HashSet<Integer>());
/**
* Constructor.
- *
- * @param doc the iText document
- * @param theWriter an iText byte writer
- * @param theStages a set of stage numbers
+ *
+ * @param doc the iText document
+ * @param theWriter an iText byte writer
+ * @param theStages a set of stage numbers
*/
public BaseVisitorStrategy (Document doc, PdfWriter theWriter, Set<Integer> theStages) {
document = doc;
/**
* Determine if the visitor strategy's set of stage numbers (to print) contains the specified stage.
- *
+ *
* @param stageNumber a stage number
- *
- * @return true if the visitor strategy contains the stage number provided
+ *
+ * @return true if the visitor strategy contains the stage number provided
*/
public boolean shouldVisitStage (int stageNumber) {
if (stages == null || stages.isEmpty()) {
return true;
}
}
-
+
return false;
}
-
+
/**
* Recurse through the given rocket component.
- *
- * @param root the root component; all children will be visited recursively
+ *
+ * @param root the root component; all children will be visited recursively
*/
protected void goDeep (final RocketComponent root) {
RocketComponent[] rc = root.getChildren();
/**
- * Recurse through the given rocket component.
- *
- * @param theRc an array of rocket components; all children will be visited recursively
- */
- protected void goDeep (final RocketComponent[] theRc) {
+ * Recurse through the given rocket component.
+ *
+ * @param theRc an array of rocket components; all children will be visited recursively
+ */
+ protected void goDeep (final RocketComponent[] theRc) {
level++;
for (RocketComponent rocketComponent : theRc) {
rocketComponent.accept(parent);
/**
* Get the dimensions of the paper page.
- *
+ *
* @return an internal Dimension
*/
- protected Dimension getPageSize() {
+ protected Dimension getPageSize () {
return new Dimension(document.getPageSize().getWidth(),
document.getPageSize().getHeight());
}
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final Rocket visitable) {
goDeep(visitable);
}
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final RocketComponent visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final Stage visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final ExternalComponent visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final BodyComponent visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final RingComponent visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final InnerTube visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final LaunchLug visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final Transition visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final RadiusRingComponent visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
+ public void visit (final MassObject visitable) {
+ if (shouldVisitStage(visitable.getStageNumber())) {
+ goDeep(visitable);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void visit (final NoseCone visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final BodyTube visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final TrapezoidFinSet visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final EllipticalFinSet visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void visit (final FreeformFinSet visitable) {
if (shouldVisitStage(visitable.getStageNumber())) {
goDeep(visitable);
/**
* {@inheritDoc}
*/
- @Override
+ @Override
public void close () {
}
}
class Dimension {
public float width;
public float height;
-
- public Dimension(float w, float h) {
+
+ public Dimension (float w, float h) {
width = w;
height = h;
}
-
- public float getWidth() {
+
+ public float getWidth () {
return width;
}
-
- public float getHeight() {
+
+ public float getHeight () {
return height;
}
}
\ No newline at end of file
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
import net.sf.openrocket.rocketcomponent.InnerTube;
import net.sf.openrocket.rocketcomponent.LaunchLug;
+import net.sf.openrocket.rocketcomponent.MassObject;
import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.RadiusRingComponent;
import net.sf.openrocket.rocketcomponent.RingComponent;
goDeep(rc);
}
-
+
/**
* {@inheritDoc}
*/
goDeep(rc);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void visit (final MassObject visitable) {
+ PdfPCell cell = ITextHelper.createCell();
+ cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
+ cell.setPaddingBottom(12f);
+
+ grid.addCell(iconToImage(visitable));
+ final PdfPCell nameCell = createNameCell(visitable.getName(), true);
+ nameCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);
+ nameCell.setPaddingBottom(12f);
+ grid.addCell(nameCell);
+ grid.addCell(cell);
+ grid.addCell(cell);
+ grid.addCell(cell);
+ grid.addCell(createMassCell(visitable.getMass()));
+ RocketComponent[] rc = visitable.getChildren();
+ goDeep(rc);
+ }
+
/**
* {@inheritDoc}
*/
img = Image.getInstance(writer, awtImage, 0.25f);
}
catch (BadElementException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ e.printStackTrace();
}
catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ e.printStackTrace();
}
grid.addCell(iconToImage(visitable));
import net.sf.openrocket.rocketcomponent.FreeformFinSet;
import net.sf.openrocket.rocketcomponent.InnerTube;
import net.sf.openrocket.rocketcomponent.LaunchLug;
+import net.sf.openrocket.rocketcomponent.MassObject;
import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.RadiusRingComponent;
import net.sf.openrocket.rocketcomponent.RingComponent;
goDeep(visitable);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void visit (final MassObject visitable) {
+ mass += visitable.getMass();
+ goDeep(visitable);
+ }
+
/**
* {@inheritDoc}
*/
/**
* Constructor.
- *
- * @param aStrategy the object to delegate the visiting to
+ *
+ * @param aStrategy the object to delegate the visiting to
*/
public ComponentVisitor (ComponentVisitorStrategy aStrategy) {
strategy = aStrategy;
/**
* Visit a Rocket object.
- *
- * @param visitable the Rocket to visit
+ *
+ * @param visitable the Rocket to visit
*/
public void visit (final Rocket visitable) {
strategy.visit(visitable);
}
/**
- * Visit a RocketComponent object. This is used to catch any RocketComponent subclass not explicity
- * defined by a visit method in this strategy.
- *
- * @param visitable the RocketComponent to visit
+ * Visit a RocketComponent object. This is used to catch any RocketComponent subclass not explicity defined by a
+ * visit method in this strategy.
+ *
+ * @param visitable the RocketComponent to visit
*/
public void visit (final RocketComponent visitable) {
strategy.visit(visitable);
/**
* Visit a Stage object.
- *
- * @param visitable the Stage to visit
+ *
+ * @param visitable the Stage to visit
*/
public void visit (final Stage visitable) {
strategy.visit(visitable);
/**
* Visit an ExternalComponent object.
- *
- * @param visitable the ExternalComponent to visit
+ *
+ * @param visitable the ExternalComponent to visit
*/
public void visit (final ExternalComponent visitable) {
strategy.visit(visitable);
/**
* Visit a BodyComponent object.
- *
- * @param visitable the BodyComponent to visit
+ *
+ * @param visitable the BodyComponent to visit
*/
public void visit (final BodyComponent visitable) {
strategy.visit(visitable);
/**
* Visit a RingComponent object.
- *
- * @param visitable the RingComponent to visit
+ *
+ * @param visitable the RingComponent to visit
*/
public void visit (final RingComponent visitable) {
strategy.visit(visitable);
/**
* Visit an InnerTube object.
- *
- * @param visitable the InnerTube to visit
+ *
+ * @param visitable the InnerTube to visit
*/
public void visit (final InnerTube visitable) {
strategy.visit(visitable);
/**
* Visit a LaunchLug object.
- *
- * @param visitable the LaunchLug to visit
+ *
+ * @param visitable the LaunchLug to visit
*/
public void visit (final LaunchLug visitable) {
- strategy.visit(visitable);
+ strategy.visit(visitable);
}
-
+
/**
* Visit a Transition object.
- *
- * @param visitable the Transition to visit
+ *
+ * @param visitable the Transition to visit
*/
public void visit (final Transition visitable) {
strategy.visit(visitable);
/**
* Visit a RadiusRingComponent object.
- *
- * @param visitable the RadiusRingComponent to visit
+ *
+ * @param visitable the RadiusRingComponent to visit
*/
public void visit (final RadiusRingComponent visitable) {
strategy.visit(visitable);
}
+ /**
+ * Visit a MassObject object.
+ *
+ * @param visitable the MassObject to visit
+ */
+ public void visit (final MassObject visitable) {
+ strategy.visit(visitable);
+ }
+
/**
* Visit a NoseCone object.
- *
- * @param visitable the NoseCone to visit
+ *
+ * @param visitable the NoseCone to visit
*/
public void visit (final NoseCone visitable) {
strategy.visit(visitable);
/**
* Visit a BodyTube object.
- *
- * @param visitable the BodyTube to visit
+ *
+ * @param visitable the BodyTube to visit
*/
public void visit (final BodyTube visitable) {
strategy.visit(visitable);
/**
* Visit a Rocket object.
- *
- * @param visitable the Rocket to visit
+ *
+ * @param visitable the Rocket to visit
*/
public void visit (final TrapezoidFinSet visitable) {
strategy.visit(visitable);
/**
* Visit a Rocket object.
- *
- * @param visitable the Rocket to visit
+ *
+ * @param visitable the Rocket to visit
*/
public void visit (final EllipticalFinSet visitable) {
strategy.visit(visitable);
/**
* Visit a FreeformFinSet object.
- *
- * @param visitable the FreeformFinSet to visit
+ *
+ * @param visitable the FreeformFinSet to visit
*/
public void visit (final FreeformFinSet visitable) {
strategy.visit(visitable);
package net.sf.openrocket.rocketcomponent;
/**
- * This interface defines the methods used in a Rocket component visitor. By using a strategy,
- * we can reuse one visitor definition and just instrument it with different strategies.
+ * This interface defines the methods used in a Rocket component visitor. By using a strategy, we can reuse one visitor
+ * definition and just instrument it with different strategies.
*/
public interface ComponentVisitorStrategy {
/**
* Visit a Rocket object.
- *
- * @param visitable the Rocket to visit
+ *
+ * @param visitable the Rocket to visit
*/
void visit (final Rocket visitable);
/**
- * Visit a RocketComponent object. This is used to catch any RocketComponent subclass not explicity
- * defined by a visit method in this strategy.
- *
- * @param visitable the RocketComponent to visit
+ * Visit a RocketComponent object. This is used to catch any RocketComponent subclass not explicity defined by a
+ * visit method in this strategy.
+ *
+ * @param visitable the RocketComponent to visit
*/
void visit (final RocketComponent visitable);
/**
* Visit a Stage object.
- *
- * @param visitable the Stage to visit
+ *
+ * @param visitable the Stage to visit
*/
void visit (final Stage visitable);
/**
* Visit an ExternalComponent object.
- *
- * @param visitable the ExternalComponent to visit
+ *
+ * @param visitable the ExternalComponent to visit
*/
void visit (final ExternalComponent visitable);
/**
* Visit a BodyComponent object.
- *
- * @param visitable the BodyComponent to visit
+ *
+ * @param visitable the BodyComponent to visit
*/
void visit (final BodyComponent visitable);
/**
* Visit a RingComponent object.
- *
- * @param visitable the RingComponent to visit
+ *
+ * @param visitable the RingComponent to visit
*/
void visit (final RingComponent visitable);
/**
* Visit an InnerTube object.
- *
- * @param visitable the InnerTube to visit
+ *
+ * @param visitable the InnerTube to visit
*/
void visit (final InnerTube visitable);
/**
* Visit a LaunchLug object.
- *
- * @param visitable the LaunchLug to visit
+ *
+ * @param visitable the LaunchLug to visit
*/
void visit (final LaunchLug visitable);
-
+
/**
* Visit a Transition object.
- *
- * @param visitable the Transition to visit
+ *
+ * @param visitable the Transition to visit
*/
void visit (final Transition visitable);
/**
* Visit a RadiusRingComponent object.
- *
- * @param visitable the RadiusRingComponent to visit
+ *
+ * @param visitable the RadiusRingComponent to visit
*/
void visit (final RadiusRingComponent visitable);
+ /**
+ * Visit a MassComponent object.
+ *
+ * @param visitable the MassComponent to visit
+ */
+ void visit (final MassObject visitable);
+
/**
* Visit a NoseCone object.
- *
- * @param visitable the NoseCone to visit
+ *
+ * @param visitable the NoseCone to visit
*/
void visit (final NoseCone visitable);
/**
* Visit a BodyTube object.
- *
- * @param visitable the BodyTube to visit
+ *
+ * @param visitable the BodyTube to visit
*/
void visit (final BodyTube visitable);
/**
* Visit a TrapezoidFinSet object.
- *
- * @param visitable the TrapezoidFinSet to visit
+ *
+ * @param visitable the TrapezoidFinSet to visit
*/
void visit (final TrapezoidFinSet visitable);
/**
* Visit an EllipticalFinSet object.
- *
- * @param visitable the EllipticalFinSet to visit
+ *
+ * @param visitable the EllipticalFinSet to visit
*/
void visit (final EllipticalFinSet visitable);
/**
* Visit a FreeformFinSet object.
- *
- * @param visitable the FreeformFinSet to visit
+ *
+ * @param visitable the FreeformFinSet to visit
*/
void visit (final FreeformFinSet visitable);
/**
* Set the visitor that is using this strategy.
- *
- * @param parent the visitor
+ *
+ * @param parent the visitor
*/
- void setParent(ComponentVisitor parent);
+ void setParent (ComponentVisitor parent);
/**
* Perform any cleanup or finishing operations.
*/
- void close();
+ void close ();
}
package net.sf.openrocket.rocketcomponent;
-import static net.sf.openrocket.util.MathUtil.pow2;
+import net.sf.openrocket.util.Coordinate;
+import net.sf.openrocket.util.MathUtil;
import java.util.ArrayList;
import java.util.Collection;
-import net.sf.openrocket.util.Coordinate;
-import net.sf.openrocket.util.MathUtil;
-
+import static net.sf.openrocket.util.MathUtil.pow2;
/**
- * A MassObject is an internal component that can a specific weight, but not
- * necessarily a strictly bound shape. It is represented as a homogeneous
- * cylinder and drawn in the rocket figure with rounded corners.
- * <p>
- * Subclasses of this class need only implement the {@link #getComponentMass()},
- * {@link #getComponentName()} and {@link #isCompatible(RocketComponent)}
- * methods.
- *
+ * A MassObject is an internal component that can a specific weight, but not necessarily a strictly bound shape. It is
+ * represented as a homogeneous cylinder and drawn in the rocket figure with rounded corners.
+ * <p/>
+ * Subclasses of this class need only implement the {@link #getComponentMass()}, {@link #getComponentName()} and {@link
+ * #isCompatible(RocketComponent)} methods.
+ *
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public abstract class MassObject extends InternalComponent {
- private double radius;
-
- private double radialPosition;
- private double radialDirection;
-
- private double shiftY = 0;
- private double shiftZ = 0;
-
-
- public MassObject() {
- this(0.03, 0.015);
- }
-
- public MassObject(double length, double radius) {
- super();
-
- this.length = length;
- this.radius = radius;
-
- this.setRelativePosition(Position.TOP);
- this.setPositionValue(0.0);
- }
-
-
-
-
- public void setLength(double length) {
- length = Math.max(length, 0);
- if (MathUtil.equals(this.length, length))
- return;
- this.length = length;
- fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
- }
-
-
-
- public final double getRadius() {
- return radius;
- }
-
-
- public final void setRadius(double radius) {
- radius = Math.max(radius, 0);
- if (MathUtil.equals(this.radius, radius))
- return;
- this.radius = radius;
- fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
- }
-
-
-
- public final double getRadialPosition() {
- return radialPosition;
- }
-
- public final void setRadialPosition(double radialPosition) {
- radialPosition = Math.max(radialPosition, 0);
- if (MathUtil.equals(this.radialPosition, radialPosition))
- return;
- this.radialPosition = radialPosition;
- shiftY = radialPosition * Math.cos(radialDirection);
- shiftZ = radialPosition * Math.sin(radialDirection);
- fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
- }
-
- public final double getRadialDirection() {
- return radialDirection;
- }
-
- public final void setRadialDirection(double radialDirection) {
- radialDirection = MathUtil.reduce180(radialDirection);
- if (MathUtil.equals(this.radialDirection, radialDirection))
- return;
- this.radialDirection = radialDirection;
- shiftY = radialPosition * Math.cos(radialDirection);
- shiftZ = radialPosition * Math.sin(radialDirection);
- fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
- }
-
-
-
-
- /**
- * Shift the coordinates according to the radial position and direction.
- */
- @Override
- public final Coordinate[] shiftCoordinates(Coordinate[] array) {
- for (int i=0; i < array.length; i++) {
- array[i] = array[i].add(0, shiftY, shiftZ);
- }
- return array;
- }
-
- @Override
- public final Coordinate getComponentCG() {
- return new Coordinate(length/2, shiftY, shiftZ, getComponentMass());
- }
-
- @Override
- public final double getLongitudalUnitInertia() {
- return (3*pow2(radius) + pow2(length)) / 12;
- }
-
- @Override
- public final double getRotationalUnitInertia() {
- return pow2(radius) / 2;
- }
-
- @Override
- public final Collection<Coordinate> getComponentBounds() {
- Collection<Coordinate> c = new ArrayList<Coordinate>();
- addBound(c, 0, radius);
- addBound(c, length, radius);
- return c;
- }
+ private double radius;
+
+ private double radialPosition;
+ private double radialDirection;
+
+ private double shiftY = 0;
+ private double shiftZ = 0;
+
+
+ public MassObject () {
+ this(0.03, 0.015);
+ }
+
+ public MassObject (double length, double radius) {
+ super();
+
+ this.length = length;
+ this.radius = radius;
+
+ this.setRelativePosition(Position.TOP);
+ this.setPositionValue(0.0);
+ }
+
+
+ public void setLength (double length) {
+ length = Math.max(length, 0);
+ if (MathUtil.equals(this.length, length)) {
+ return;
+ }
+ this.length = length;
+ fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
+ }
+
+
+ public final double getRadius () {
+ return radius;
+ }
+
+
+ public final void setRadius (double radius) {
+ radius = Math.max(radius, 0);
+ if (MathUtil.equals(this.radius, radius)) {
+ return;
+ }
+ this.radius = radius;
+ fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
+ }
+
+
+ public final double getRadialPosition () {
+ return radialPosition;
+ }
+
+ public final void setRadialPosition (double radialPosition) {
+ radialPosition = Math.max(radialPosition, 0);
+ if (MathUtil.equals(this.radialPosition, radialPosition)) {
+ return;
+ }
+ this.radialPosition = radialPosition;
+ shiftY = radialPosition * Math.cos(radialDirection);
+ shiftZ = radialPosition * Math.sin(radialDirection);
+ fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
+ }
+
+ public final double getRadialDirection () {
+ return radialDirection;
+ }
+
+ public final void setRadialDirection (double radialDirection) {
+ radialDirection = MathUtil.reduce180(radialDirection);
+ if (MathUtil.equals(this.radialDirection, radialDirection)) {
+ return;
+ }
+ this.radialDirection = radialDirection;
+ shiftY = radialPosition * Math.cos(radialDirection);
+ shiftZ = radialPosition * Math.sin(radialDirection);
+ fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
+ }
+
+
+ /**
+ * Shift the coordinates according to the radial position and direction.
+ */
+ @Override
+ public final Coordinate[] shiftCoordinates (Coordinate[] array) {
+ for (int i = 0; i < array.length; i++) {
+ array[i] = array[i].add(0, shiftY, shiftZ);
+ }
+ return array;
+ }
+
+ @Override
+ public final Coordinate getComponentCG () {
+ return new Coordinate(length / 2, shiftY, shiftZ, getComponentMass());
+ }
+
+ @Override
+ public final double getLongitudalUnitInertia () {
+ return (3 * pow2(radius) + pow2(length)) / 12;
+ }
+
+ @Override
+ public final double getRotationalUnitInertia () {
+ return pow2(radius) / 2;
+ }
+
+ @Override
+ public final Collection<Coordinate> getComponentBounds () {
+ Collection<Coordinate> c = new ArrayList<Coordinate>();
+ addBound(c, 0, radius);
+ addBound(c, length, radius);
+ return c;
+ }
+
+ /**
+ * Accept a visitor to this MassObject in the component hierarchy.
+ *
+ * @param theVisitor the visitor that will be called back with a reference to this MassObject
+ */
+ @Override
+ public void accept (final ComponentVisitor theVisitor) {
+ theVisitor.visit(this);
+ }
+
}