// RadialLine.java /* This application demonstrates a fixed-length line that is manipulable through manual picking (i.e., not with a direct manipulation renderer). */ import visad.*; import visad.java3d.*; import visad.util.Util; import java.awt.event.*; import java.rmi.RemoteException; import java.util.Vector; import javax.swing.*; public class RadialLine { private static final float LENGTH = 5; private static final float END_X = 2; private static final float END_Y = 3; private static final double THRESHOLD = 0.1; public static void main(String[] args) throws Exception { // math types RealType x = RealType.getRealType("x"); RealType y = RealType.getRealType("y"); final RealTupleType xy = new RealTupleType(x, y); // mappings ScalarMap xmap = new ScalarMap(x, Display.XAxis); ScalarMap ymap = new ScalarMap(y, Display.YAxis); xmap.setRange(END_X - LENGTH, END_X + LENGTH); ymap.setRange(END_Y - LENGTH, END_Y + LENGTH); // display final DisplayImpl display = new DisplayImplJ3D("display", new TwoDDisplayRendererJ3D()); display.disableAction(); display.addMap(xmap); display.addMap(ymap); GraphicsModeControl gmc = display.getGraphicsModeControl(); gmc.setScaleEnable(true); gmc.setPointSize(5.0f); // data references final DataReferenceImpl lineRef = new DataReferenceImpl("line"); display.addReference(lineRef); // data objects doLine(xy, 0, 0, lineRef); display.enableEvent(DisplayEvent.MOUSE_DRAGGED); display.addDisplayListener(new DisplayListener() { private boolean isDragging = false; public void displayChanged(DisplayEvent e) { // verify mouse press or drag int id = e.getId(); boolean press = id == DisplayEvent.MOUSE_PRESSED; boolean drag = id == DisplayEvent.MOUSE_DRAGGED; boolean release = id == DisplayEvent.MOUSE_RELEASED; if (!press && !drag && !release) return; // verify right mouse button only MouseEvent mouse = (MouseEvent) e.getInputEvent(); if (!SwingUtilities.isRightMouseButton(mouse)) return; if (release) { isDragging = false; return; // done dragging } // get point coordinates int x = e.getX(); int y = e.getY(); double[] vals = pixelToDomain(display, x, y); // verify coordinates are close enough to the line if (press) { try { Gridded2DSet set = (Gridded2DSet) lineRef.getData(); float[][] samps = set.getSamples(false); double[] ep1 = {samps[0][0], samps[1][0]}; double[] ep2 = {samps[0][1], samps[1][1]}; double dist = getDistance(ep1, ep2, vals, true); if (dist > THRESHOLD) return; // click is too far away isDragging = true; } catch (VisADException exc) { exc.printStackTrace(); } } if (!isDragging) return; // adjust point coordinates float xval = (float) vals[0]; float yval = (float) vals[1]; float xlen = END_X - xval; float ylen = END_Y - yval; float len = (float) Math.sqrt(xlen * xlen + ylen * ylen); if (!Util.isApproximatelyEqual(len, LENGTH)) { double lamda = LENGTH / len; xval = (float) (END_X + lamda * (xval - END_X)); yval = (float) (END_Y + lamda * (yval - END_Y)); } // update line try { doLine(xy, xval, yval, lineRef); } catch (Exception exc) { exc.printStackTrace(); } } }); display.enableAction(); // show display onscreen JFrame frame = new JFrame("Radial line with manual picking"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); p.add(display.getComponent()); frame.setContentPane(p); frame.setSize(400, 400); Util.centerWindow(frame); frame.show(); } private static void doLine(RealTupleType rtt, float x, float y, DataReferenceImpl lineRef) throws VisADException, RemoteException { float[][] samples = { {x, END_X}, {y, END_Y} }; Gridded2DSet set = new Gridded2DSet(rtt, samples, 2); lineRef.setData(set); } // -- Utility methods -- /** Converts the given cursor coordinates to domain coordinates. */ public static double[] cursorToDomain(DisplayImpl d, double[] cursor) { return cursorToDomain(d, null, cursor); } /** Converts the given cursor coordinates to domain coordinates. */ public static double[] cursorToDomain(DisplayImpl d, RealType[] types, double[] cursor) { // locate x, y and z mappings Vector maps = d.getMapVector(); int numMaps = maps.size(); ScalarMap mapX = null, mapY = null, mapZ = null; for (int i=0; i a[i] && p[i] > b[i]) flag = a[i] > b[i] ? 1 : 2; else if (p[i] < a[i] && p[i] < b[i]) flag = a[i] < b[i] ? 1 : 2; else continue; break; } } double sum = 0; for (int i=0; i