trackeditor: add segment subdivide by Simon Wood

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@8544 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: c5334a7082ce605df1463e2b478b840b98c083e9
Former-commit-id: 0be2e5e8f4bbec9903cb66338b0bd9a7ad249afb
This commit is contained in:
iobyte 2022-09-24 22:27:57 +00:00
parent 9784035da9
commit c0ab4c5c87
2 changed files with 229 additions and 0 deletions

View file

@ -103,6 +103,7 @@ public class EditorFrame extends JFrame
ShowArrowsAction showArrowsAction = null;
ShowBackgroundAction showBackgroundAction = null;
MoveAction moveAction = null;
SubdivideAction subdivideAction = null;
HelpAction helpAction = null;
ImportAction importAction = null;
ExportAction exportAction = null;
@ -137,6 +138,7 @@ public class EditorFrame extends JFrame
public JToggleButton toggleButtonCreateLeftSegment = null;
public JToggleButton toggleButtonCreateRightSegment = null;
public JToggleButton toggleButtonDelete = null;
public JToggleButton toggleButtonSubdivide = null;
JButton undoButton = null;
JButton redoButton = null;
JMenu viewMenu = new JMenu();
@ -163,6 +165,7 @@ public class EditorFrame extends JFrame
private JMenuItem addLeftMenuItem = null;
private JMenuItem moveMenuItem = null;
private JMenuItem deleteMenuItem = null;
private JMenuItem subdivideMenuItem = null;
private JMenuItem showArrowsMenuItem = null;
private JMenuItem showBackgroundMenuItem = null;
private JMenuItem defaultSurfacesItem = null;
@ -924,6 +927,7 @@ public class EditorFrame extends JFrame
segmentMenu.addSeparator();
segmentMenu.add(getMoveMenuItem());
segmentMenu.add(getDeleteMenuItem());
segmentMenu.add(getSubdivideMenuItem());
}
return segmentMenu;
}
@ -1017,6 +1021,21 @@ public class EditorFrame extends JFrame
}
return moveMenuItem;
}
/**
* This method initializes subdivideMenuItem
*
* @return javax.swing.JMenuItem
*/
private JMenuItem getSubdivideMenuItem()
{
if (subdivideMenuItem == null)
{
subdivideMenuItem = new JMenuItem();
subdivideMenuItem.setAction(subdivideAction);
subdivideMenuItem.setIcon(null);
}
return subdivideMenuItem;
}
/**
* This method initializes deleteMenuItem
*
@ -1437,6 +1456,25 @@ public class EditorFrame extends JFrame
return toggleButtonDelete;
}
/**
* This method initializes toggleButtonSubdivide
*
* @return javax.swing.JToggleButton
*/
private JToggleButton getToggleButtonSubdivide()
{
if (toggleButtonSubdivide == null)
{
toggleButtonSubdivide = new JToggleButton();
toggleButtonSubdivide.setAction(subdivideAction);
if (toggleButtonSubdivide.getIcon() != null)
{
toggleButtonSubdivide.setText("");
}
}
return toggleButtonSubdivide;
}
/**
* This method initializes buttonZoomPlus
*
@ -1789,6 +1827,8 @@ public class EditorFrame extends JFrame
getMoveButton().setSelected(false);
if (toggleButtonDelete != button)
toggleButtonDelete.setSelected(false);
if (toggleButtonSubdivide != button)
toggleButtonSubdivide.setSelected(false);
} else
{
view.setState(CircuitView.STATE_NONE);
@ -1837,6 +1877,11 @@ public class EditorFrame extends JFrame
view.redrawCircuit();
}
void toggleButtonSubdivide_actionPerformed(ActionEvent e)
{
checkButtons(toggleButtonSubdivide, CircuitView.STATE_SUBDIVIDE);
}
void menuItemAddBackground_actionPerformed(ActionEvent e)
{
try
@ -1901,6 +1946,7 @@ public class EditorFrame extends JFrame
jToolBar.add(getUndoButton());
jToolBar.add(getRedoButton());
jToolBar.add(getToggleButtonDelete());
jToolBar.add(getToggleButtonSubdivide());
jToolBar.add(getButtonZoomPlus());
jToolBar.add(getButtonZoomOne());
jToolBar.add(getButtonZoomMinus());
@ -1973,6 +2019,7 @@ public class EditorFrame extends JFrame
undoAction = new UndoAction("Undo", createNavigationIcon("Undo24"), "Undo.", KeyEvent.VK_Z);
redoAction = new RedoAction("Redo", createNavigationIcon("Redo24"), "Redo.", KeyEvent.VK_R);
deleteAction = new DeleteAction("Delete", createNavigationIcon("Cut24"), "Delete.", KeyEvent.VK_L);
subdivideAction = new SubdivideAction("Subdivide", createNavigationIcon("Subdivide24"), "Subdivide.", KeyEvent.VK_Q);
zoomPlusAction = new ZoomPlusAction("Zoom in", createNavigationIcon("ZoomIn24"), "Zoom in.", KeyEvent.VK_M);
zoomOneAction = new ZoomOneAction("Zoom 1:1", createNavigationIcon("Zoom24"), "Zoom 1:1.", KeyEvent.VK_N);
zoomMinusAction = new ZoomMinusAction("Zoom out", createNavigationIcon("ZoomOut24"), "Zoom out.", KeyEvent.VK_O);
@ -2040,6 +2087,19 @@ public class EditorFrame extends JFrame
toggleButtonDelete_actionPerformed(e);
}
}
public class SubdivideAction extends AbstractAction
{
public SubdivideAction(String text, ImageIcon icon, String desc, Integer mnemonic)
{
super(text, icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnemonic);
}
public void actionPerformed(final ActionEvent e) {
toggleButtonSubdivide_actionPerformed(e);
}
}
public class ZoomPlusAction extends AbstractAction
{
public ZoomPlusAction(String text, ImageIcon icon, String desc, Integer mnemonic)

View file

@ -123,6 +123,7 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
static public final int STATE_DELETE = 4;
static public final int STATE_SHOW_BGRD_START_POSITION = 5;
static public final int STATE_MOVE_SEGMENTS = 6;
static public final int STATE_SUBDIVIDE = 7;
/** arrow showing state */
public boolean showArrows = false;
@ -376,6 +377,173 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
}
}
break;
case STATE_SUBDIVIDE:
{
if (handledShape == null)
{
return;
}
SegmentVector data = editorFrame.getTrackData().getSegments();
int pos = data.indexOf(handledShape);
double splitPoint = 0.5;
switch (handledShape.getType())
{
case "lft":
{
Curve oldShape = (Curve)handledShape;
Curve cloneShape = (Curve)oldShape.clone();
Curve newShape2 = new Curve("lft", oldShape);
double arc = oldShape.getArcDeg();
double rStart = oldShape.getRadiusStart();
double rEnd = oldShape.getRadiusEnd();
double L = (rStart + rEnd) / 2.0 * oldShape.getArcDeg();
double nbSteps = (int)(L / 4.0 + 0.5) + 1;
double stepLength = L / nbSteps;
double deltaRadiusStep = (rEnd - rStart) / (nbSteps - 1.0);
double tmpAngle = 0.0;
double tmpRadius = rStart;
for (int curStep = 0; curStep < nbSteps; ++curStep)
{
tmpAngle += stepLength / tmpRadius;
tmpRadius += deltaRadiusStep;
}
stepLength *= arc / tmpAngle;
tmpAngle = 0.0;
tmpRadius = rStart;
for (int curStep = 0; curStep < nbSteps; ++curStep)
{
tmpAngle += stepLength / tmpRadius;
tmpRadius += deltaRadiusStep;
oldShape.setArcDeg(tmpAngle);
oldShape.setRadiusEnd(tmpRadius - deltaRadiusStep);
redrawCircuit();
if (oldShape.contains(mousePoint.x, mousePoint.y))
{
splitPoint = curStep / nbSteps;
break;
}
}
newShape2.setArcDeg(arc - tmpAngle);
newShape2.setRadiusEnd(rEnd);
newShape2.setRadiusStart(tmpRadius);
double leftSide = oldShape.getLeft().getSideStartWidth() + (oldShape.getLeft().getSideEndWidth() - oldShape.getLeft().getSideStartWidth()) * splitPoint;
double rightSide = oldShape.getRight().getSideStartWidth() + (oldShape.getRight().getSideEndWidth() - oldShape.getRight().getSideStartWidth()) * splitPoint;
newShape2.getLeft().setBorderWidth(oldShape.getLeft().getBorderWidth());
newShape2.getRight().setBorderWidth(oldShape.getRight().getBorderWidth());
newShape2.getLeft().setSideStartWidth(leftSide);
newShape2.getRight().setSideStartWidth(rightSide);
newShape2.getLeft().setSideEndWidth(oldShape.getLeft().getSideEndWidth());
newShape2.getRight().setSideEndWidth(oldShape.getRight().getSideEndWidth());
oldShape.getRight().setSideEndWidth(rightSide);
oldShape.getLeft().setSideEndWidth(leftSide);
newShape2.setProfilStepsLength(4.0);
int count2 = Editor.getProperties().getCurveNameCount() + 1;
Editor.getProperties().setCurveNameCount(count2);
newShape2.setName("curve " + count2);
data.insertElementAt(newShape2, pos + 1);
//Undo.add(new UndoSplitSegment(cloneShape, newShape2));
break;
}
case "rgt":
{
Curve oldShape = (Curve)this.handledShape;
Curve cloneShape = (Curve)oldShape.clone();
Curve newShape2 = new Curve("rgt", oldShape);
double arc = oldShape.getArcDeg();
double rStart = oldShape.getRadiusStart();
double rEnd = oldShape.getRadiusEnd();
double L = (rStart + rEnd) / 2.0 * oldShape.getArcDeg();
double nbSteps = (int)(L / 4.0 + 0.5) + 1;
double stepLength = L / nbSteps;
final double deltaRadiusStep = (rEnd - rStart) / (nbSteps - 1.0);
double tmpAngle = 0.0;
double tmpRadius = rStart;
for (int curStep = 0; curStep < nbSteps; ++curStep)
{
tmpAngle += stepLength / tmpRadius;
tmpRadius += deltaRadiusStep;
}
stepLength *= arc / tmpAngle;
tmpAngle = 0.0;
tmpRadius = rStart;
for (int curStep = 0; curStep < nbSteps; ++curStep)
{
tmpAngle += stepLength / tmpRadius;
tmpRadius += deltaRadiusStep;
oldShape.setArcDeg(tmpAngle);
oldShape.setRadiusEnd(tmpRadius - deltaRadiusStep);
redrawCircuit();
if (oldShape.contains(mousePoint.x, mousePoint.y))
{
splitPoint = curStep / nbSteps;
break;
}
}
newShape2.setArcDeg(arc - tmpAngle);
newShape2.setRadiusEnd(rEnd);
newShape2.setRadiusStart(tmpRadius);
double leftSide = oldShape.getLeft().getSideStartWidth() + (oldShape.getLeft().getSideEndWidth() - oldShape.getLeft().getSideStartWidth()) * splitPoint;
double rightSide = oldShape.getRight().getSideStartWidth() + (oldShape.getRight().getSideEndWidth() - oldShape.getRight().getSideStartWidth()) * splitPoint;
newShape2.getLeft().setBorderWidth(oldShape.getLeft().getBorderWidth());
newShape2.getRight().setBorderWidth(oldShape.getRight().getBorderWidth());
newShape2.getLeft().setSideStartWidth(leftSide);
newShape2.getRight().setSideStartWidth(rightSide);
newShape2.getLeft().setSideEndWidth(oldShape.getLeft().getSideEndWidth());
newShape2.getRight().setSideEndWidth(oldShape.getRight().getSideEndWidth());
oldShape.getRight().setSideEndWidth(rightSide);
oldShape.getLeft().setSideEndWidth(leftSide);
newShape2.setProfilStepsLength(4.0);
int count2 = Editor.getProperties().getCurveNameCount() + 1;
Editor.getProperties().setCurveNameCount(count2);
newShape2.setName("curve " + count2);
data.insertElementAt(newShape2, pos + 1);
//Undo.add(new UndoSplitSegment(cloneShape, newShape2));
break;
}
case "str":
{
Straight oldShape = (Straight)this.handledShape;
Straight cloneShape = (Straight)oldShape.clone();
Straight newShape3 = new Straight();
double length = oldShape.getLength();
for (int i = 0; i < 100; ++i)
{
splitPoint = i * 0.01;
newShape3.setLength(length * (1.0 - splitPoint));
oldShape.setLength(length * splitPoint);
redrawCircuit();
if (oldShape.contains(mousePoint.x, mousePoint.y))
{
break;
}
}
double leftSide2 = oldShape.getLeft().getSideStartWidth() + (oldShape.getLeft().getSideEndWidth() - oldShape.getLeft().getSideStartWidth()) * splitPoint;
double rightSide2 = oldShape.getRight().getSideStartWidth() + (oldShape.getRight().getSideEndWidth() - oldShape.getRight().getSideStartWidth()) * splitPoint;
newShape3.getLeft().setBorderWidth(oldShape.getLeft().getBorderWidth());
newShape3.getRight().setBorderWidth(oldShape.getRight().getBorderWidth());
newShape3.getLeft().setSideStartWidth(leftSide2);
newShape3.getRight().setSideStartWidth(rightSide2);
newShape3.getLeft().setSideEndWidth(oldShape.getLeft().getSideEndWidth());
newShape3.getRight().setSideEndWidth(oldShape.getRight().getSideEndWidth());
oldShape.getRight().setSideEndWidth(rightSide2);
oldShape.getLeft().setSideEndWidth(leftSide2);
int count3 = Editor.getProperties().getStraightNameCount() + 1;
Editor.getProperties().setStraightNameCount(count3);
newShape3.setName("straight " + count3);
data.insertElementAt(newShape3, pos + 1);
//Undo.add(new UndoSplitSegment(cloneShape, newShape3));
break;
}
default:
break;
}
editorFrame.toggleButtonSubdivide.setSelected(false);
editorFrame.documentIsModified = true;
redrawCircuit();
setState(STATE_NONE);
}
break;
}
} catch (Exception ex)
{
@ -599,6 +767,7 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
case STATE_CREATE_STRAIGHT :
case STATE_MOVE_SEGMENTS :
case STATE_DELETE :
case STATE_SUBDIVIDE :
{
if (dragging)
return;