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.Transformation;
11 public class SymmetricComponentShapes extends RocketComponentShapes {
12 private static final int MINPOINTS = 91;
13 private static final double ACCEPTABLE_ANGLE = Math.cos(7.0*Math.PI/180.0);
15 // TODO: HIGH: adaptiveness sucks, remove it.
17 // TODO: LOW: Uses only first component of cluster (not currently clusterable)
19 public static Shape[] getShapesSide(net.sf.openrocket.rocketcomponent.RocketComponent component,
20 Transformation transformation) {
21 net.sf.openrocket.rocketcomponent.SymmetricComponent c = (net.sf.openrocket.rocketcomponent.SymmetricComponent)component;
24 final double delta = 0.0000001;
27 ArrayList<Coordinate> points = new ArrayList<Coordinate>();
29 points.add(new Coordinate(x,c.getRadius(x),0));
30 for (i=1; i < MINPOINTS-1; i++) {
31 x = c.getLength()*i/(MINPOINTS-1);
32 points.add(new Coordinate(x,c.getRadius(x),0));
33 //System.out.println("Starting with x="+x);
35 x = c.getLength() - delta;
36 points.add(new Coordinate(x,c.getRadius(x),0));
40 while (i < points.size()-2) {
41 if (angleAcceptable(points.get(i),points.get(i+1),points.get(i+2)) ||
42 points.get(i+1).x - points.get(i).x < 0.001) { // 1mm
47 // Split the longer of the areas
49 if (points.get(i+2).x-points.get(i+1).x > points.get(i+1).x-points.get(i).x)
54 x = (points.get(n).x + points.get(n+1).x)/2;
55 points.add(n+1,new Coordinate(x,c.getRadius(x),0));
59 //System.out.println("Final points: "+points.size());
61 final int len = points.size();
63 for (i=0; i < len; i++) {
64 points.set(i, c.toAbsolute(points.get(i))[0]);
68 Shape[] s = new Shape[len+1];
70 for (i=0; i<len; i++) {
71 s[i] = new Ellipse2D.Double(points.get(i).x()-d/2,points.get(i).y()-d/2,d,d);
75 //System.out.println("here");
77 // TODO: LOW: curved path instead of linear
78 Path2D.Double path = new Path2D.Double();
79 path.moveTo(points.get(len-1).x*S, points.get(len-1).y*S);
80 for (i=len-2; i>=0; i--) {
81 path.lineTo(points.get(i).x*S, points.get(i).y*S);
83 for (i=0; i<len; i++) {
84 path.lineTo(points.get(i).x*S, -points.get(i).y*S);
86 path.lineTo(points.get(len-1).x*S, points.get(len-1).y*S);
91 return new Shape[]{ path };
94 private static boolean angleAcceptable(Coordinate v1, Coordinate v2, Coordinate v3) {
95 return (cosAngle(v1,v2,v3) > ACCEPTABLE_ANGLE);
98 * cosAngle = v1.v2 / |v1|*|v2| = v1.v2 / sqrt(v1.v1*v2.v2)
100 private static double cosAngle(Coordinate v1, Coordinate v2, Coordinate v3) {
103 cos = Coordinate.dot(v1.sub(v2), v2.sub(v3));
104 len = Math.sqrt(v1.sub(v2).length2() * v2.sub(v3).length2());