Support multi-comp fin set shape editing

This commit is contained in:
SiboVG 2022-12-01 18:19:35 +01:00
parent 611fa93dbe
commit f77614fee3
3 changed files with 113 additions and 13 deletions

View File

@ -103,6 +103,43 @@ public class FreeformFinSet extends FinSet {
}
return freeform;
}
/**
* Converts a point of this fin set to edit into a point for a config listener to edit.
*
* The editing is as follows:
* 1) Editing the first point of this fin set will always edit the first point of the listener set
* 2) Editing the last point of this fin set will always edit the last point of the listener set
* 3) Editing any other point of this fin set will edit the corresponding point of the listener set, except
* for when the current point is not the last of this set, but it is the last of the listener set. In that
* case, no listener point will be edited.
*
* @param listener the listener which point needs to be edited
* @param index the point index of this fin set that is being edited
* @return the point index of the listener fin set that needs to be edited. Returns -1 if the listener's point should not be edited.
*/
private int getConfigListenerPointIdx(FreeformFinSet listener, int index) {
/*
The editing is as follows:
1) Editing the first point of this fin set will always edit the first point of the listener set
2) Editing the last point of this fin set will always edit the last point of the listener set
3) Editing any other point of this fin set will edit the corresponding point of the listener set, except
for when the current point is not the last of this set, but it is the last of the listener set. In that
case, no listener point will be edited.
*/
if (index == this.points.size() - 1) {
// If editing the last point, also edit the last point of the listener
return listener.getPointCount() - 1;
} else {
if (index == listener.getPointCount() - 1) {
// If editing the last point of the listener, but not the last point of this fin set, don't edit the listener
return -1;
} else {
// Index-wise editing
return index;
}
}
}
/**
* Add a fin point between indices <code>index-1</code> and <code>index</code>.
@ -111,7 +148,22 @@ public class FreeformFinSet extends FinSet {
* @param index the fin point before which to add the new point.
* @param location the target location to create the new point at
*/
public void addPoint(int index, Point2D.Double location) {
public void addPoint(int index, Point2D.Double location) throws IllegalFinPointException {
if (index < 1 || index > points.size() - 1) {
throw new IllegalFinPointException("Cannot add new point before the first or after the last point");
}
for (RocketComponent listener : configListeners) {
if (listener instanceof FreeformFinSet) {
try {
int listenerIdx = getConfigListenerPointIdx((FreeformFinSet) listener, index);
((FreeformFinSet) listener).addPoint(listenerIdx, location);
} catch (IllegalFinPointException ignored) {
// ignore
}
}
}
// new method: add new point at closest point
points.add(index, new Coordinate(location.x, location.y));
@ -131,6 +183,20 @@ public class FreeformFinSet extends FinSet {
if (index == 0 || index == points.size() - 1) {
throw new IllegalFinPointException("cannot remove first or last point");
}
if (index < 0 || index >= points.size() - 1) {
throw new IllegalFinPointException("index out of range");
}
for (RocketComponent listener : configListeners) {
if (listener instanceof FreeformFinSet) {
try {
int listenerIdx = getConfigListenerPointIdx((FreeformFinSet) listener, index);
((FreeformFinSet) listener).removePoint(listenerIdx);
} catch (IllegalFinPointException ignored) {
// ignore
}
}
}
// copy the old list in case the operation fails
ArrayList<Coordinate> copy = new ArrayList<>(this.points);
@ -226,11 +292,26 @@ public class FreeformFinSet extends FinSet {
* @param xRequest the x-coordinate.
* @param yRequest the y-coordinate.
*/
public void setPoint(final int index, final double xRequest, final double yRequest) {
if(null == this.getParent()) {
public void setPoint(final int index, final double xRequest, final double yRequest) throws IllegalFinPointException {
if (this.getParent() == null) {
return;
}
if (index < 0 || index > this.points.size() - 1) {
throw new IllegalFinPointException("index out of range");
}
for (RocketComponent listener : configListeners) {
if (listener instanceof FreeformFinSet) {
try {
int listenerIdx = getConfigListenerPointIdx((FreeformFinSet) listener, index);
((FreeformFinSet) listener).setPoint(listenerIdx, xRequest, yRequest);
} catch (IllegalFinPointException ignored) {
// Ignore
}
}
}
// if the new x,y would cause a fin larger than our max-size, limit the new request:
double xAccept = xRequest;
double yAccept = yRequest;

View File

@ -7,6 +7,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.awt.geom.Point2D;
@ -432,7 +433,11 @@ public class FreeformFinSetTest extends BaseTestCase {
// / |
// +=====+
Point2D.Double toAdd = new Point2D.Double(1.01, 0.8);
fin.addPoint(3, toAdd);
try {
fin.addPoint(3, toAdd);
} catch (IllegalFinPointException e) {
fail("IllegalFinPointException thrown");
}
assertEquals(5, fin.getPointCount());
final Coordinate added = fin.getFinPoints()[3];
@ -441,7 +446,7 @@ public class FreeformFinSetTest extends BaseTestCase {
}
@Test
public void testSetFirstPoint() {
public void testSetFirstPoint() throws IllegalFinPointException {
// more transitions trigger more complicated positioning math:
final Rocket rkt = createTemplateRocket();
final Transition tailCone = (Transition) rkt.getChild(0).getChild(2);
@ -605,7 +610,7 @@ public class FreeformFinSetTest extends BaseTestCase {
}
@Test
public void testSetLastPoint() {
public void testSetLastPoint() throws IllegalFinPointException {
final Rocket rkt = createTemplateRocket();
final Transition tailCone = (Transition) rkt.getChild(0).getChild(2);
final FreeformFinSet fins = createFinOnConicalTransition(tailCone);
@ -771,7 +776,7 @@ public class FreeformFinSetTest extends BaseTestCase {
}
@Test
public void testSetInteriorPoint() {
public void testSetInteriorPoint() throws IllegalFinPointException {
final Rocket rkt = createTemplateRocket();
final Transition tailCone = (Transition) rkt.getChild(0).getChild(2);
final FreeformFinSet fins = this.createFinOnConicalTransition(tailCone);
@ -875,7 +880,7 @@ public class FreeformFinSetTest extends BaseTestCase {
}
@Test
public void testSetFirstPoint_clampToLast() {
public void testSetFirstPoint_clampToLast() throws IllegalFinPointException {
final Rocket rkt = createTemplateRocket();
final Transition tailCone = (Transition) rkt.getChild(0).getChild(2);
final FreeformFinSet fins = this.createFinOnConicalTransition(tailCone);
@ -906,7 +911,7 @@ public class FreeformFinSetTest extends BaseTestCase {
}
@Test
public void testSetPoint_otherPoint(){
public void testSetPoint_otherPoint() throws IllegalFinPointException {
// combine the simple case with the complicated to ensure that the simple case is flagged, tested, and debugged before running the more complicated case...
{ // setting points on a Tube Body is the simpler case. Test this first:
final Rocket rkt = createTemplateRocket();

View File

@ -466,7 +466,7 @@ public class FreeformFinSetConfig extends FinSetConfig {
* Insert a new fin point between the currently selected point and the next point.
* The coordinates of the new point will be the average of the two points.
*/
private void insertPoint() {
private void insertPoint() throws IllegalFinPointException {
int currentPointIdx = table.getSelectedRow();
if (currentPointIdx == -1 || currentPointIdx >= table.getRowCount() - 1) {
return;
@ -532,7 +532,11 @@ public class FreeformFinSetConfig extends FinSetConfig {
final int segmentIndex = getSegment(event);
if (segmentIndex >= 0) {
Point2D.Double point = getCoordinates(event);
finset.addPoint(segmentIndex, point);
try {
finset.addPoint(segmentIndex, point);
} catch (IllegalFinPointException e) {
throw new RuntimeException(e);
}
dragIndex = segmentIndex;
dragPoint = event.getPoint();
@ -554,7 +558,11 @@ public class FreeformFinSetConfig extends FinSetConfig {
Point2D.Double point = getCoordinates(event);
final FreeformFinSet finset = (FreeformFinSet) component;
finset.setPoint(dragIndex, point.x, point.y);
try {
finset.setPoint(dragIndex, point.x, point.y);
} catch (IllegalFinPointException e) {
throw new RuntimeException(e);
}
dragPoint.x = event.getX();
dragPoint.y = event.getY();
@ -782,6 +790,8 @@ public class FreeformFinSetConfig extends FinSetConfig {
updateFields();
} catch (NumberFormatException ignore) {
log.warn("ignoring NumberFormatException while editing a Freeform Fin");
} catch (IllegalFinPointException e) {
throw new RuntimeException(e);
}
}
}
@ -800,7 +810,11 @@ public class FreeformFinSetConfig extends FinSetConfig {
@Override
public void actionPerformed(ActionEvent e) {
insertPoint();
try {
insertPoint();
} catch (IllegalFinPointException ex) {
throw new RuntimeException(ex);
}
}
@Override