1 package net.sf.openrocket.gui.rocketfigure;
4 import java.awt.geom.Path2D;
5 import java.util.ArrayList;
7 import net.sf.openrocket.util.Coordinate;
8 import net.sf.openrocket.util.MathUtil;
9 import net.sf.openrocket.util.Transformation;
12 public class SymmetricComponentShapes extends RocketComponentShapes {
13 private static final int MINPOINTS = 91;
14 private static final double ACCEPTABLE_ANGLE = Math.cos(7.0 * Math.PI / 180.0);
16 // TODO: HIGH: adaptiveness sucks, remove it.
18 // TODO: LOW: Uses only first component of cluster (not currently clusterable)
20 public static Shape[] getShapesSide(net.sf.openrocket.rocketcomponent.RocketComponent component,
21 Transformation transformation) {
22 net.sf.openrocket.rocketcomponent.SymmetricComponent c = (net.sf.openrocket.rocketcomponent.SymmetricComponent) component;
25 final double delta = 0.0000001;
28 ArrayList<Coordinate> points = new ArrayList<Coordinate>();
30 points.add(new Coordinate(x, c.getRadius(x), 0));
31 for (i = 1; i < MINPOINTS - 1; i++) {
32 x = c.getLength() * i / (MINPOINTS - 1);
33 points.add(new Coordinate(x, c.getRadius(x), 0));
34 //System.out.println("Starting with x="+x);
36 x = c.getLength() - delta;
37 points.add(new Coordinate(x, c.getRadius(x), 0));
41 while (i < points.size() - 2) {
42 if (angleAcceptable(points.get(i), points.get(i + 1), points.get(i + 2)) ||
43 points.get(i + 1).x - points.get(i).x < 0.001) { // 1mm
48 // Split the longer of the areas
50 if (points.get(i + 2).x - points.get(i + 1).x > points.get(i + 1).x - points.get(i).x)
55 x = (points.get(n).x + points.get(n + 1).x) / 2;
56 points.add(n + 1, new Coordinate(x, c.getRadius(x), 0));
60 //System.out.println("Final points: "+points.size());
62 final int len = points.size();
64 for (i = 0; i < len; i++) {
65 points.set(i, c.toAbsolute(points.get(i))[0]);
69 Shape[] s = new Shape[len+1];
71 for (i=0; i<len; i++) {
72 s[i] = new Ellipse2D.Double(points.get(i).x()-d/2,points.get(i).y()-d/2,d,d);
76 //System.out.println("here");
78 // TODO: LOW: curved path instead of linear
79 Path2D.Double path = new Path2D.Double();
80 path.moveTo(points.get(len - 1).x * S, points.get(len - 1).y * S);
81 for (i = len - 2; i >= 0; i--) {
82 path.lineTo(points.get(i).x * S, points.get(i).y * S);
84 for (i = 0; i < len; i++) {
85 path.lineTo(points.get(i).x * S, -points.get(i).y * S);
87 path.lineTo(points.get(len - 1).x * S, points.get(len - 1).y * S);
92 return new Shape[] { path };
95 private static boolean angleAcceptable(Coordinate v1, Coordinate v2, Coordinate v3) {
96 return (cosAngle(v1, v2, v3) > ACCEPTABLE_ANGLE);
100 * cosAngle = v1.v2 / |v1|*|v2| = v1.v2 / sqrt(v1.v1*v2.v2)
102 private static double cosAngle(Coordinate v1, Coordinate v2, Coordinate v3) {
105 cos = Coordinate.dot(v1.sub(v2), v2.sub(v3));
106 len = MathUtil.safeSqrt(v1.sub(v2).length2() * v2.sub(v3).length2());