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.newUserMaterial(Material.Type.BULK,"test",density));
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.newUserMaterial(Material.Type.BULK,"test",density));
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.newUserMaterial(Material.Type.BULK,"test",density));
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.newUserMaterial(Material.Type.BULK,"test",density));
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.newUserMaterial(Material.Type.BULK,"test",density));
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.newUserMaterial(Material.Type.BULK,"test",density));
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.newUserMaterial(Material.Type.BULK,"test",density));
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.newUserMaterial(Material.Type.BULK,"test",density));
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.newUserMaterial(Material.Type.BULK,"test",density));
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 * ( innerTransitionAftRadius * innerTransitionAftRadius + innerTransitionAftRadius * innerTransitionForeRadius + innerTransitionForeRadius * innerTransitionForeRadius);
375 double volume = filledVolume - innerVolume;
377 double mass = density * volume;
379 System.out.println( volume );
381 assertEquals( volume, nc.getComponentVolume(), epsilonPercent * volume);
382 assertEquals( mass, nc.getMass(), epsilonPercent * mass );
384 assertEquals( 0.56827, cg.x, epsilonPercent * 0.56827 );
385 assertEquals( mass, cg.weight, epsilonPercent * mass);
389 public void simpleTransitionWithShouldersHollow2() {
390 Transition nc = new Transition();
392 final double epsilonPercent = 0.001;
393 final double density = 2.0;
396 nc.setType( Transition.Shape.CONICAL );
397 nc.setForeRadius(0.5);
398 nc.setAftRadius(1.0);
399 nc.setThickness(0.25);
400 nc.setAftShoulderLength(1.0);
401 nc.setAftShoulderRadius(1.0);
402 nc.setAftShoulderThickness(0.25);
403 nc.setForeShoulderLength(1.0);
404 nc.setForeShoulderRadius(0.5);
405 nc.setForeShoulderThickness(0.25);
407 nc.setMaterial( Material.newUserMaterial(Material.Type.BULK,"test",density));
409 Coordinate cg = nc.getCG();
411 System.out.println( nc.getComponentVolume() + "\t" + nc.getMass());
412 System.out.println( cg );
414 // Volume of filled transition =
415 double filledVolume = Math.PI /3.0 * ( 1.0*1.0 + 1.0 * 0.5 + 0.5 * 0.5 ) * 1.0;
417 // magic 2D cad drawing...
419 // Since the thickness < fore radius, the
420 // hollowed out portion of the transition
421 // forms a transition.
422 // the dimensions of this transition were determined
423 // using a 2d cad tool.
425 double innerTransitionAftRadius = 0.7205;
426 double innerTransitionForeRadius = 0.2205;
427 double innerVolume = Math.PI /3.0 * ( innerTransitionAftRadius * innerTransitionAftRadius + innerTransitionAftRadius * innerTransitionForeRadius + innerTransitionForeRadius * innerTransitionForeRadius);
429 double volume = filledVolume - innerVolume;
431 // now add aft shoulder
432 volume += Math.PI * 1.0 * 1.0 * 1.0 - Math.PI * 1.0 * 0.75 * 0.75;
433 // now add fore shoulder
434 volume += Math.PI * 1.0 * 0.5 * 0.5 - Math.PI * 1.0 * 0.25 * 0.25;
437 double mass = density * volume;
439 System.out.println( volume );
441 assertEquals( volume, nc.getComponentVolume(), epsilonPercent * volume);
442 assertEquals( mass, nc.getMass(), epsilonPercent * mass );
444 assertEquals( 0.7829, cg.x, epsilonPercent * 0.7829 );
445 assertEquals( mass, cg.weight, epsilonPercent * mass);