Merge pull request #506 from teyrana/fix_498_neg_inertia
Fixes #498 - Refactor of FreeformFinSet[Test]
This commit is contained in:
commit
090caed29e
@ -439,17 +439,25 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
* 5. Return twice that since there is a fillet on each side of the fin.
|
* 5. Return twice that since there is a fillet on each side of the fin.
|
||||||
*/
|
*/
|
||||||
protected Coordinate calculateFilletVolumeCentroid() {
|
protected Coordinate calculateFilletVolumeCentroid() {
|
||||||
Coordinate[] mountPoints = this.getRootPoints();
|
if((null == this.parent) || (!SymmetricComponent.class.isAssignableFrom(this.parent.getClass()))){
|
||||||
if( null == mountPoints ){
|
|
||||||
return Coordinate.ZERO;
|
return Coordinate.ZERO;
|
||||||
}
|
}
|
||||||
|
Coordinate[] mountPoints = this.getRootPoints();
|
||||||
|
// if( null == mountPoints ){
|
||||||
|
// return Coordinate.ZERO;
|
||||||
|
// }
|
||||||
|
|
||||||
final SymmetricComponent sym = (SymmetricComponent) this.parent;
|
final SymmetricComponent sym = (SymmetricComponent) this.parent;
|
||||||
if (!SymmetricComponent.class.isInstance(this.parent)) {
|
|
||||||
|
final Coordinate finLead = getFinFront();
|
||||||
|
final double xFinEnd = finLead.x + getLength();
|
||||||
|
final Coordinate[] rootPoints = getMountPoints( finLead.x, xFinEnd, -finLead.x, -finLead.y);
|
||||||
|
if (0 == rootPoints.length) {
|
||||||
return Coordinate.ZERO;
|
return Coordinate.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
Coordinate filletVolumeCentroid = Coordinate.ZERO;
|
Coordinate filletVolumeCentroid = Coordinate.ZERO;
|
||||||
|
|
||||||
Coordinate prev = mountPoints[0];
|
Coordinate prev = mountPoints[0];
|
||||||
for (int index = 1; index < mountPoints.length; index++) {
|
for (int index = 1; index < mountPoints.length; index++) {
|
||||||
final Coordinate cur = mountPoints[index];
|
final Coordinate cur = mountPoints[index];
|
||||||
@ -496,10 +504,9 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
for( int index = 1; index < points.length; index++){
|
for( int index = 1; index < points.length; index++){
|
||||||
Coordinate cur = points[index];
|
Coordinate cur = points[index];
|
||||||
|
|
||||||
|
// calculate marginal area
|
||||||
final double delta_x = (cur.x - prev.x);
|
final double delta_x = (cur.x - prev.x);
|
||||||
final double y_avg = (cur.y + prev.y)*0.5;
|
final double y_avg = (cur.y + prev.y)*0.5;
|
||||||
|
|
||||||
// calculate marginal area
|
|
||||||
double area_increment = delta_x*y_avg;
|
double area_increment = delta_x*y_avg;
|
||||||
if( MathUtil.equals( 0, area_increment)){
|
if( MathUtil.equals( 0, area_increment)){
|
||||||
prev = cur;
|
prev = cur;
|
||||||
@ -535,17 +542,14 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
final double xTabFront_fin = getTabFrontEdge();
|
final double xTabFront_fin = getTabFrontEdge();
|
||||||
final double xTabTrail_fin = getTabTrailingEdge();
|
final double xTabTrail_fin = getTabTrailingEdge();
|
||||||
|
|
||||||
final double xFinFront_body = this.getAxialFront();
|
final Coordinate finFront = getFinFront();
|
||||||
|
final double xFinFront_body = finFront.x;
|
||||||
final double xTabFront_body = xFinFront_body + xTabFront_fin;
|
final double xTabFront_body = xFinFront_body + xTabFront_fin;
|
||||||
final double xTabTrail_body = xFinFront_body + xTabTrail_fin;
|
final double xTabTrail_body = xFinFront_body + xTabTrail_fin;
|
||||||
|
|
||||||
// always returns x coordinates relTo fin front:
|
// get body points, relTo fin front / centerline);
|
||||||
Coordinate[] upperCurve = getMountInterval( xTabFront_body, xTabTrail_body );
|
final Coordinate[] upperCurve = getMountPoints( xTabFront_body, xTabTrail_body, -xFinFront_body, 0);
|
||||||
// locate relative to fin/body centerline
|
final Coordinate[] lowerCurve = translateToCenterline( getTabPoints());
|
||||||
upperCurve = translatePoints( upperCurve, -xFinFront_body, 0.0);
|
|
||||||
|
|
||||||
Coordinate[] lowerCurve = translateToCenterline( getTabPoints());
|
|
||||||
|
|
||||||
final Coordinate[] tabPoints = combineCurves( upperCurve, lowerCurve);
|
final Coordinate[] tabPoints = combineCurves( upperCurve, lowerCurve);
|
||||||
|
|
||||||
return calculateCurveIntegral( tabPoints );
|
return calculateCurveIntegral( tabPoints );
|
||||||
@ -559,27 +563,23 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calculates the 2-dimensional area-centroid of a single fin.
|
* The coordinate contains an x,y coordinate of the centroid, relative to the parent-body-centerline
|
||||||
*
|
* The weight contains the area of the fin.
|
||||||
* Located from the leading end of the fin root.
|
|
||||||
*
|
*
|
||||||
* @return area centroid coordinates (weight is the area)
|
* @return area centroid coordinates (weight is the area)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* The coordinate contains an x,y coordinate of the centroid, relative to the parent-body-centerline
|
|
||||||
*/
|
|
||||||
private Coordinate calculateSinglePlanformCentroid(){
|
private Coordinate calculateSinglePlanformCentroid(){
|
||||||
final Coordinate finFront = getFinFront();
|
final Coordinate finLead = getFinFront();
|
||||||
|
final double xFinTrail = finLead.x+getLength();
|
||||||
|
|
||||||
final Coordinate[] upperCurve = getFinPoints();
|
final Coordinate[] upperCurve = translatePoints(getFinPoints(), 0, finLead.y);
|
||||||
final Coordinate[] lowerCurve = getRootPoints();
|
final Coordinate[] lowerCurve = getMountPoints( finLead.x, xFinTrail, -finLead.x, 0);
|
||||||
final Coordinate[] totalCurve = combineCurves( upperCurve, lowerCurve);
|
final Coordinate[] totalCurve = combineCurves( upperCurve, lowerCurve);
|
||||||
|
|
||||||
Coordinate planformCentroid = calculateCurveIntegral( totalCurve );
|
final Coordinate planformCentroid = calculateCurveIntegral( totalCurve );
|
||||||
|
|
||||||
// return as a position relative to fin-root
|
// return as a position relative to fin-root
|
||||||
return planformCentroid.add(0., finFront.y, 0);
|
return planformCentroid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -592,15 +592,15 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
* @return combined curve
|
* @return combined curve
|
||||||
*/
|
*/
|
||||||
private Coordinate[] combineCurves( final Coordinate[] c1, final Coordinate[] c2){
|
private Coordinate[] combineCurves( final Coordinate[] c1, final Coordinate[] c2){
|
||||||
Coordinate[] combined = new Coordinate[ c1.length + c2.length - 1];
|
Coordinate[] combined = new Coordinate[ c1.length + c2.length];
|
||||||
|
|
||||||
// copy the first array to the start of the return array...
|
// copy the first array to the start of the return array...
|
||||||
System.arraycopy(c1, 0, combined, 0, c1.length);
|
System.arraycopy(c1, 0, combined, 0, c1.length);
|
||||||
|
|
||||||
Coordinate[] revCurve = reverse( c2);
|
Coordinate[] revCurve = reverse( c2);
|
||||||
int writeIndex = c1.length; // start directly after previous array
|
int writeIndex = c1.length; // start directly after previous array
|
||||||
int writeCount = revCurve.length - 1; // write all-but-first
|
int writeCount = revCurve.length;
|
||||||
System.arraycopy(revCurve, 1, combined, writeIndex, writeCount);
|
System.arraycopy(revCurve, 0, combined, writeIndex, writeCount);
|
||||||
|
|
||||||
return combined;
|
return combined;
|
||||||
}
|
}
|
||||||
@ -814,6 +814,11 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a copied list of the given input, translated by the delta
|
||||||
|
*
|
||||||
|
* @return List of XY-coordinates.
|
||||||
|
*/
|
||||||
protected static Coordinate[] translatePoints( final Coordinate[] inp, final double x_delta , final double y_delta){
|
protected static Coordinate[] translatePoints( final Coordinate[] inp, final double x_delta , final double y_delta){
|
||||||
Coordinate[] returnPoints = new Coordinate[inp.length];
|
Coordinate[] returnPoints = new Coordinate[inp.length];
|
||||||
for( int index=0; index < inp.length; ++index){
|
for( int index=0; index < inp.length; ++index){
|
||||||
@ -824,6 +829,21 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
return returnPoints;
|
return returnPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a copied list of the given input, translated by the delta
|
||||||
|
*
|
||||||
|
* @return List of XY-coordinates.
|
||||||
|
*/
|
||||||
|
protected static ArrayList<Coordinate> translatePoints( final ArrayList<Coordinate> inp, final Coordinate delta){
|
||||||
|
final ArrayList<Coordinate> returnPoints = new ArrayList<>();
|
||||||
|
returnPoints.ensureCapacity(inp.size());
|
||||||
|
|
||||||
|
for( Coordinate c: inp ){
|
||||||
|
returnPoints.add(c.add(delta));
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnPoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of X,Y coordinates defining the geometry of a single fin tab.
|
* Return a list of X,Y coordinates defining the geometry of a single fin tab.
|
||||||
@ -1037,6 +1057,7 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
<<<<<<< HEAD
|
||||||
* use this for calculating physical properties, and routine drawing
|
* use this for calculating physical properties, and routine drawing
|
||||||
*
|
*
|
||||||
* @return points representing the fin-root points, relative to ( x: fin-front, y: centerline ) i.e. relto: fin Component reference point
|
* @return points representing the fin-root points, relative to ( x: fin-front, y: centerline ) i.e. relto: fin Component reference point
|
||||||
@ -1046,13 +1067,13 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getMountInterval(0., parent.getLength());
|
return getMountPoints(0., parent.getLength(), 0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* used to get body points for the profile design view
|
* used to get body points for the profile design view
|
||||||
*
|
*
|
||||||
* @return points representing the fin-root points, relative to ( x: fin-front, y: fin-root-radius )
|
* @return points representing the fin-root points, relative to ( x: fin-front, y: centerline ) i.e. relto: fin Component reference point
|
||||||
*/
|
*/
|
||||||
public Coordinate[] getRootPoints(){
|
public Coordinate[] getRootPoints(){
|
||||||
if( null == parent){
|
if( null == parent){
|
||||||
@ -1060,16 +1081,25 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Coordinate finLead = getFinFront();
|
final Coordinate finLead = getFinFront();
|
||||||
final double finTailX = finLead.x + getLength();
|
final double xFinEnd = finLead.x + getLength();
|
||||||
|
|
||||||
final Coordinate[] bodyPoints = getMountInterval( finLead.x, finTailX);
|
return getMountPoints( finLead.x, xFinEnd, -finLead.x, -finLead.y);
|
||||||
|
|
||||||
return translatePoints(bodyPoints, -finLead.x, -finLead.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
private Coordinate[] getMountInterval( final double xStart, final double xEnd ) {
|
* used to get calculate body profile points:
|
||||||
// System.err.println(String.format(" .... >> mount interval/x: ( %g, %g)]", xStart, xEnd));
|
*
|
||||||
|
* @param xStart - xStart, in Mount-frame
|
||||||
|
* @param xEnd - xEnd, in Mount-frame
|
||||||
|
* @param xOffset - x-Offset to apply to returned points
|
||||||
|
* @param yOffset - y-Offset to apply to returned points
|
||||||
|
*
|
||||||
|
* @return points representing the mount's points
|
||||||
|
*/
|
||||||
|
private Coordinate[] getMountPoints(final double xStart, final double xEnd, final double xOffset, final double yOffset) {
|
||||||
|
if( null == parent){
|
||||||
|
return new Coordinate[]{Coordinate.ZERO};
|
||||||
|
}
|
||||||
|
|
||||||
// for a simple bodies, one increment is perfectly accurate.
|
// for a simple bodies, one increment is perfectly accurate.
|
||||||
int divisionCount = 1;
|
int divisionCount = 1;
|
||||||
@ -1105,14 +1135,23 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
points[lastIndex] = points[lastIndex].setX(body.getLength()).setY(body.getAftRadius());
|
points[lastIndex] = points[lastIndex].setX(body.getLength()).setY(body.getAftRadius());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( 0.0000001 < (Math.abs(xOffset) + Math.abs(yOffset))){
|
||||||
|
points = translatePoints(points, xOffset, yOffset);
|
||||||
|
}
|
||||||
|
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for debugging. You can safely delete this method
|
// for debugging. You can safely delete this method
|
||||||
public static String getPointDescr( final Coordinate[] points, final String name, final String indent){
|
public static String getPointDescr( final Coordinate[] points, final String name, final String indent){
|
||||||
|
return getPointDescr(Arrays.asList(points), name, indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for debugging. You can safely delete this method
|
||||||
|
public static String getPointDescr( final List<Coordinate> points, final String name, final String indent){
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
|
|
||||||
buf.append(String.format("%s >> %s: %d points\n", indent, name, points.length));
|
buf.append(String.format("%s >> %s: %d points\n", indent, name, points.size()));
|
||||||
int index =0;
|
int index =0;
|
||||||
for( Coordinate c : points ){
|
for( Coordinate c : points ){
|
||||||
buf.append( String.format( indent+" ....[%2d] (%6.4g, %6.4g)\n", index, c.x, c.y));
|
buf.append( String.format( indent+" ....[%2d] (%6.4g, %6.4g)\n", index, c.x, c.y));
|
||||||
@ -1128,8 +1167,8 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
|
|||||||
buf.append( getPointDescr( this.getFinPoints(), "Fin Points", ""));
|
buf.append( getPointDescr( this.getFinPoints(), "Fin Points", ""));
|
||||||
|
|
||||||
if (null != parent) {
|
if (null != parent) {
|
||||||
|
buf.append( getPointDescr( this.getMountPoints(0, parent.getLength(), 0, 0), "Body Points", ""));
|
||||||
buf.append( getPointDescr( this.getRootPoints(), "Root Points", ""));
|
buf.append( getPointDescr( this.getRootPoints(), "Root Points", ""));
|
||||||
buf.append( getPointDescr( this.getMountPoints(), "Mount Points", ""));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ! this.isTabTrivial() ) {
|
if( ! this.isTabTrivial() ) {
|
||||||
|
@ -22,7 +22,7 @@ public class FreeformFinSet extends FinSet {
|
|||||||
// this class uses certain features of 'ArrayList' which are not implemented in other 'List' implementations.
|
// this class uses certain features of 'ArrayList' which are not implemented in other 'List' implementations.
|
||||||
private ArrayList<Coordinate> points = new ArrayList<>();
|
private ArrayList<Coordinate> points = new ArrayList<>();
|
||||||
|
|
||||||
private static final double SNAP_SMALLER_THAN = 1e-6;
|
private static final double SNAP_SMALLER_THAN = 5e-3;
|
||||||
private static final double IGNORE_SMALLER_THAN = 1e-12;
|
private static final double IGNORE_SMALLER_THAN = 1e-12;
|
||||||
|
|
||||||
public FreeformFinSet() {
|
public FreeformFinSet() {
|
||||||
@ -133,7 +133,7 @@ public class FreeformFinSet extends FinSet {
|
|||||||
ArrayList<Coordinate> copy = new ArrayList<>(this.points);
|
ArrayList<Coordinate> copy = new ArrayList<>(this.points);
|
||||||
|
|
||||||
this.points.remove(index);
|
this.points.remove(index);
|
||||||
if (!validate()) {
|
if (intersects()) {
|
||||||
// if error, rollback.
|
// if error, rollback.
|
||||||
this.points = copy;
|
this.points = copy;
|
||||||
}
|
}
|
||||||
@ -149,12 +149,6 @@ public class FreeformFinSet extends FinSet {
|
|||||||
/** maintained just for backwards compatibility:
|
/** maintained just for backwards compatibility:
|
||||||
*/
|
*/
|
||||||
public void setPoints(Coordinate[] newPoints) {
|
public void setPoints(Coordinate[] newPoints) {
|
||||||
// move to zero, if applicable
|
|
||||||
if( ! Coordinate.ZERO.equals(newPoints[0])) {
|
|
||||||
final Coordinate p0 = newPoints[0];
|
|
||||||
newPoints = translatePoints( newPoints, -p0.x, -p0.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
setPoints(new ArrayList<>(Arrays.asList(newPoints)));
|
setPoints(new ArrayList<>(Arrays.asList(newPoints)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,43 +158,29 @@ public class FreeformFinSet extends FinSet {
|
|||||||
* @param newPoints New points to set as the exposed edges of the fin
|
* @param newPoints New points to set as the exposed edges of the fin
|
||||||
*/
|
*/
|
||||||
public void setPoints( ArrayList<Coordinate> newPoints) {
|
public void setPoints( ArrayList<Coordinate> newPoints) {
|
||||||
|
|
||||||
|
final Coordinate delta = newPoints.get(0).multiply(-1);
|
||||||
|
if( IGNORE_SMALLER_THAN < delta.length2()){
|
||||||
|
newPoints = translatePoints( newPoints, delta);
|
||||||
|
}
|
||||||
|
|
||||||
// copy the old points, in case validation fails
|
// copy the old points, in case validation fails
|
||||||
ArrayList<Coordinate> copy = new ArrayList<>(this.points);
|
final ArrayList<Coordinate> pointsCopy = new ArrayList<>(this.points);
|
||||||
|
final double lengthCopy = this.length;
|
||||||
|
|
||||||
this.points = newPoints;
|
this.points = newPoints;
|
||||||
this.length = newPoints.get(newPoints.size() -1).x;
|
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
||||||
//StackTraceElement[] stacktrack = Thread.currentThread().getStackTrace();
|
if( intersects()){
|
||||||
if("Canard fins, mounted to transition".equals(this.getName())) {
|
|
||||||
log.error(String.format("starting to set %d points @ %s", newPoints.size(), this.getName()), new NullPointerException());
|
|
||||||
System.err.println( toDebugDetail());
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ! validate()){
|
|
||||||
// on error, reset to the old points
|
// on error, reset to the old points
|
||||||
this.points = copy;
|
this.points = pointsCopy;
|
||||||
|
this.length = lengthCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE);
|
fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private double y_body(final double x) {
|
|
||||||
return y_body(x, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private double y_body(final double x_target, final double x_ref) {
|
|
||||||
final SymmetricComponent sym = (SymmetricComponent) getParent();
|
|
||||||
return (sym.getRadius(x_target) - sym.getRadius(x_ref));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPointRelToFin(final int index, final double x_request_fin, final double y_request_fin) throws IllegalFinPointException {
|
|
||||||
final double x_finStart_body = getAxialFront(); // x @ fin start, body frame
|
|
||||||
final double y_finStart_body = y_body(x_finStart_body);
|
|
||||||
|
|
||||||
setPoint(index, x_request_fin + x_finStart_body, y_request_fin + y_finStart_body);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the point at position <code>i</code> to coordinates (x,y).
|
* Set the point at position <code>i</code> to coordinates (x,y).
|
||||||
* <p>
|
* <p>
|
||||||
@ -225,19 +205,16 @@ public class FreeformFinSet extends FinSet {
|
|||||||
public void setPoint(final int index, final double xRequest, final double yRequest) {
|
public void setPoint(final int index, final double xRequest, final double yRequest) {
|
||||||
|
|
||||||
if(null != this.getParent()) {
|
if(null != this.getParent()) {
|
||||||
if (0 == index) {
|
final Coordinate prior = points.get(index);
|
||||||
clampFirstPoint(new Coordinate(xRequest, yRequest));
|
points.set(index, new Coordinate(xRequest, yRequest));
|
||||||
} else if ((this.points.size() - 1) == index) {
|
|
||||||
Coordinate priorPoint = points.get(index);
|
if((points.size() - 1) == index){
|
||||||
points.set(index, new Coordinate(xRequest, yRequest));
|
clampLastPoint(xRequest-prior.x);
|
||||||
clampLastPoint(priorPoint);
|
|
||||||
} else {
|
|
||||||
// interior points can never change the
|
|
||||||
points.set(index, new Coordinate(xRequest, yRequest));
|
|
||||||
clampInteriorPoint(index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
|
||||||
// this maps the last index and the next-to-last-index to the same 'testIndex'
|
// this maps the last index and the next-to-last-index to the same 'testIndex'
|
||||||
int testIndex = Math.min(index, (points.size() - 2));
|
int testIndex = Math.min(index, (points.size() - 2));
|
||||||
if (intersects(testIndex)) {
|
if (intersects(testIndex)) {
|
||||||
@ -245,12 +222,12 @@ public class FreeformFinSet extends FinSet {
|
|||||||
log.error(String.format("ERROR: found an intersection while setting fin point #%d to [%6.4g, %6.4g] <body frame> : ABORTING setPoint(..) !! ", index, xRequest, yRequest));
|
log.error(String.format("ERROR: found an intersection while setting fin point #%d to [%6.4g, %6.4g] <body frame> : ABORTING setPoint(..) !! ", index, xRequest, yRequest));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void movePoints(final double delta_x, final double delta_y) {
|
private void movePoints(final double delta_x, final double delta_y) {
|
||||||
// skip 0th index -- it's the local origin and is always (0,0)
|
// zero-out 0th index -- it's the local origin and is always (0,0)
|
||||||
|
points.set(0, Coordinate.ZERO);
|
||||||
|
|
||||||
for (int index = 1; index < points.size(); ++index) {
|
for (int index = 1; index < points.size(); ++index) {
|
||||||
final Coordinate oldPoint = this.points.get(index);
|
final Coordinate oldPoint = this.points.get(index);
|
||||||
final Coordinate newPoint = oldPoint.add(delta_x, delta_y, 0.0f);
|
final Coordinate newPoint = oldPoint.add(delta_x, delta_y, 0.0f);
|
||||||
@ -288,236 +265,113 @@ public class FreeformFinSet extends FinSet {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setAxialOffset(final AxialMethod newAxialMethod, final double newOffsetRequest) {
|
|
||||||
super.setAxialOffset(newAxialMethod, newOffsetRequest);
|
|
||||||
|
|
||||||
if (null != parent) {
|
|
||||||
// if the new position would cause fin overhang, only allow movement up to the end of the parent component.
|
|
||||||
// N.B. if you want a fin to overhang, add & adjust interior points.
|
|
||||||
final double backOverhang = getAxialOffset(AxialMethod.BOTTOM);
|
|
||||||
if (0 < backOverhang) {
|
|
||||||
final double newOffset = newOffsetRequest - backOverhang;
|
|
||||||
super.setAxialOffset(newAxialMethod, newOffset);
|
|
||||||
}
|
|
||||||
final double frontOverhang = getAxialFront();
|
|
||||||
if (0 > frontOverhang) {
|
|
||||||
final double newOffset = newOffsetRequest - frontOverhang;
|
|
||||||
super.setAxialOffset(newAxialMethod, newOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
|
this.length = points.get(points.size() -1).x - points.get(0).x;
|
||||||
this.setAxialOffset(this.axialMethod, this.axialOffset);
|
this.setAxialOffset(this.axialMethod, this.axialOffset);
|
||||||
|
|
||||||
if(null != this.getParent()) {
|
if(null != this.getParent()) {
|
||||||
clampFirstPoint(points.get(0));
|
clampFirstPoint();
|
||||||
|
|
||||||
for(int i=1; i < points.size()-1; i++) {
|
for(int i=1; i < points.size()-1; i++) {
|
||||||
clampInteriorPoint(i);
|
clampInteriorPoint(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
clampLastPoint(null);
|
clampLastPoint();
|
||||||
|
|
||||||
validateFinTab();
|
validateFinTab();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clampFirstPoint(final Coordinate newPoint) {
|
private void clampFirstPoint() {
|
||||||
final SymmetricComponent body = (SymmetricComponent) getParent();
|
final SymmetricComponent body = (SymmetricComponent) getParent();
|
||||||
|
|
||||||
final Coordinate finFront = getFinFront();
|
final Coordinate finFront = getFinFront();
|
||||||
final double xFinFront = finFront.x; // x of fin start, body-frame
|
final double xFinFront = finFront.x; // x of fin start, body-frame
|
||||||
final double yFinFront = finFront.y; // y of fin start, body-frame
|
final double yFinFront = finFront.y; // y of fin start, body-frame
|
||||||
final double xBodyStart = -getAxialFront(); // x-offset from start-to-start; fin-frame
|
|
||||||
|
|
||||||
double xDelta;
|
final Coordinate p0 = points.get(0);
|
||||||
double yDelta;
|
|
||||||
|
|
||||||
if(IGNORE_SMALLER_THAN > Math.abs(newPoint.x)){
|
if( ! Coordinate.ZERO.equals(p0)){
|
||||||
return;
|
double xDelta = p0.x;
|
||||||
}else if (xBodyStart > newPoint.x) {
|
double xTrail = points.get(points.size() - 1).x;
|
||||||
// attempt to place point in front of the start of the body
|
if(xDelta > xTrail){
|
||||||
|
xDelta = xTrail;
|
||||||
|
}
|
||||||
|
double yDelta = body.getRadius(xFinFront + xDelta) - yFinFront;
|
||||||
|
|
||||||
// delta for new zeroth point
|
|
||||||
xDelta = xBodyStart;
|
|
||||||
yDelta = body.getForeRadius() - yFinFront;
|
|
||||||
points.set(0, newPoint);
|
|
||||||
points.add(0, Coordinate.ZERO);
|
|
||||||
movePoints(-xDelta, -yDelta);
|
movePoints(-xDelta, -yDelta);
|
||||||
|
|
||||||
//System.err.println(String.format(".... @[0]//A: delta= %f, %f", xDelta, yDelta));
|
if(AxialMethod.TOP == getAxialMethod()) {
|
||||||
|
this.axialOffset = axialOffset + xDelta;
|
||||||
}else if (xFinFront > body.getLength()) {
|
this.position = this.position.add(xDelta, 0, 0);
|
||||||
final double xNew = body.getLength();
|
} else if (AxialMethod.MIDDLE == getAxialMethod()) {
|
||||||
final double yNew = yFinFront - body.getAftRadius();
|
this.axialOffset = axialOffset + xDelta / 2;
|
||||||
points.set(0, points.set(0, new Coordinate(xNew, yNew)));
|
}
|
||||||
|
|
||||||
xDelta = xNew - xFinFront;
|
|
||||||
yDelta = yNew - yFinFront;
|
|
||||||
movePoints(-xDelta, -yDelta);
|
|
||||||
//System.err.println(String.format(".... @[0]//B: delta= %f, %f", xDelta, yDelta));
|
|
||||||
|
|
||||||
}else {
|
|
||||||
// distance to move the entire fin by:
|
|
||||||
xDelta = newPoint.x;
|
|
||||||
yDelta = body.getRadius(xFinFront + xDelta) - yFinFront;
|
|
||||||
movePoints(-xDelta, -yDelta);
|
|
||||||
|
|
||||||
//System.err.println(String.format(".... @[0]//C: delta= %f, %f", xDelta, yDelta));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final int lastIndex = points.size()-1;
|
final int lastIndex = points.size()-1;
|
||||||
this.length = points.get(lastIndex).x;
|
this.length = points.get(lastIndex).x;
|
||||||
|
|
||||||
if (AxialMethod.TOP == getAxialMethod()) {
|
|
||||||
setAxialOffset(AxialMethod.TOP, getAxialOffset() + xDelta);
|
|
||||||
} else if (AxialMethod.MIDDLE == getAxialMethod()) {
|
|
||||||
setAxialOffset(AxialMethod.MIDDLE, getAxialOffset() + xDelta / 2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clampInteriorPoint(final int index) {
|
private void clampInteriorPoint(final int index) {
|
||||||
final SymmetricComponent sym = (SymmetricComponent) this.getParent();
|
final SymmetricComponent sym = (SymmetricComponent) this.getParent();
|
||||||
|
|
||||||
final double xPrior = points.get(index).x;
|
|
||||||
final double yPrior = points.get(index).y;
|
|
||||||
|
|
||||||
final Coordinate finFront = getFinFront();
|
final Coordinate finFront = getFinFront();
|
||||||
final double xFinFront = finFront.x; // x of fin start, body-frame
|
final double xFinFront = finFront.x; // x of fin start, body-frame
|
||||||
final double yFinFront = finFront.y; // y of fin start, body-frame
|
final double yFinFront = finFront.y; // y of fin start, body-frame
|
||||||
|
|
||||||
final double yBody = sym.getRadius(xPrior + xFinFront) - yFinFront;
|
final double xBodyFront = -xFinFront;
|
||||||
|
final double xBodyBack = xBodyFront + sym.getLength();
|
||||||
|
|
||||||
// ensure that an interior point is outside of its mounting body:
|
final double xPrior = points.get(index).x;
|
||||||
if (yBody > yPrior) {
|
final double yPrior = points.get(index).y;
|
||||||
points.set(index, points.get(index).setY(yBody));
|
|
||||||
|
if((xBodyFront <= xPrior ) && ( xPrior <= xBodyBack )) {
|
||||||
|
final double yBody = sym.getRadius(xPrior + xFinFront) - yFinFront;
|
||||||
|
|
||||||
|
// ensure that an interior point is outside of its mounting body:
|
||||||
|
if (yBody > yPrior) {
|
||||||
|
points.set(index, points.get(index).setY(yBody));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clampLastPoint(final Coordinate prior) {
|
private void clampLastPoint() {
|
||||||
|
clampLastPoint(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clampLastPoint(final double xDelta) {
|
||||||
final SymmetricComponent body = (SymmetricComponent) getParent();
|
final SymmetricComponent body = (SymmetricComponent) getParent();
|
||||||
|
|
||||||
final double xFinStart = getAxialFront(); // x of fin start, body-frame
|
final Coordinate finFront = getFinFront();
|
||||||
final double yFinStart = body.getRadius(xFinStart); // y of fin start, body-frame
|
final double xFinStart = finFront.x; // x of fin start, body-frame
|
||||||
|
final double yFinStart = finFront.y; // y of fin start, body-frame
|
||||||
final double xBodyStart = -getAxialFront(); // x-offset from start-to-start; fin-frame
|
|
||||||
final double xBodyEnd = xBodyStart + body.getLength(); /// x-offset from start-to-body; fin-frame
|
|
||||||
|
|
||||||
int lastIndex = points.size() - 1;
|
int lastIndex = points.size() - 1;
|
||||||
final Coordinate cur = points.get(lastIndex);
|
final Coordinate last = points.get(lastIndex);
|
||||||
|
|
||||||
double xDelta=0;
|
double yBody = body.getRadius(xFinStart + last.x) - yFinStart;
|
||||||
|
double yDelta = yBody - last.y;
|
||||||
|
if( IGNORE_SMALLER_THAN < Math.abs(yDelta)){
|
||||||
|
// i.e. if it delta is close enough above OR is inside the body. In either case, snap it to the body.
|
||||||
|
|
||||||
if (xBodyEnd < cur.x) {
|
// => set y-value to *exactly* match parent body:
|
||||||
if(SNAP_SMALLER_THAN > Math.abs(xBodyEnd - cur.x)){
|
points.set(lastIndex, new Coordinate(last.x, yBody));
|
||||||
points.set( lastIndex, new Coordinate(xBodyEnd, body.getAftRadius() - yFinStart));
|
|
||||||
}else {
|
|
||||||
// the last point is placed after the end of the mount-body
|
|
||||||
points.add(new Coordinate(xBodyEnd, body.getAftRadius() - yFinStart));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(null != prior) {
|
|
||||||
xDelta = xBodyEnd - prior.x;
|
|
||||||
}else{
|
|
||||||
xDelta = xBodyEnd - cur.x;
|
|
||||||
}
|
|
||||||
//System.err.println(String.format(".... @[-1]//A: delta= %f", xDelta));
|
|
||||||
|
|
||||||
}else if (cur.x < 0) {
|
|
||||||
// the last point is positioned ahead of the first point.
|
|
||||||
points.set(lastIndex, Coordinate.ZERO);
|
|
||||||
|
|
||||||
xDelta = cur.x;
|
|
||||||
|
|
||||||
//System.err.println(String.format(".... @[-1]//B: delta= %f", xDelta));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if(null != prior) {
|
|
||||||
xDelta = cur.x - prior.x;
|
|
||||||
}
|
|
||||||
double yBody = body.getRadius(xFinStart + cur.x) - yFinStart;
|
|
||||||
if(IGNORE_SMALLER_THAN < Math.abs(yBody - cur.y)) {
|
|
||||||
// for the first and last points: set y-value to *exactly* match parent body:
|
|
||||||
points.set(lastIndex, new Coordinate(cur.x, yBody));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//System.err.println(String.format(".... @[-1]//C: delta = %f", xDelta));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IGNORE_SMALLER_THAN < Math.abs(xDelta)) {
|
if( IGNORE_SMALLER_THAN < Math.abs(xDelta)) {
|
||||||
lastIndex = points.size()-1;
|
|
||||||
this.length = points.get(lastIndex).x;
|
this.length = points.get(lastIndex).x;
|
||||||
|
|
||||||
if (AxialMethod.MIDDLE == getAxialMethod()) {
|
if (AxialMethod.MIDDLE == getAxialMethod()) {
|
||||||
setAxialOffset(AxialMethod.MIDDLE, getAxialOffset() + xDelta / 2);
|
this.axialOffset = axialOffset + xDelta/2;
|
||||||
} else if (AxialMethod.BOTTOM == getAxialMethod()) {
|
} else if (AxialMethod.BOTTOM == getAxialMethod()) {
|
||||||
setAxialOffset(AxialMethod.BOTTOM, getAxialOffset() + xDelta);
|
this.axialOffset = axialOffset + xDelta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validate() {
|
|
||||||
final Coordinate firstPoint = this.points.get(0);
|
|
||||||
if (firstPoint.x != 0 || firstPoint.y != 0) {
|
|
||||||
log.error("Start point illegal -- not located at (0,0): " + firstPoint + " (" + getName() + ")");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Coordinate lastPoint = this.points.get(points.size() - 1);
|
|
||||||
if (lastPoint.x < 0) {
|
|
||||||
log.error("End point illegal: end point starts in front of start point: " + lastPoint.x);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the last point *is* restricted to be on the surface of its owning component:
|
|
||||||
SymmetricComponent symBody = (SymmetricComponent) this.getParent();
|
|
||||||
if (null != symBody) {
|
|
||||||
final double startOffset = this.getAxialFront();
|
|
||||||
final Coordinate finStart = new Coordinate(startOffset, symBody.getRadius(startOffset));
|
|
||||||
|
|
||||||
// campare x-values
|
|
||||||
final Coordinate finAtLast = lastPoint.add(finStart);
|
|
||||||
if (symBody.getLength() < finAtLast.x) {
|
|
||||||
log.error("End point falls after parent body ends: [" + symBody.getName() + "]. Exception: ",
|
|
||||||
new IllegalFinPointException("Fin ends after its parent body \"" + symBody.getName() + "\". Ignoring."));
|
|
||||||
log.error(String.format(" ..fin position: (x: %12.10f via: %s)", this.axialOffset, this.axialMethod.name()));
|
|
||||||
log.error(String.format(" ..Body Length: %12.10f finLength: %12.10f", symBody.getLength(), this.getLength()));
|
|
||||||
log.error(String.format(" ..fin endpoint: (x: %12.10f, y: %12.10f)", finAtLast.x, finAtLast.y));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compare the y-values
|
|
||||||
final Coordinate bodyAtLast = finAtLast.setY(symBody.getRadius(finAtLast.x));
|
|
||||||
if (0.0001 < Math.abs(finAtLast.y - bodyAtLast.y)) {
|
|
||||||
String numbers = String.format("finStart=(%6.2g,%6.2g) // fin_end=(%6.2g,%6.2g) // body=(%6.2g,%6.2g)", finStart.x, finStart.y, finAtLast.x, finAtLast.y, bodyAtLast.x, bodyAtLast.y);
|
|
||||||
log.error("End point does not touch its parent body [" + symBody.getName() + "]. exception: ",
|
|
||||||
new IllegalFinPointException("End point does not touch its parent body! Expected: " + numbers));
|
|
||||||
log.error(" .." + numbers);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (intersects()) {
|
|
||||||
log.error("found intersection in finset points!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int lastIndex = points.size() - 1;
|
|
||||||
final List<Coordinate> pts = this.points;
|
|
||||||
for (int i = 0; i < lastIndex; i++) {
|
|
||||||
if (pts.get(i).z != 0) {
|
|
||||||
log.error("z-coordinate not zero");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if *any* of the fin-point line segments intersects with another.
|
* Check if *any* of the fin-point line segments intersects with another.
|
||||||
*
|
*
|
||||||
|
@ -348,8 +348,10 @@ public class Transition extends SymmetricComponent {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public double getRadius(double x) {
|
public double getRadius(double x) {
|
||||||
if (x < 0 || x > length)
|
if ( x < 0 )
|
||||||
return 0;
|
return getForeRadius();
|
||||||
|
if ( x > length)
|
||||||
|
return getAftRadius();
|
||||||
|
|
||||||
double r1 = getForeRadius();
|
double r1 = getForeRadius();
|
||||||
double r2 = getAftRadius();
|
double r2 = getAftRadius();
|
||||||
|
@ -318,7 +318,6 @@ public class MassCalculatorTest extends BaseTestCase {
|
|||||||
FlightConfiguration emptyConfig = rocket.getEmptyConfiguration();
|
FlightConfiguration emptyConfig = rocket.getEmptyConfiguration();
|
||||||
rocket.setSelectedConfiguration( emptyConfig.getFlightConfigurationID() );
|
rocket.setSelectedConfiguration( emptyConfig.getFlightConfigurationID() );
|
||||||
|
|
||||||
|
|
||||||
double expInertia;
|
double expInertia;
|
||||||
RocketComponent cc;
|
RocketComponent cc;
|
||||||
double compInertia;
|
double compInertia;
|
||||||
@ -326,30 +325,24 @@ public class MassCalculatorTest extends BaseTestCase {
|
|||||||
// ====== Payload Stage ======
|
// ====== Payload Stage ======
|
||||||
// ====== ====== ====== ======
|
// ====== ====== ====== ======
|
||||||
{
|
{
|
||||||
expInertia = 3.1698055283e-5;
|
final AxialStage payloadStage = (AxialStage) rocket.getChild(0);
|
||||||
cc= rocket.getChild(0).getChild(0);
|
|
||||||
compInertia = cc.getRotationalInertia();
|
|
||||||
assertEquals(cc.getName()+" Rotational MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
|
||||||
expInertia = 1.79275e-5;
|
|
||||||
compInertia = cc.getLongitudinalInertia();
|
|
||||||
assertEquals(cc.getName()+" Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
|
||||||
|
|
||||||
cc= rocket.getChild(0).getChild(1);
|
// Component: Nose Cone
|
||||||
expInertia = 7.70416e-5;
|
final NoseCone payloadNose = (NoseCone) payloadStage.getChild(0);
|
||||||
compInertia = cc.getRotationalInertia();
|
assertEquals(payloadNose.getName()+" Rotational MOI calculated incorrectly: ", 3.508155e-5, payloadNose.getRotationalInertia(), EPSILON);
|
||||||
assertEquals(cc.getName()+" Rotational MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
assertEquals(payloadNose.getName()+" Longitudinal MOI calculated incorrectly: ", 2.0400578477e-6, payloadNose.getLongitudinalInertia(), EPSILON);
|
||||||
expInertia = 8.06940e-5;
|
|
||||||
compInertia = cc.getLongitudinalInertia();
|
|
||||||
assertEquals(cc.getName()+" Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
|
||||||
|
|
||||||
cc= rocket.getChild(0).getChild(2);
|
// Component: Payload BodyTube
|
||||||
expInertia = 1.43691e-5;
|
final BodyTube payloadBody = (BodyTube)payloadStage.getChild(1);
|
||||||
compInertia = cc.getRotationalInertia();
|
assertEquals(payloadBody.getName()+" Rotational MOI calculated incorrectly: ", 7.70416e-5, payloadBody.getRotationalInertia(), EPSILON);
|
||||||
assertEquals(cc.getName()+" Rotational MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
assertEquals(payloadBody.getName()+" Longitudinal MOI calculated incorrectly: ", 8.06940e-5, payloadBody.getLongitudinalInertia(), EPSILON);
|
||||||
expInertia = 7.30265e-6;
|
|
||||||
compInertia = cc.getLongitudinalInertia();
|
|
||||||
assertEquals(cc.getName()+" Longitudinal MOI calculated incorrectly: ", expInertia, compInertia, EPSILON);
|
|
||||||
|
|
||||||
|
// Component: Payload Trailing Transition
|
||||||
|
final Transition payloadTail = (Transition) payloadStage.getChild(2);
|
||||||
|
assertEquals(payloadTail.getName()+" Rotational MOI calculated incorrectly: ", 1.43691e-5, payloadTail.getRotationalInertia(), EPSILON);
|
||||||
|
assertEquals(payloadTail.getName()+" Longitudinal MOI calculated incorrectly: ", 7.30265e-6, payloadTail.getLongitudinalInertia(), EPSILON);
|
||||||
|
|
||||||
|
// Component: Interstage
|
||||||
cc= rocket.getChild(0).getChild(3);
|
cc= rocket.getChild(0).getChild(3);
|
||||||
expInertia = 4.22073e-5;
|
expInertia = 4.22073e-5;
|
||||||
compInertia = cc.getRotationalInertia();
|
compInertia = cc.getRotationalInertia();
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -425,11 +425,6 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
|||||||
Point2D.Double point = getCoordinates(event);
|
Point2D.Double point = getCoordinates(event);
|
||||||
finset.setPoint(dragIndex, point.x, point.y);
|
finset.setPoint(dragIndex, point.x, point.y);
|
||||||
|
|
||||||
final double bodyFront = -finset.getAxialFront();
|
|
||||||
if(0 == dragIndex && bodyFront > point.x){
|
|
||||||
dragIndex = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateFields();
|
updateFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,6 +442,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
|||||||
if ( 0 < clickIndex) {
|
if ( 0 < clickIndex) {
|
||||||
// if ctrl+click, delete point
|
// if ctrl+click, delete point
|
||||||
try {
|
try {
|
||||||
|
Point2D.Double point = getCoordinates(event);
|
||||||
finset.removePoint(clickIndex);
|
finset.removePoint(clickIndex);
|
||||||
} catch (IllegalFinPointException ignore) {
|
} catch (IllegalFinPointException ignore) {
|
||||||
log.error("Ignoring IllegalFinPointException while dragging, dragIndex=" + dragIndex + ". This is likely an internal error.");
|
log.error("Ignoring IllegalFinPointException while dragging, dragIndex=" + dragIndex + ". This is likely an internal error.");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user