create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / rocketcomponent / ClusterConfiguration.java
1 package net.sf.openrocket.rocketcomponent;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.List;
6
7
8 /**
9  * Class that defines different cluster configurations available for the InnerTube.
10  * The class is immutable, and all the constructors are private.  Therefore the only
11  * available cluster configurations are those available in the static fields.
12  * 
13  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
14  */
15 public class ClusterConfiguration {
16         // Helper vars
17         private static final double R5 = 1.0/(2*Math.sin(2*Math.PI/10));
18         private static final double SQRT2 = Math.sqrt(2);
19         private static final double SQRT3 = Math.sqrt(3);
20
21         /** A single motor */
22         public static final ClusterConfiguration SINGLE = new ClusterConfiguration("single", 0,0);
23
24         /** Definitions of cluster configurations.  Do not modify array. */
25         public static final ClusterConfiguration[] CONFIGURATIONS = {
26                 // Single row
27                 SINGLE,
28                 new ClusterConfiguration("double", -0.5,0, 0.5,0),
29                 new ClusterConfiguration("3-row", -1.0,0, 0.0,0, 1.0,0),
30                 new ClusterConfiguration("4-row", -1.5,0, -0.5,0, 0.5,0, 1.5,0),
31                 
32                 // Ring of tubes
33                 new ClusterConfiguration("3-ring", -0.5,-1.0/(2*SQRT3),
34                                                                   0.5,-1.0/(2*SQRT3),
35                                                                     0, 1.0/SQRT3),
36                 new ClusterConfiguration("4-ring", -0.5,0.5, 0.5,0.5, 0.5,-0.5, -0.5,-0.5),
37                 new ClusterConfiguration("5-ring", 0,R5,
38                                                                  R5*Math.sin(2*Math.PI/5),R5*Math.cos(2*Math.PI/5),
39                                                                  R5*Math.sin(2*Math.PI*2/5),R5*Math.cos(2*Math.PI*2/5),
40                                                                  R5*Math.sin(2*Math.PI*3/5),R5*Math.cos(2*Math.PI*3/5),
41                                                                  R5*Math.sin(2*Math.PI*4/5),R5*Math.cos(2*Math.PI*4/5)),
42                 new ClusterConfiguration("6-ring", 0,1, SQRT3/2,0.5, SQRT3/2,-0.5,
43                                                                  0,-1, -SQRT3/2,-0.5, -SQRT3/2,0.5),
44                 
45                 // Centered with ring
46                 new ClusterConfiguration("3-star", 0,0, 0,1, SQRT3/2,-0.5, -SQRT3/2,-0.5),
47                 new ClusterConfiguration("4-star", 0,0, -1/SQRT2,1/SQRT2, 1/SQRT2,1/SQRT2,
48                                                                  1/SQRT2,-1/SQRT2, -1/SQRT2,-1/SQRT2),
49                 new ClusterConfiguration("5-star", 0,0, 0,1, 
50                                                                  Math.sin(2*Math.PI/5),Math.cos(2*Math.PI/5),
51                                                                  Math.sin(2*Math.PI*2/5),Math.cos(2*Math.PI*2/5),
52                                                                  Math.sin(2*Math.PI*3/5),Math.cos(2*Math.PI*3/5),
53                                                                  Math.sin(2*Math.PI*4/5),Math.cos(2*Math.PI*4/5)),
54                 new ClusterConfiguration("6-star", 0,0, 0,1, SQRT3/2,0.5, SQRT3/2,-0.5,
55                                                                  0,-1, -SQRT3/2,-0.5, -SQRT3/2,0.5)
56         };
57         
58         
59         
60         private final List<Double> points;
61         private final String xmlName;
62         
63         
64         private ClusterConfiguration(String xmlName, double... points) {
65                 this.xmlName = xmlName;
66                 if (points.length == 0 || points.length%2 == 1) {
67                         throw new IllegalArgumentException("Illegal number of points specified: "+
68                                         points.length);
69                 }
70                 List<Double> l = new ArrayList<Double>(points.length);
71                 for (double d: points)
72                         l.add(d);
73                 
74                 this.points = Collections.unmodifiableList(l);
75         }
76         
77         public String getXMLName() {
78                 return xmlName;
79         }
80         
81         public int getClusterCount() {
82                 return points.size()/2;
83         }
84         
85         /**
86          * Returns the relative positions of the cluster components.  The list is of length
87          * <code>2*getClusterCount()</code> with (x,y) value pairs.  The origin is at (0,0)
88          * and the values are positioned so that the closest clusters have distance of 1.
89          * 
90          * @return      a list of (x,y) coordinate pairs.
91          */
92         public List<Double> getPoints() {
93                 return points;  // Unmodifiable
94         }
95         
96         /**
97          * Return the points rotated by <code>rotation</code> radians.
98          * @param rotation  Rotation amount.
99          */
100         public List<Double> getPoints(double rotation) {
101                 double cos = Math.cos(rotation);
102                 double sin = Math.sin(rotation);
103                 List<Double> ret = new ArrayList<Double>(points.size());
104                 for (int i=0; i<points.size()/2; i++) {
105                         double x = points.get(2*i);
106                         double y = points.get(2*i+1);
107                         ret.add( x*cos + y*sin);
108                         ret.add(-x*sin + y*cos);
109                 }
110                 return ret;
111         }
112         
113         
114         @Override
115         public String toString() {
116                 return xmlName;
117         }
118 }