public static final void drawGrid(final Canvas canvas, final OrbiterMouseHandler orbiter) { final double s = 500.0; final double minimumX = orbiter.getCenterX() - s; final double maximumX = orbiter.getCenterX() + s; final double minimumY = orbiter.getCenterY() - s; final double maximumY = orbiter.getCenterY() + s; final double z = 0.0; final int stripes = 10; final double amplitudeX = maximumX - minimumX; final double amplitudeY = maximumY - minimumY; final int n = 3 * 2 * (stripes + 1) * 2; final double[] segments = new double[n]; for (int i = 0, j = 0; i <= stripes; ++i) { segments[j++] = minimumX; segments[j++] = minimumY + i * amplitudeY / stripes; segments[j++] = z; segments[j++] = maximumX; segments[j++] = minimumY + i * amplitudeY / stripes; segments[j++] = z; segments[j++] = minimumX + i * amplitudeX / stripes; segments[j++] = minimumY; segments[j++] = z; segments[j++] = minimumX + i * amplitudeY / stripes; segments[j++] = maximumY; segments[j++] = z; } orbiter.transform(segments); final Graphics2D g = canvas.getGraphics(); final int bottom = canvas.getHeight() - 1; g.setColor(Color.GRAY); for (int i = 0; i < n; i += 6) { g.drawLine( iround(segments[i + 0]), iround(bottom - segments[i + 1]), iround(segments[i + 3]), iround(bottom - segments[i + 4])); } }
/** * @param commandLineArguments <br> * Unused */ public static final void main(final String[] commandLineArguments) { final DoubleList vertices = new DoubleList(); final DoubleList masses = new DoubleList(); vertices.addAll(0.0, 0.0, -640000000.0); masses.addAll(Double.POSITIVE_INFINITY); final DoubleList transformedVertices = new DoubleList(); final Canvas canvas = new Canvas().setFormat(600, 600, BufferedImage.TYPE_3BYTE_BGR); final Canvas ids = new Canvas().setFormat(canvas.getWidth(), canvas.getHeight(), BufferedImage.TYPE_3BYTE_BGR); final JLabel view = new JLabel(new ImageIcon(canvas.getImage())); final AtomicInteger idUnderMouse = new AtomicInteger(-1); final OrbiterMouseHandler orbiter = new OrbiterMouseHandler(null) .setCenterX(canvas.getWidth() / 2.0) .setCenterY(canvas.getHeight() / 2.0); new MouseHandler(orbiter.getUpdateNeeded()) { private double massUnderMouse; @Override public final void mouseMoved(final MouseEvent event) { if (event.isConsumed()) { return; } final int newIdUnderMouse = (ids.getImage().getRGB(event.getX(), event.getY()) & 0x00FFFFFF) - 1; final int oldIdUnderMouse = idUnderMouse.getAndSet(newIdUnderMouse); if (newIdUnderMouse != oldIdUnderMouse) { if (0 <= oldIdUnderMouse) { masses.set(oldIdUnderMouse, this.massUnderMouse); } if (0 <= newIdUnderMouse) { this.massUnderMouse = masses.get(newIdUnderMouse); masses.set(newIdUnderMouse, Double.POSITIVE_INFINITY); } this.getUpdateNeeded().set(true); } } @Override public final void mouseDragged(final MouseEvent event) { if (event.isConsumed()) { return; } final int offsetUnderMouse = idUnderMouse.get() * 3; final double[] locations = transformedVertices.toArray(); if (0 <= offsetUnderMouse) { final double[] location = { locations[offsetUnderMouse + X], locations[offsetUnderMouse + Y], locations[offsetUnderMouse + Z] }; location[X] = event.getX(); location[Y] = canvas.getHeight() - 1 - event.getY(); orbiter.inverseTransform(location); vertices.set(offsetUnderMouse + X, location[X]); vertices.set(offsetUnderMouse + Y, location[Y]); vertices.set(offsetUnderMouse + Z, location[Z]); event.consume(); } this.getUpdateNeeded().set(true); } /** {@value}. */ private static final long serialVersionUID = 1415975957612152368L; }.addTo(view); final StickMan stickMan = new StickMan(vertices, masses) .translate(orbiter.getCenterX(), orbiter.getCenterY(), orbiter.getCenterZ()); orbiter.addTo(view); show(view, Demo.class.getName(), false); new Animator(view) { @Override protected final boolean animateFrame() { if (orbiter.getUpdateNeeded().getAndSet(false)) { transformedVertices.clear().addAll(vertices.toArray()); orbiter.transform(transformedVertices.toArray()); canvas.clear(Color.BLACK); ids.clear(Color.BLACK); drawGrid(canvas, orbiter); stickMan.draw(transformedVertices.toArray(), canvas, ids, idUnderMouse, orbiter); drawAxes(canvas, orbiter); } { final int n = vertices.size(); for (int i = 3; i < n; i += 3) { final double m = masses.get(i / 3); if (!Double.isInfinite(m)) { final double oldZ = vertices.get(i + Z); final double newZ = max(0.0, oldZ - 10.0); if (oldZ != newZ) { orbiter.getUpdateNeeded().set(true); vertices.set(i + Z, newZ); } } } } while (10.0 < stickMan.update()) { orbiter.getUpdateNeeded().set(true); } return view.isShowing(); } /** {@value}. */ private static final long serialVersionUID = -809734448123973442L; }.setFrameRate(10.0).animate(); }