[#2231] Account for fin cant in root points
This commit is contained in:
parent
103a981bca
commit
d728a27ee9
@ -36,11 +36,18 @@ public class EllipticalFinSet extends FinSet {
|
||||
@Override
|
||||
public Coordinate[] getFinPoints() {
|
||||
double len = MathUtil.max(length, 0.0001);
|
||||
Coordinate[] points = new Coordinate[POINTS];
|
||||
Coordinate[] finPoints = new Coordinate[POINTS];
|
||||
for (int i = 0; i < POINTS; i++) {
|
||||
points[i] = new Coordinate(POINT_X[i] * len, POINT_Y[i] * height);
|
||||
finPoints[i] = new Coordinate(POINT_X[i] * len, POINT_Y[i] * height);
|
||||
}
|
||||
return points;
|
||||
|
||||
// Set the start and end fin points the same as the root points (necessary for canted fins)
|
||||
final Coordinate[] rootPoints = getRootPoints();
|
||||
if (rootPoints.length > 1) {
|
||||
finPoints[0] = finPoints[0].setX(rootPoints[0].x).setY(rootPoints[0].y);
|
||||
finPoints[finPoints.length - 1] = finPoints[finPoints.length - 1].setX(rootPoints[rootPoints.length - 1].x).setY(rootPoints[rootPoints.length - 1].y);
|
||||
}
|
||||
return finPoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1025,14 +1025,14 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
|
||||
* @return points representing the fin-root points, relative to ( x: fin-front, y: centerline ) i.e. relto: fin Component reference point
|
||||
*/
|
||||
public Coordinate[] getRootPoints(final int maximumBodyDivisionCount) {
|
||||
if( null == parent){
|
||||
if (parent == null) {
|
||||
return new Coordinate[]{Coordinate.ZERO};
|
||||
}
|
||||
|
||||
final Coordinate finLead = getFinFront();
|
||||
final double xFinEnd = finLead.x + getLength();
|
||||
|
||||
return getMountPoints( finLead.x, xFinEnd, -finLead.x, -finLead.y, maximumBodyDivisionCount);
|
||||
return getMountPoints(finLead.x, xFinEnd, -finLead.x, -finLead.y, maximumBodyDivisionCount);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1075,11 +1075,11 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
|
||||
|
||||
// for a simple body, one increment is perfectly accurate.
|
||||
int divisionCount = 1;
|
||||
final SymmetricComponent body = (SymmetricComponent) getParent();
|
||||
final SymmetricComponent parent = (SymmetricComponent) getParent();
|
||||
final double intervalLength = xEnd - xStart;
|
||||
|
||||
// for anything more complicated, increase the count:
|
||||
if ((body instanceof Transition) && (((Transition)body).getShapeType() != Shape.CONICAL)) {
|
||||
if ((!MathUtil.equals(getCantAngle(), 0)) || (parent instanceof Transition) && (((Transition)parent).getShapeType() != Shape.CONICAL)) {
|
||||
// the maximum precision to enforce when calculating the areas of fins (especially on curved parent bodies)
|
||||
final double xWidth = 0.0025; // width (in meters) of each individual iteration
|
||||
divisionCount = (int) Math.ceil(intervalLength / xWidth);
|
||||
@ -1093,13 +1093,18 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
|
||||
double xIncrement = intervalLength / divisionCount;
|
||||
|
||||
// Create the points: step through the radius of the parent
|
||||
double xCur = xStart;
|
||||
double xCurr = xStart;
|
||||
List<Coordinate> points = new ArrayList<>();
|
||||
for (int index = 0; index < divisionCount+1; index++) {
|
||||
double yCur = body.getRadius(xCur);
|
||||
points.add(new Coordinate(xCur, yCur));
|
||||
double yCurr = parent.getRadius(xCurr);
|
||||
|
||||
xCur += xIncrement;
|
||||
// Account for the fin cant angle
|
||||
final double dy = getFinCantYOffset(xStart, xEnd, xCurr);
|
||||
yCurr += dy;
|
||||
|
||||
points.add(new Coordinate(xCurr, yCurr));
|
||||
|
||||
xCurr += xIncrement;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1107,11 +1112,11 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
|
||||
then we need to add an extra root point at the front of the parent. Same goes for the last point, but vice versa.
|
||||
This ensures that fins are drawn correctly on transitions and nose cones (see GitHub issue #1021 for more info).
|
||||
*/
|
||||
// Front fin point is outside the parent's bounds and last point is still within the parent's bounds
|
||||
// Front fin point is outside the parent's bounds and last point is beyond the parent's fore end
|
||||
if (xStart < 0 && xEnd > 0) {
|
||||
points.add(1, new Coordinate(0, points.get(0).y));
|
||||
}
|
||||
// End fin point is outside the parent's bounds and first point is still within the parent's bounds
|
||||
// End fin point is beyond the parent's aft and first point is still before the parent's aft end
|
||||
if (xEnd > parent.length && xStart < parent.length) {
|
||||
final double x = parent.length;
|
||||
final double y = points.get(points.size() - 1).y;
|
||||
@ -1122,8 +1127,8 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
|
||||
|
||||
// correct last point, if beyond a rounding error from body's end.
|
||||
final int lastIndex = rootPoints.length - 1;
|
||||
if (Math.abs(rootPoints[lastIndex].x - body.getLength()) < MathUtil.EPSILON) {
|
||||
rootPoints[lastIndex] = rootPoints[lastIndex].setX(body.getLength()).setY(body.getAftRadius());
|
||||
if (Math.abs(rootPoints[lastIndex].x - parent.getLength()) < MathUtil.EPSILON) {
|
||||
rootPoints[lastIndex] = rootPoints[lastIndex].setX(parent.getLength());
|
||||
}
|
||||
|
||||
// translate the points if needed
|
||||
@ -1138,6 +1143,51 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona
|
||||
return getMountPoints(xStart, xEnd, xOffset, yOffset, MAX_ROOT_DIVISIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a y offset that should be applied to the fin root point at the given x position to account for the fin cant.
|
||||
* @param xStart The x position of the fin root point at the front of the fin.
|
||||
* @param xEnd The x position of the fin root point at the back of the fin.
|
||||
* @param xCurr The x position of the fin root point to calculate the y offset for.
|
||||
* @return The y offset to apply to the fin root point at the given x position.
|
||||
*/
|
||||
private double getFinCantYOffset(final double xStart, final double xEnd, double xCurr) {
|
||||
final SymmetricComponent parent = (SymmetricComponent) getParent();
|
||||
final double cantAngle = getCantAngle();
|
||||
|
||||
if (MathUtil.equals(cantAngle, 0) || (xStart > parent.length && xEnd > parent.length) || (xStart < 0 && xEnd < 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Limit the x position to the parent's bounds
|
||||
double x = Math.max(xCurr, 0);
|
||||
x = Math.min(x, parent.getLength());
|
||||
|
||||
// Determine the center of rotation
|
||||
final double xCenter = (xStart + xEnd) / 2;
|
||||
|
||||
// Calculate the new x position after rotation
|
||||
final double dx = x - xCenter; // Distance to the center of rotation
|
||||
final double xCurr_rot = xCenter + dx * Math.abs(Math.cos(cantAngle)); // X coordinate after rotation
|
||||
|
||||
// Extend the root of the fin to touch the surface of the parent
|
||||
final double radius_rot = parent.getRadius(xCurr_rot);
|
||||
final double dz = Math.abs(Math.sin(cantAngle)) * dx;
|
||||
|
||||
final double dy;
|
||||
if (dz >= radius_rot) {
|
||||
dy = 0;
|
||||
} else {
|
||||
/*
|
||||
Simplification of r^2 = (r-dy)^2 + dz^2, given that dz < r. (to derive this, draw
|
||||
the cross-section of the body, which is just a circle, with a tangent line starting on the top of the circle
|
||||
and reaching a distance dz. Use some Pythagorean theorem and bam, you got this equation.)
|
||||
*/
|
||||
dy = radius_rot - Math.sqrt(Math.pow(radius_rot, 2) - Math.pow(dz, 2));
|
||||
}
|
||||
|
||||
return -dy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of coordinates defining the geometry of a single fin, including the parent's body points .
|
||||
*/
|
||||
|
@ -392,7 +392,16 @@ public class FreeformFinSet extends FinSet {
|
||||
|
||||
@Override
|
||||
public Coordinate[] getFinPoints() {
|
||||
return points.toArray(new Coordinate[0]);
|
||||
Coordinate[] finPoints = points.toArray(new Coordinate[0]);
|
||||
|
||||
// Set the start and end fin points the same as the root points (necessary for canted fins)
|
||||
final Coordinate[] rootPoints = getRootPoints();
|
||||
if (rootPoints.length > 1) {
|
||||
finPoints[0] = finPoints[0].setX(rootPoints[0].x).setY(rootPoints[0].y);
|
||||
finPoints[finPoints.length - 1] = finPoints[finPoints.length - 1].setX(rootPoints[rootPoints.length - 1].x).setY(rootPoints[rootPoints.length - 1].y);
|
||||
}
|
||||
|
||||
return finPoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -193,16 +193,25 @@ public class TrapezoidFinSet extends FinSet {
|
||||
*/
|
||||
@Override
|
||||
public Coordinate[] getFinPoints() {
|
||||
List<Coordinate> list = new ArrayList<Coordinate>(4);
|
||||
|
||||
list.add(Coordinate.NUL);
|
||||
list.add(new Coordinate(sweep, height));
|
||||
List<Coordinate> points = new ArrayList<>(4);
|
||||
|
||||
points.add(Coordinate.NUL);
|
||||
points.add(new Coordinate(sweep, height));
|
||||
if (tipChord > 0.0001) {
|
||||
list.add(new Coordinate(sweep + tipChord, height));
|
||||
points.add(new Coordinate(sweep + tipChord, height));
|
||||
}
|
||||
points.add(new Coordinate(MathUtil.max(length, 0.0001), 0));
|
||||
|
||||
Coordinate[] finPoints = points.toArray(new Coordinate[0]);
|
||||
|
||||
// Set the start and end fin points the same as the root points (necessary for canted fins)
|
||||
final Coordinate[] rootPoints = getRootPoints();
|
||||
if (rootPoints.length > 1) {
|
||||
finPoints[0] = finPoints[0].setX(rootPoints[0].x).setY(rootPoints[0].y);
|
||||
finPoints[finPoints.length - 1] = finPoints[finPoints.length - 1].setX(rootPoints[rootPoints.length - 1].x).setY(rootPoints[rootPoints.length - 1].y);
|
||||
}
|
||||
list.add(new Coordinate(MathUtil.max(length, 0.0001), 0));
|
||||
|
||||
return list.toArray(new Coordinate[list.size()]);
|
||||
return finPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user