trackeditor: show elevation at cursor position
git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@9300 30fe4595-0a0c-4342-8851-515496e4dcbd
This commit is contained in:
parent
0ddf3071db
commit
99b4b78eb0
|
@ -305,6 +305,9 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
|
|||
/** input events management */
|
||||
public void mouseClicked(MouseEvent e)
|
||||
{
|
||||
if (editorFrame.getTrackData() == null)
|
||||
return;
|
||||
|
||||
if (e.getButton() == MouseEvent.BUTTON1)
|
||||
{
|
||||
screenToReal(e, clickPoint);
|
||||
|
@ -716,6 +719,9 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
|
|||
/** input events management */
|
||||
public void mousePressed(MouseEvent e)
|
||||
{
|
||||
if (editorFrame.getTrackData() == null)
|
||||
return;
|
||||
|
||||
if (e.getButton() == MouseEvent.BUTTON3)
|
||||
{
|
||||
Segment obj = findObjAtMousePos();
|
||||
|
@ -925,6 +931,9 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
|
|||
/** input events management */
|
||||
public void mouseReleased(MouseEvent e)
|
||||
{
|
||||
if (editorFrame.getTrackData() == null)
|
||||
return;
|
||||
|
||||
if (e.getButton() == MouseEvent.BUTTON1)
|
||||
{
|
||||
switch (currentState)
|
||||
|
@ -987,6 +996,9 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
|
|||
/** input events management */
|
||||
public void mouseDragged(MouseEvent e)
|
||||
{
|
||||
if (editorFrame.getTrackData() == null)
|
||||
return;
|
||||
|
||||
if (e.getModifiers() == 4)
|
||||
{
|
||||
if (objectShape != null && objectDragging == true)
|
||||
|
@ -1079,6 +1091,9 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
|
|||
/** input events management */
|
||||
public void mouseMoved(MouseEvent e)
|
||||
{
|
||||
if (editorFrame.getTrackData() == null)
|
||||
return;
|
||||
|
||||
screenToReal(e, mousePoint);
|
||||
|
||||
if (editorFrame.getCursorCoordinates())
|
||||
|
@ -1194,6 +1209,9 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
|
|||
|
||||
public void mouseWheelMoved(MouseWheelEvent e)
|
||||
{
|
||||
if (editorFrame.getTrackData() == null)
|
||||
return;
|
||||
|
||||
screenToReal(e, mousePoint);
|
||||
|
||||
getParent().dispatchEvent(e);
|
||||
|
@ -1668,6 +1686,9 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
|
|||
*/
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
if (editorFrame.getTrackData() == null)
|
||||
return;
|
||||
|
||||
graphics = g;
|
||||
|
||||
// visible part of screen in pixels
|
||||
|
@ -1677,7 +1698,37 @@ public class CircuitView extends JComponent implements KeyListener, MouseListene
|
|||
{
|
||||
if (editorFrame.getTrackData() != null)
|
||||
{
|
||||
String coordinates = String.format("x: %.3f y: %.3f", + mousePoint.x, + mousePoint.y);
|
||||
String coordinates = null;
|
||||
|
||||
// must check for a object under the mouse
|
||||
Segment obj = findObjAtMousePos();
|
||||
|
||||
if (obj != null)
|
||||
{
|
||||
if (obj.getType().equals("rgt") ||
|
||||
obj.getType().equals("lft") ||
|
||||
obj.getType().equals("str"))
|
||||
{
|
||||
double height = obj.getHeightAt(editorFrame, mousePoint.x, mousePoint.y);
|
||||
coordinates = String.format("x: %.3f y: %.3f z: %.3f", mousePoint.x, mousePoint.y, height);
|
||||
/*
|
||||
MutableDouble height = new MutableDouble();
|
||||
MutableDouble slopeLeft = new MutableDouble();
|
||||
MutableDouble slopeRight = new MutableDouble();
|
||||
if (obj.getHeightAndSlopeAt(editorFrame, mousePoint.x, mousePoint.y, height, slopeLeft, slopeRight))
|
||||
{
|
||||
double slope = (slopeLeft.getValue() + slopeRight.getValue()) / 2.0;
|
||||
|
||||
coordinates = String.format("x: %.3f y: %.3f z: %.3f slope: %.3f", mousePoint.x, mousePoint.y, height.getValue(), slope);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (coordinates == null)
|
||||
{
|
||||
coordinates = String.format("x: %.3f y: %.3f", mousePoint.x, mousePoint.y);
|
||||
}
|
||||
|
||||
graphics.drawString(coordinates, r.x + 10, r.y + 20);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public class Properties
|
|||
private static Properties instance = new Properties();
|
||||
private Vector<ActionListener> propertiesListeners = new Vector<ActionListener>();
|
||||
public final String title = "sd2-trackeditor";
|
||||
public final String version = "1.4.27";
|
||||
public final String version = "1.4.28";
|
||||
private String path;
|
||||
|
||||
private double imageScale = 1;
|
||||
|
|
|
@ -30,6 +30,8 @@ import java.util.Arrays;
|
|||
import java.util.Vector;
|
||||
|
||||
import gui.EditorFrame;
|
||||
import utils.Editor;
|
||||
import utils.MutableDouble;
|
||||
|
||||
/**
|
||||
* @author Patrice Espie , Charalampos Alexopoulos
|
||||
|
@ -2260,6 +2262,153 @@ public class Segment implements Cloneable
|
|||
right.setSideBankingType(getValidRightSideBankingType(editorFrame));
|
||||
}
|
||||
|
||||
public double getGradeAt(EditorFrame editorFrame, double splitPoint)
|
||||
{
|
||||
int splitStep = (int) (splitPoint * nbSteps);
|
||||
int splitSubSeg = 4 * (7 + (Editor.getProperties().getShowArrows() > 0.0 ? 1 : 0)) * splitStep;
|
||||
double startZ = (points[splitSubSeg].z + points[splitSubSeg + 3].z) / 2;
|
||||
double endZ = (points[splitSubSeg + 1].z + points[splitSubSeg + 2].z) / 2;
|
||||
|
||||
return ((endZ - startZ) / stepLength) * 100;
|
||||
}
|
||||
|
||||
public double getGradeAtLeft(EditorFrame editorFrame, double splitPoint)
|
||||
{
|
||||
int splitStep = (int) (splitPoint * nbSteps);
|
||||
int splitSubSeg = 4 * (7 + (Editor.getProperties().getShowArrows() > 0.0 ? 1 : 0)) * splitStep;
|
||||
double startZ = points[splitSubSeg].z;
|
||||
double endZ = points[splitSubSeg + 1].z;
|
||||
|
||||
return ((endZ - startZ) / stepLength) * 100;
|
||||
}
|
||||
|
||||
public double getGradeAtRight(EditorFrame editorFrame, double splitPoint)
|
||||
{
|
||||
int splitStep = (int) (splitPoint * nbSteps);
|
||||
int splitSubSeg = 4 * (7 + (Editor.getProperties().getShowArrows() > 0.0 ? 1 : 0)) * splitStep;
|
||||
double startZ = points[splitSubSeg + 3].z;
|
||||
double endZ = points[splitSubSeg + 2].z;
|
||||
|
||||
return ((endZ - startZ) / stepLength) * 100;
|
||||
}
|
||||
|
||||
// from https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
|
||||
private static final double EPSILON = 0.0000001;
|
||||
|
||||
public static boolean rayIntersectsTriangle(Point3D rayOrigin,
|
||||
Point3D rayVector,
|
||||
Point3D vertex0,
|
||||
Point3D vertex1,
|
||||
Point3D vertex2,
|
||||
Point3D outIntersectionPoint)
|
||||
{
|
||||
Point3D edge1 = new Point3D();
|
||||
Point3D edge2 = new Point3D();
|
||||
Point3D h = new Point3D();
|
||||
Point3D s = new Point3D();
|
||||
Point3D q = new Point3D();
|
||||
double a, f, u, v;
|
||||
edge1.sub(vertex1, vertex0);
|
||||
edge2.sub(vertex2, vertex0);
|
||||
h.cross(rayVector, edge2);
|
||||
a = edge1.dot(h);
|
||||
|
||||
if (a > -EPSILON && a < EPSILON)
|
||||
{
|
||||
return false; // This ray is parallel to this triangle.
|
||||
}
|
||||
|
||||
f = 1.0 / a;
|
||||
s.sub(rayOrigin, vertex0);
|
||||
u = f * (s.dot(h));
|
||||
|
||||
if (u < 0.0 || u > 1.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
q.cross(s, edge1);
|
||||
v = f * rayVector.dot(q);
|
||||
|
||||
if (v < 0.0 || u + v > 1.0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// At this stage we can compute t to find out where the intersection point is on the line.
|
||||
double t = f * edge2.dot(q);
|
||||
if (t > EPSILON) // ray intersection
|
||||
{
|
||||
outIntersectionPoint.set(0.0, 0.0, 0.0);
|
||||
outIntersectionPoint.scaleAdd(t, rayVector, rayOrigin);
|
||||
return true;
|
||||
}
|
||||
else // This means that there is a line intersection but not a ray intersection.
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public double getHeightAt(EditorFrame editorFrame, double x, double y)
|
||||
{
|
||||
if (points == null)
|
||||
return 0.0;
|
||||
|
||||
Point3D rayOrigin = new Point3D(x, y, -1000.0);
|
||||
Point3D rayVector = new Point3D(0.0, 0.0, 1.0);
|
||||
Point3D intersectionPoint = new Point3D();
|
||||
|
||||
int stride = 4 * (7 + (Editor.getProperties().getShowArrows() > 0.0 ? 1 : 0));
|
||||
|
||||
for (int i = 0; i < points.length; i += stride)
|
||||
{
|
||||
if (rayIntersectsTriangle(rayOrigin, rayVector, points[i + 0], points[i + 1], points[i + 2], intersectionPoint))
|
||||
{
|
||||
return intersectionPoint.z;
|
||||
}
|
||||
if (rayIntersectsTriangle(rayOrigin, rayVector, points[i + 0], points[i + 2], points[i + 3], intersectionPoint))
|
||||
{
|
||||
return intersectionPoint.z;
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public boolean getHeightAndSlopeAt(EditorFrame editorFrame, double x, double y, MutableDouble height, MutableDouble slopeLeft, MutableDouble slopeRight)
|
||||
{
|
||||
if (points == null)
|
||||
return false;
|
||||
|
||||
Point3D rayOrigin = new Point3D(x, y, -1000.0);
|
||||
Point3D rayVector = new Point3D(0.0, 0.0, 1.0);
|
||||
Point3D intersectionPoint = new Point3D();
|
||||
|
||||
int stride = 4 * (7 + (Editor.getProperties().getShowArrows() > 0.0 ? 1 : 0));
|
||||
|
||||
for (int i = 0; i < points.length; i += stride)
|
||||
{
|
||||
if (rayIntersectsTriangle(rayOrigin, rayVector, points[i + 0], points[i + 1], points[i + 2], intersectionPoint))
|
||||
{
|
||||
height.setValue(intersectionPoint.z);
|
||||
double at = (((i / stride) * stepLength) + (stepLength / 2)) / length;
|
||||
slopeLeft.setValue(getGradeAtLeft(editorFrame, at));
|
||||
slopeRight.setValue(getGradeAtRight(editorFrame, at));
|
||||
return true;
|
||||
}
|
||||
if (rayIntersectsTriangle(rayOrigin, rayVector, points[i + 0], points[i + 2], points[i + 3], intersectionPoint))
|
||||
{
|
||||
height.setValue(intersectionPoint.z);
|
||||
double at = (((i / stride) * stepLength) + (stepLength / 2)) / length;
|
||||
slopeLeft.setValue(getGradeAtLeft(editorFrame, at));
|
||||
slopeRight.setValue(getGradeAtRight(editorFrame, at));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void dump(String indent)
|
||||
{
|
||||
dump(indent, true, true, true, true);
|
||||
|
|
Loading…
Reference in New Issue