Instead of incrementing through the slices of the component, multiply to recalculate each slice (from some comments in the code I suspect there were some problems with floating point error accumulating).
Increase the number of divisions to 128, so division is just an exponent change and won't cause floating point error a little tidying
This commit is contained in:
parent
ff6b23f366
commit
e92e2bc3a9
@ -23,7 +23,7 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
|||||||
public static final double DEFAULT_RADIUS = 0.025;
|
public static final double DEFAULT_RADIUS = 0.025;
|
||||||
public static final double DEFAULT_THICKNESS = 0.002;
|
public static final double DEFAULT_THICKNESS = 0.002;
|
||||||
|
|
||||||
private static final int DIVISIONS = 100; // No. of divisions when integrating
|
private static final int DIVISIONS = 128; // No. of divisions when integrating
|
||||||
|
|
||||||
protected boolean filled = false;
|
protected boolean filled = false;
|
||||||
protected double thickness = DEFAULT_THICKNESS;
|
protected double thickness = DEFAULT_THICKNESS;
|
||||||
@ -332,9 +332,6 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
|||||||
* Performs integration over the length of the component and updates the cached variables.
|
* Performs integration over the length of the component and updates the cached variables.
|
||||||
*/
|
*/
|
||||||
private void integrate() {
|
private void integrate() {
|
||||||
double x, r1, r2;
|
|
||||||
double cgx;
|
|
||||||
|
|
||||||
wetArea = 0;
|
wetArea = 0;
|
||||||
planArea = 0;
|
planArea = 0;
|
||||||
planCenter = 0;
|
planCenter = 0;
|
||||||
@ -343,6 +340,8 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
|||||||
cg = Coordinate.NUL;
|
cg = Coordinate.NUL;
|
||||||
longitudinalInertia = 0;
|
longitudinalInertia = 0;
|
||||||
rotationalInertia = 0;
|
rotationalInertia = 0;
|
||||||
|
|
||||||
|
double cgx = 0;
|
||||||
|
|
||||||
// Check length > 0
|
// Check length > 0
|
||||||
if (getLength() <= 0) {
|
if (getLength() <= 0) {
|
||||||
@ -350,27 +349,18 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Integrate for volume, CG, wetted area, planform area, and moments of inertia
|
// Integrate for volume, CG, wetted area, planform area, and moments of inertia
|
||||||
|
for (int n = 0; n < DIVISIONS; n++) {
|
||||||
final double l = getLength() / DIVISIONS;
|
|
||||||
final double pi3 = Math.PI / 3.0;
|
|
||||||
final double pil = Math.PI * l;
|
|
||||||
final double pil3 = Math.PI * l / 3;
|
|
||||||
|
|
||||||
r1 = getRadius(0);
|
|
||||||
x = 0;
|
|
||||||
cgx = 0;
|
|
||||||
|
|
||||||
for (int n = 1; n <= DIVISIONS; n++) {
|
|
||||||
/*
|
/*
|
||||||
* r1 and r2 are the two radii
|
* x1 and x2 are the bounds on this section
|
||||||
* x is the position of r1
|
|
||||||
* hyp is the length of the hypotenuse from r1 to r2
|
* hyp is the length of the hypotenuse from r1 to r2
|
||||||
* height is the y-axis height of the component if not filled
|
* height is the y-axis height of the component if not filled
|
||||||
*/
|
*/
|
||||||
|
final double x1 = n * getLength() / DIVISIONS;
|
||||||
// Further to prevent round off error from the previous statement,
|
final double r1 = getRadius(x1);
|
||||||
// we clamp r2 to length at the last iteration.
|
final double x2 = (n + 1) * getLength() / DIVISIONS;
|
||||||
r2 = getRadius((n==DIVISIONS) ? getLength() : x + l);
|
final double r2 = getRadius(x2);
|
||||||
|
final double l = x2 - x1;
|
||||||
|
final double xmean = (x1 + x2) / 2;
|
||||||
|
|
||||||
final double outer = (r1 + r2) / 2;
|
final double outer = (r1 + r2) / 2;
|
||||||
final double hyp = MathUtil.hypot(r2 - r1, l);
|
final double hyp = MathUtil.hypot(r2 - r1, l);
|
||||||
@ -381,7 +371,7 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
|||||||
final double dV;
|
final double dV;
|
||||||
final double dFullV;
|
final double dFullV;
|
||||||
|
|
||||||
dFullV = pi3 * l * (r1 * r1 + r1 * r2 + r2 * r2);
|
dFullV = Math.PI * l * (r1 * r1 + r1 * r2 + r2 * r2) / 3.0;
|
||||||
|
|
||||||
if ( filled || r1 < height || r2 < height ) {
|
if ( filled || r1 < height || r2 < height ) {
|
||||||
inner = 0;
|
inner = 0;
|
||||||
@ -405,7 +395,7 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
|||||||
// Add to the volume-related components
|
// Add to the volume-related components
|
||||||
volume += dV;
|
volume += dV;
|
||||||
fullVolume += dFullV;
|
fullVolume += dFullV;
|
||||||
cgx += (x + l / 2) * dV;
|
cgx += xmean * dV;
|
||||||
|
|
||||||
// Wetted area ( * PI at the end)
|
// Wetted area ( * PI at the end)
|
||||||
wetArea += hyp * (r1 + r2);
|
wetArea += hyp * (r1 + r2);
|
||||||
@ -413,14 +403,10 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
|||||||
// Planform area & center
|
// Planform area & center
|
||||||
final double p = l * (r1 + r2);
|
final double p = l * (r1 + r2);
|
||||||
planArea += p;
|
planArea += p;
|
||||||
planCenter += (x + l / 2) * p;
|
planCenter += xmean * p;
|
||||||
|
|
||||||
rotationalInertia += dV * (pow2(outer) + pow2(inner)) / 2;
|
rotationalInertia += dV * (pow2(outer) + pow2(inner)) / 2;
|
||||||
longitudinalInertia += dV * ((3 * (pow2(outer) + pow2(inner)) + pow2(l)) / 12 + pow2(x + l / 2));
|
longitudinalInertia += dV * ((3 * (pow2(outer) + pow2(inner)) + pow2(l)) / 12 + pow2(xmean));
|
||||||
|
|
||||||
// Update for next iteration
|
|
||||||
r1 = r2;
|
|
||||||
x += l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wetArea *= Math.PI;
|
wetArea *= Math.PI;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user