1 package net.sf.openrocket.rocketcomponent;
3 import static org.junit.Assert.assertEquals;
4 import net.sf.openrocket.material.Material;
5 import net.sf.openrocket.util.Coordinate;
6 import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
10 public class SymmetricComponentVolumeTest extends BaseTestCase {
13 public void simpleConeFilled() {
14 NoseCone nc = new NoseCone();
16 final double epsilonPercent = 0.001;
17 final double density = 2.0;
21 nc.setType(Transition.Shape.CONICAL);
23 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
25 Coordinate cg = nc.getCG();
27 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
28 System.out.println(cg);
30 double volume = Math.PI / 3.0;
32 double mass = density * volume;
34 System.out.println(volume);
36 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
37 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
39 assertEquals(0.75, cg.x, epsilonPercent * 0.75);
40 assertEquals(mass, cg.weight, epsilonPercent * mass);
44 public void simpleConeWithShoulderFilled() {
45 NoseCone nc = new NoseCone();
47 final double epsilonPercent = 0.001;
48 final double density = 2.0;
52 nc.setType(Transition.Shape.CONICAL);
54 nc.setAftShoulderRadius(1.0);
55 nc.setAftShoulderLength(1.0);
56 nc.setAftShoulderThickness(1.0);
57 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
59 Coordinate cg = nc.getCG();
61 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
62 System.out.println(cg);
64 double volume = Math.PI / 3.0;
67 double mass = density * volume;
69 System.out.println(volume + "\t" + mass);
71 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
72 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
74 assertEquals(1.312, cg.x, epsilonPercent * 1.071);
75 assertEquals(mass, cg.weight, epsilonPercent * mass);
79 public void simpleConeHollow() {
80 NoseCone nc = new NoseCone();
82 final double epsilonPercent = 0.001;
83 final double density = 2.0;
88 nc.setType(Transition.Shape.CONICAL);
89 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
91 Coordinate cg = nc.getCG();
93 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
94 System.out.println(cg);
96 double volume = Math.PI / 3.0; // outer volume
98 // manually projected Thickness of 0.5 on to radius to determine
99 // the innerConeDimen. Since the outer cone is "square" (height = radius),
100 // we only need to compute this one dimension in order to compute the
101 // volume of the inner cone.
102 double innerConeDimen = 1.0 - Math.sqrt(2.0) / 2.0;
103 double innerVolume = Math.PI / 3.0 * innerConeDimen * innerConeDimen * innerConeDimen;
104 volume -= innerVolume;
106 double mass = density * volume;
108 System.out.println(volume);
110 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
111 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
113 assertEquals(0.7454, cg.x, epsilonPercent * 0.7454);
114 assertEquals(mass, cg.weight, epsilonPercent * mass);
118 public void simpleConeWithShoulderHollow() {
119 NoseCone nc = new NoseCone();
121 final double epsilonPercent = 0.001;
122 final double density = 2.0;
125 nc.setType(Transition.Shape.CONICAL);
126 nc.setAftRadius(1.0);
127 nc.setThickness(0.5);
128 nc.setAftShoulderRadius(1.0);
129 nc.setAftShoulderLength(1.0);
130 nc.setAftShoulderThickness(0.5);
131 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
133 Coordinate cg = nc.getCG();
135 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
136 System.out.println(cg);
138 double volume = Math.PI / 3.0; // outer volume
140 // manually projected Thickness of 0.5 on to radius to determine
141 // the innerConeDimen. Since the outer cone is "square" (height = radius),
142 // we only need to compute this one dimension in order to compute the
143 // volume of the inner cone.
144 double innerConeDimen = 1.0 - Math.sqrt(2.0) / 2.0;
145 double innerVolume = Math.PI / 3.0 * innerConeDimen * innerConeDimen * innerConeDimen;
146 volume -= innerVolume;
148 volume += Math.PI - Math.PI * 0.5 * 0.5;
151 double mass = density * volume;
153 System.out.println(volume);
155 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
156 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
158 assertEquals(1.2719, cg.x, epsilonPercent * 1.2719);
159 assertEquals(mass, cg.weight, epsilonPercent * mass);
163 public void simpleTransitionFilled() {
164 Transition nc = new Transition();
166 final double epsilonPercent = 0.001;
167 final double density = 2.0;
171 nc.setType(Transition.Shape.CONICAL);
172 nc.setForeRadius(1.0);
173 nc.setAftRadius(2.0);
174 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
176 Coordinate cg = nc.getCG();
178 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
179 System.out.println(cg);
181 double volume = Math.PI / 3.0 * (2.0 * 2.0 + 2.0 * 1.0 + 1.0 * 1.0) * 4.0;
183 double mass = density * volume;
185 System.out.println(volume);
187 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
188 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
190 assertEquals(2.4285, cg.x, epsilonPercent * 2.4285);
191 assertEquals(mass, cg.weight, epsilonPercent * mass);
195 public void simpleTransitionWithShouldersFilled() {
196 Transition nc = new Transition();
198 final double epsilonPercent = 0.001;
199 final double density = 2.0;
203 nc.setType(Transition.Shape.CONICAL);
204 nc.setForeRadius(1.0);
205 nc.setAftRadius(2.0);
206 nc.setAftShoulderLength(1.0);
207 nc.setAftShoulderRadius(2.0);
208 nc.setAftShoulderThickness(2.0);
209 nc.setForeShoulderLength(1.0);
210 nc.setForeShoulderRadius(1.0);
211 nc.setForeShoulderThickness(1.0);
212 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
214 Coordinate cg = nc.getCG();
216 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
217 System.out.println(cg);
219 double volume = Math.PI / 3.0 * (2.0 * 2.0 + 2.0 * 1.0 + 1.0 * 1.0) * 4.0;
220 // plus aft shoulder:
221 volume += Math.PI * 1.0 * 2.0 * 2.0;
222 // plus fore shoulder:
223 volume += Math.PI * 1.0 * 1.0 * 1.0;
225 double mass = density * volume;
227 System.out.println(volume);
229 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
230 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
232 assertEquals(2.8023, cg.x, epsilonPercent * 2.8023);
233 assertEquals(mass, cg.weight, epsilonPercent * mass);
237 public void simpleTransitionHollow1() {
238 Transition nc = new Transition();
240 final double epsilonPercent = 0.001;
241 final double density = 2.0;
244 nc.setType(Transition.Shape.CONICAL);
245 nc.setForeRadius(0.5);
246 nc.setAftRadius(1.0);
247 nc.setThickness(0.5);
248 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
250 Coordinate cg = nc.getCG();
252 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
253 System.out.println(cg);
255 // Volume of filled transition =
256 double filledVolume = Math.PI / 3.0 * (1.0 * 1.0 + 1.0 * 0.5 + 0.5 * 0.5) * 1.0;
258 // magic 2D cad drawing...
260 // Since the thickness >= fore radius, the
261 // hollowed out portion of the transition
263 // the dimensions of this cone were determined
264 // using a 2d cad tool.
266 double innerConeRadius = 0.441;
267 double innerConeLength = 0.882;
268 double innerVolume = Math.PI / 3.0 * innerConeLength * innerConeRadius * innerConeRadius;
270 double volume = filledVolume - innerVolume;
272 double mass = density * volume;
274 System.out.println(volume);
276 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
277 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
279 assertEquals(0.5884, cg.x, epsilonPercent * 0.5884);
280 assertEquals(mass, cg.weight, epsilonPercent * mass);
284 public void simpleTransitionWithShouldersHollow1() {
285 Transition nc = new Transition();
287 final double epsilonPercent = 0.001;
288 final double density = 2.0;
291 nc.setType(Transition.Shape.CONICAL);
292 nc.setForeRadius(0.5);
293 nc.setAftRadius(1.0);
294 nc.setThickness(0.5);
295 nc.setAftShoulderLength(1.0);
296 nc.setAftShoulderRadius(1.0);
297 nc.setAftShoulderThickness(0.5);
298 nc.setForeShoulderLength(1.0);
299 nc.setForeShoulderRadius(0.5);
300 nc.setForeShoulderThickness(0.5); // note this means fore shoulder is filled.
301 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
303 Coordinate cg = nc.getCG();
305 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
306 System.out.println(cg);
308 // Volume of filled transition =
309 double filledVolume = Math.PI / 3.0 * (1.0 * 1.0 + 1.0 * 0.5 + 0.5 * 0.5) * 1.0;
311 // magic 2D cad drawing...
313 // Since the thickness >= fore radius, the
314 // hollowed out portion of the transition
316 // the dimensions of this cone were determined
317 // using a 2d cad tool.
319 double innerConeRadius = 0.441;
320 double innerConeLength = 0.882;
321 double innerVolume = Math.PI / 3.0 * innerConeLength * innerConeRadius * innerConeRadius;
323 double volume = filledVolume - innerVolume;
325 // Now add aft shoulder
326 volume += Math.PI * 1.0 * 1.0 * 1.0 - Math.PI * 1.0 * 0.5 * 0.5;
327 // Now add fore shoulder
328 volume += Math.PI * 1.0 * 0.5 * 0.5;
330 double mass = density * volume;
332 System.out.println(volume);
334 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
335 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
337 assertEquals(0.8581, cg.x, epsilonPercent * 0.8581);
338 assertEquals(mass, cg.weight, epsilonPercent * mass);
342 public void simpleTransitionHollow2() {
343 Transition nc = new Transition();
345 final double epsilonPercent = 0.001;
346 final double density = 2.0;
349 nc.setType(Transition.Shape.CONICAL);
350 nc.setForeRadius(0.5);
351 nc.setAftRadius(1.0);
352 nc.setThickness(0.25);
353 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
355 Coordinate cg = nc.getCG();
357 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
358 System.out.println(cg);
360 // Volume of filled transition =
361 double filledVolume = Math.PI / 3.0 * (1.0 * 1.0 + 1.0 * 0.5 + 0.5 * 0.5) * 1.0;
363 // magic 2D cad drawing...
365 // Since the thickness < fore radius, the
366 // hollowed out portion of the transition
367 // forms a transition.
368 // the dimensions of this transition were determined
369 // using a 2d cad tool.
371 double innerTransitionAftRadius = 0.7205;
372 double innerTransitionForeRadius = 0.2205;
373 double innerVolume = Math.PI / 3.0
374 * (innerTransitionAftRadius * innerTransitionAftRadius + innerTransitionAftRadius * innerTransitionForeRadius + innerTransitionForeRadius * innerTransitionForeRadius);
376 double volume = filledVolume - innerVolume;
378 double mass = density * volume;
380 System.out.println(volume);
382 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
383 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
385 assertEquals(0.56827, cg.x, epsilonPercent * 0.56827);
386 assertEquals(mass, cg.weight, epsilonPercent * mass);
390 public void simpleTransitionWithShouldersHollow2() {
391 Transition nc = new Transition();
393 final double epsilonPercent = 0.001;
394 final double density = 2.0;
397 nc.setType(Transition.Shape.CONICAL);
398 nc.setForeRadius(0.5);
399 nc.setAftRadius(1.0);
400 nc.setThickness(0.25);
401 nc.setAftShoulderLength(1.0);
402 nc.setAftShoulderRadius(1.0);
403 nc.setAftShoulderThickness(0.25);
404 nc.setForeShoulderLength(1.0);
405 nc.setForeShoulderRadius(0.5);
406 nc.setForeShoulderThickness(0.25);
408 nc.setMaterial(Material.newMaterial(Material.Type.BULK, "test", density, true));
410 Coordinate cg = nc.getCG();
412 System.out.println(nc.getComponentVolume() + "\t" + nc.getMass());
413 System.out.println(cg);
415 // Volume of filled transition =
416 double filledVolume = Math.PI / 3.0 * (1.0 * 1.0 + 1.0 * 0.5 + 0.5 * 0.5) * 1.0;
418 // magic 2D cad drawing...
420 // Since the thickness < fore radius, the
421 // hollowed out portion of the transition
422 // forms a transition.
423 // the dimensions of this transition were determined
424 // using a 2d cad tool.
426 double innerTransitionAftRadius = 0.7205;
427 double innerTransitionForeRadius = 0.2205;
428 double innerVolume = Math.PI / 3.0
429 * (innerTransitionAftRadius * innerTransitionAftRadius + innerTransitionAftRadius * innerTransitionForeRadius + innerTransitionForeRadius * innerTransitionForeRadius);
431 double volume = filledVolume - innerVolume;
433 // now add aft shoulder
434 volume += Math.PI * 1.0 * 1.0 * 1.0 - Math.PI * 1.0 * 0.75 * 0.75;
435 // now add fore shoulder
436 volume += Math.PI * 1.0 * 0.5 * 0.5 - Math.PI * 1.0 * 0.25 * 0.25;
439 double mass = density * volume;
441 System.out.println(volume);
443 assertEquals(volume, nc.getComponentVolume(), epsilonPercent * volume);
444 assertEquals(mass, nc.getMass(), epsilonPercent * mass);
446 assertEquals(0.7829, cg.x, epsilonPercent * 0.7829);
447 assertEquals(mass, cg.weight, epsilonPercent * mass);