package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
-import java.util.List;
import net.sf.openrocket.util.Coordinate;
public class FreeformFinSet extends FinSet {
- private final List<Coordinate> points = new ArrayList<Coordinate>();
+ private ArrayList<Coordinate> points = new ArrayList<Coordinate>();
public FreeformFinSet() {
points.add(Coordinate.NUL);
this.length = 0.05;
}
-
+
+ public FreeformFinSet(Coordinate[] finpoints) {
+ points.clear();
+ for (Coordinate c: finpoints) {
+ points.add(c);
+ }
+ this.length = points.get(points.size()-1).x - points.get(0).x;
+ }
+
+ /*
public FreeformFinSet(FinSet finset) {
Coordinate[] finpoints = finset.getFinPoints();
this.copyFrom(finset);
}
this.length = points.get(points.size()-1).x - points.get(0).x;
}
+ */
+ /**
+ * Convert an existing fin set into a freeform fin set. The specified
+ * fin set is taken out of the rocket tree (if any) and the new component
+ * inserted in its stead.
+ * <p>
+ * The specified fin set should not be used after the call!
+ *
+ * @param finset the fin set to convert.
+ * @return the new freeform fin set.
+ */
+ public static FreeformFinSet convertFinSet(FinSet finset) {
+ final RocketComponent root = finset.getRoot();
+ FreeformFinSet freeform;
+
+ try {
+ if (root instanceof Rocket) {
+ ((Rocket)root).freeze();
+ }
+
+ // Get fin set position and remove fin set
+ final RocketComponent parent = finset.getParent();
+ final int position;
+ if (parent != null) {
+ position = parent.getChildPosition(finset);
+ parent.removeChild(position);
+ } else {
+ position = -1;
+ }
+
+
+ // Create the freeform fin set
+ Coordinate[] finpoints = finset.getFinPoints();
+ freeform = new FreeformFinSet(finpoints);
+
+ // Copy component attributes
+ freeform.copyFrom(finset);
+
+ // Set name
+ final String componentTypeName = finset.getComponentName();
+ final String name = freeform.getName();
+
+ if (name.startsWith(componentTypeName)) {
+ freeform.setName(freeform.getComponentName() +
+ name.substring(componentTypeName.length()));
+ }
+
+ // Add freeform fin set to parent
+ if (parent != null) {
+ parent.addChild(freeform, position);
+ }
+
+ } finally {
+ if (root instanceof Rocket) {
+ ((Rocket)root).thaw();
+ }
+ }
+ return freeform;
+ }
+
+
/**
* Add a fin point between indices <code>index-1</code> and <code>index</code>.
* if attempted.
*
* @param index the fin point index to remove
+ * @throws IllegalFinPointException if removing the first or last fin point was attempted.
*/
- public void removePoint(int index) {
+ public void removePoint(int index) throws IllegalFinPointException {
if (index == 0 || index == points.size()-1) {
- throw new IllegalArgumentException("cannot remove first or last point");
+ throw new IllegalFinPointException("cannot remove first or last point");
}
points.remove(index);
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
return points.size();
}
- public void setPoints(Coordinate[] p) {
+ public void setPoints(Coordinate[] p) throws IllegalFinPointException {
if (p[0].x != 0 || p[0].y != 0 || p[p.length-1].y != 0) {
- throw new IllegalArgumentException("Start or end point illegal.");
+ throw new IllegalFinPointException("Start or end point illegal.");
}
for (int i=0; i < p.length-1; i++) {
for (int j=i+2; j < p.length-1; j++) {
if (intersects(p[i].x, p[i].y, p[i+1].x, p[i+1].y,
p[j].x, p[j].y, p[j+1].x, p[j+1].y)) {
- throw new IllegalArgumentException("segments intersect");
+ throw new IllegalFinPointException("segments intersect");
}
}
if (p[i].z != 0) {
- throw new IllegalArgumentException("z-coordinate not zero");
+ throw new IllegalFinPointException("z-coordinate not zero");
}
}
* @param index the point index to modify.
* @param x the x-coordinate.
* @param y the y-coordinate.
+ * @throws IllegalFinPointException if the specified fin point would cause intersecting
+ * segments
*/
- public void setPoint(int index, double x, double y) {
+ public void setPoint(int index, double x, double y) throws IllegalFinPointException {
if (y < 0)
y = 0;
if (i != index-1 && i != index && i != index+1) {
if (intersects(x0,y0,x,y,px0,py0,px1,py1)) {
- throw new IllegalArgumentException("segments intersect");
+ throw new IllegalFinPointException("segments intersect");
}
}
if (i != index && i != index+1 && i != index+2) {
if (intersects(x,y,x1,y1,px0,py0,px1,py1)) {
- throw new IllegalArgumentException("segments intersect");
+ throw new IllegalFinPointException("segments intersect");
}
}
return "Freeform fin set";
}
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public RocketComponent copy() {
+ RocketComponent c = super.copy();
+ ((FreeformFinSet)c).points = (ArrayList<Coordinate>) this.points.clone();
+ return c;
+ }
+
}