1 package net.sf.openrocket.gui.rocketfigure;
4 import java.awt.geom.Path2D;
6 import net.sf.openrocket.util.Coordinate;
7 import net.sf.openrocket.util.MathUtil;
8 import net.sf.openrocket.util.Transformation;
11 public class FinSetShapes extends RocketComponentShapes {
13 // TODO: LOW: Clustering is ignored (FinSet cannot currently be clustered)
15 public static Shape[] getShapesSide(net.sf.openrocket.rocketcomponent.RocketComponent component,
16 Transformation transformation) {
17 net.sf.openrocket.rocketcomponent.FinSet finset = (net.sf.openrocket.rocketcomponent.FinSet)component;
20 int fins = finset.getFinCount();
21 Transformation cantRotation = finset.getCantRotation();
22 Transformation baseRotation = finset.getBaseRotationTransformation();
23 Transformation finRotation = finset.getFinRotationTransformation();
25 Coordinate finPoints[] = finset.getFinPointsWithTab();
28 // TODO: MEDIUM: sloping radius
29 double radius = finset.getBodyRadius();
31 // Translate & rotate the coordinates
32 for (int i=0; i<finPoints.length; i++) {
33 finPoints[i] = cantRotation.transform(finPoints[i]);
34 finPoints[i] = baseRotation.transform(finPoints[i].add(0,radius,0));
39 Shape[] s = new Shape[fins];
40 for (int fin=0; fin<fins; fin++) {
45 p = new Path2D.Float();
46 for (int i=0; i<finPoints.length; i++) {
47 a = transformation.transform(finset.toAbsolute(finPoints[i])[0]);
49 p.moveTo(a.x*S, a.y*S);
51 p.lineTo(a.x*S, a.y*S);
57 // Rotate fin coordinates
58 for (int i=0; i<finPoints.length; i++)
59 finPoints[i] = finRotation.transform(finPoints[i]);
65 public static Shape[] getShapesBack(net.sf.openrocket.rocketcomponent.RocketComponent component,
66 Transformation transformation) {
68 net.sf.openrocket.rocketcomponent.FinSet finset = (net.sf.openrocket.rocketcomponent.FinSet)component;
70 if (MathUtil.equals(finset.getCantAngle(),0))
71 return uncantedShapesBack(finset, transformation);
73 return cantedShapesBack(finset, transformation);
78 private static Shape[] uncantedShapesBack(net.sf.openrocket.rocketcomponent.FinSet finset,
79 Transformation transformation) {
81 int fins = finset.getFinCount();
82 double radius = finset.getBodyRadius();
83 double thickness = finset.getThickness();
84 double height = finset.getSpan();
86 Transformation baseRotation = finset.getBaseRotationTransformation();
87 Transformation finRotation = finset.getFinRotationTransformation();
90 // Generate base coordinates for a single fin
91 Coordinate c[] = new Coordinate[4];
92 c[0]=new Coordinate(0,radius,-thickness/2);
93 c[1]=new Coordinate(0,radius,thickness/2);
94 c[2]=new Coordinate(0,height+radius,thickness/2);
95 c[3]=new Coordinate(0,height+radius,-thickness/2);
97 // Apply base rotation
98 transformPoints(c,baseRotation);
101 Shape[] s = new Shape[fins];
102 for (int fin=0; fin<fins; fin++) {
107 p = new Path2D.Double();
108 a = transformation.transform(finset.toAbsolute(c[0])[0]);
109 p.moveTo(a.z*S, a.y*S);
110 a = transformation.transform(finset.toAbsolute(c[1])[0]);
111 p.lineTo(a.z*S, a.y*S);
112 a = transformation.transform(finset.toAbsolute(c[2])[0]);
113 p.lineTo(a.z*S, a.y*S);
114 a = transformation.transform(finset.toAbsolute(c[3])[0]);
115 p.lineTo(a.z*S, a.y*S);
119 // Rotate fin coordinates
120 transformPoints(c,finRotation);
127 // TODO: LOW: Jagged shapes from back draw incorrectly.
128 private static Shape[] cantedShapesBack(net.sf.openrocket.rocketcomponent.FinSet finset,
129 Transformation transformation) {
131 int fins = finset.getFinCount();
132 double radius = finset.getBodyRadius();
133 double thickness = finset.getThickness();
135 Transformation baseRotation = finset.getBaseRotationTransformation();
136 Transformation finRotation = finset.getFinRotationTransformation();
137 Transformation cantRotation = finset.getCantRotation();
139 Coordinate[] sidePoints;
140 Coordinate[] backPoints;
143 Coordinate[] points = finset.getFinPoints();
144 for (maxIndex = points.length-1; maxIndex > 0; maxIndex--) {
145 if (points[maxIndex-1].y < points[maxIndex].y)
149 transformPoints(points,cantRotation);
150 transformPoints(points,new Transformation(0,radius,0));
151 transformPoints(points,baseRotation);
154 sidePoints = new Coordinate[points.length];
155 backPoints = new Coordinate[2*(points.length-maxIndex)];
157 if (finset.getCantAngle() > 0) {
163 // Calculate points for the side panel
164 for (i=0; i < points.length; i++) {
165 sidePoints[i] = points[i].add(0,0,sign*thickness/2);
168 // Calculate points for the back portion
170 for (int j=points.length-1; j >= maxIndex; j--, i++) {
171 backPoints[i] = points[j].add(0,0,sign*thickness/2);
173 for (int j=maxIndex; j <= points.length-1; j++, i++) {
174 backPoints[i] = points[j].add(0,0,-sign*thickness/2);
179 if (thickness > 0.0005) {
181 s = new Shape[fins*2];
182 for (int fin=0; fin<fins; fin++) {
184 s[2*fin] = makePolygonBack(sidePoints,finset,transformation);
185 s[2*fin+1] = makePolygonBack(backPoints,finset,transformation);
187 // Rotate fin coordinates
188 transformPoints(sidePoints,finRotation);
189 transformPoints(backPoints,finRotation);
195 for (int fin=0; fin<fins; fin++) {
196 s[fin] = makePolygonBack(sidePoints,finset,transformation);
197 transformPoints(sidePoints,finRotation);
207 private static void transformPoints(Coordinate[] array, Transformation t) {
208 for (int i=0; i < array.length; i++) {
209 array[i] = t.transform(array[i]);
213 private static Shape makePolygonBack(Coordinate[] array, net.sf.openrocket.rocketcomponent.FinSet finset,
218 p = new Path2D.Float();
219 for (int i=0; i < array.length; i++) {
220 Coordinate a = t.transform(finset.toAbsolute(array[i])[0]);
222 p.moveTo(a.z*S, a.y*S);
224 p.lineTo(a.z*S, a.y*S);
231 /* Side painting with thickness:
233 Coordinate c[] = new Coordinate[8];
235 c[0]=new Coordinate(0-position*rootChord,radius,thickness/2);
236 c[1]=new Coordinate(rootChord-position*rootChord,radius,thickness/2);
237 c[2]=new Coordinate(sweep+tipChord-position*rootChord,height+radius,thickness/2);
238 c[3]=new Coordinate(sweep-position*rootChord,height+radius,thickness/2);
240 c[4]=new Coordinate(0-position*rootChord,radius,-thickness/2);
241 c[5]=new Coordinate(rootChord-position*rootChord,radius,-thickness/2);
242 c[6]=new Coordinate(sweep+tipChord-position*rootChord,height+radius,-thickness/2);
243 c[7]=new Coordinate(sweep-position*rootChord,height+radius,-thickness/2);
246 rot = Transformation.rotate_x(rotation);
247 for (int i=0; i<8; i++)
248 c[i] = rot.transform(c[i]);
251 Shape[] s = new Shape[fins*6];
252 rot = Transformation.rotate_x(2*Math.PI/fins);
254 for (int fin=0; fin<fins; fin++) {
259 p = new Path2D.Float();
260 a = finset.toAbsolute(c[0]);
261 p.moveTo(a.x(), a.y());
262 a = finset.toAbsolute(c[1]);
263 p.lineTo(a.x(), a.y());
264 a = finset.toAbsolute(c[2]);
265 p.lineTo(a.x(), a.y());
266 a = finset.toAbsolute(c[3]);
267 p.lineTo(a.x(), a.y());
272 p = new Path2D.Float();
273 a = finset.toAbsolute(c[4]);
274 p.moveTo(a.x(), a.y());
275 a = finset.toAbsolute(c[5]);
276 p.lineTo(a.x(), a.y());
277 a = finset.toAbsolute(c[6]);
278 p.lineTo(a.x(), a.y());
279 a = finset.toAbsolute(c[7]);
280 p.lineTo(a.x(), a.y());
285 for (int i=0; i<4; i++) {
286 a = finset.toAbsolute(c[i]);
287 b = finset.toAbsolute(c[i+4]);
288 s[fin*6+2+i] = new Line2D.Float((float)a.x(),(float)a.y(),(float)b.x(),(float)b.y());
291 // Rotate fin coordinates
292 for (int i=0; i<8; i++)
293 c[i] = rot.transform(c[i]);