/* * Copyright (C) 1998 Ralf Wiebicke * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package de.rw7; import java.applet.Applet; import java.awt.Button; import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Event; import java.awt.Graphics; class Display extends Canvas { Applet app; Dimension mySize; Display(Applet app, Dimension mySize) { this.app = app; this.mySize = mySize; } private Function F = null; private int Fdim; private double[] args; private int fl; private double minX, maxX, DotsPerX; private int IdealDotsX = 40; private double minY, maxY, DotsPerY; private int IdealDotsY = 20; void setFunction(Function F) { this.F = F; if (F != null) { Fdim = F.getDim(); args = new double[Fdim]; for (int i = 0; i < Fdim; i++) args[i] = F.suggestVal(i); fl = F.suggestFloating(); minX = F.suggestMin(fl); maxX = F.suggestMax(fl); DotsPerX = mySize.width / (maxX - minX); minY = F.suggestMin(-1); maxY = F.suggestMax(-1); DotsPerY = mySize.height / (maxY - minY); } repaint(); } public void paintAxes(Graphics g) { Dimension d = mySize; g.drawRect(0, 0, d.width - 1, d.height - 1); if (F == null) { g.drawLine(0, 0, d.width, d.height); g.drawLine(0, d.height, d.width, 0); return; } int wx; int wy; double markStep, markEnd, curr; markStep = fit(IdealDotsX / DotsPerX); markEnd = Math.ceil(maxX / markStep) * markStep; for (int i = 0;; i++) { curr = markEnd - markStep * i; if (curr <= minX) break; wx = (int) ((curr - minX) * DotsPerX); switch (i) { case 0 : break; case 2 : g.drawString(F.getDesc(fl), wx, d.height - 8); break; default : g.drawString(String.valueOf(curr), wx, d.height - 8); } g.drawLine(wx, d.height - 4, wx, d.height); } markStep = fit(IdealDotsY / DotsPerY); markEnd = Math.ceil(maxY / markStep) * markStep; for (int i = 0;; i++) { curr = markEnd - markStep * i; if (curr <= minY) break; wy = d.height - (int) ((curr - minY) * DotsPerY); switch (i) { case 0 : break; case 2 : g.drawString(F.getDesc(-1), 8, wy - 3); break; default : g.drawString(String.valueOf(curr), 8, wy); } g.drawLine(0, wy, 4, wy); }; } public void paintGraph(Graphics g) { if (F == null) return; double[] args = new double[Fdim]; for (int i = 0; i < args.length; i++) args[i] = this.args[i]; Dimension d = mySize; double DeltaX; double zX, zY; double[] fzY; int wx, wy; zX = minX; DeltaX = (1d) / DotsPerX; boolean notfirst = false; wy = 0; for (wx = 0; wx < d.width; wx++) { args[fl] = zX; fzY = F.value(args); for (int i = 0; i < fzY.length; i++) { zY = fzY[i]; if ((minY <= zY) && (zY <= maxY)) { wy = d.height - (int) ((zY - minY) * DotsPerY); if (notfirst) g.drawLine(wx, wy, wx, wy); else notfirst = true; } else { notfirst = false; }; } zX += DeltaX; //if ((wx&15)==0) repaint(); } } static double fit(double x) { double e10 = Math.pow(10d, Math.floor(Math.log(x) / Math.log(10d))); double z = x / e10; z = (z <= 1) ? 1 : (z <= 2) ? 2 : (z <= 2.5) ? 2.5 : (z <= 5) ? 5 : 10; return (z * e10); } // Umrechnung: double = ((double)(pix) / DotsPer) + min private int mouseDownX = 0, mouseDownY = 0; private int mouseUpX = 0, mouseUpY = 0; public boolean mouseMove(Event e, int x, int y) { app.showStatus( "(" + String.valueOf(minX + (double) (x) / DotsPerX) + "," + String.valueOf(maxY - (double) (y) / DotsPerY) + ")"); return (true); } public boolean mouseDrag(Event e, int x, int y) { app.showStatus( "Selected(" + String.valueOf(minX + (double) (x) / DotsPerX) + "," + String.valueOf(maxY - (double) (y) / DotsPerY) + ")"); return (true); } public boolean mouseDown(Event e, int x, int y) { mouseDownX = x; mouseDownY = y; return (true); } public boolean mouseUp(Event e, int x, int y) { mouseUpX = x; mouseUpY = y; return (true); } public boolean action(Event e, Object arg) { if (e.target instanceof Button) { if (arg.equals("Zoom In") || arg.equals("Zoom Out")) { DotsPerX = mySize.width / (maxX - minX); DotsPerY = mySize.height / (maxY - minY); if ((mouseDownX == mouseUpX) || (mouseDownY == mouseUpY)) return (true); if (mouseDownX > mouseUpX) { int z = mouseDownX; mouseDownX = mouseUpX; mouseUpX = z; }; if (mouseDownY > mouseUpY) { int z = mouseDownY; mouseDownY = mouseUpY; mouseUpY = z; }; if (arg.equals("Zoom In")) { minX += (double) (mouseDownX) / DotsPerX; maxX -= (double) (mySize.width - mouseUpX) / DotsPerX; minY += (double) (mySize.height - mouseUpY) / DotsPerY; maxY -= (double) (mouseDownY) / DotsPerY; } else { } DotsPerX = mySize.width / (maxX - minX); DotsPerY = mySize.height / (maxY - minY); repaint(); return (true); }; }; return (false); } public void paint(Graphics g) { DotsPerX = mySize.width / (maxX - minX); DotsPerY = mySize.height / (maxY - minY); g.setColor(Color.gray); paintAxes(g); g.setColor(Color.black); paintGraph(g); System.out.println("ready."); } public Dimension preferredSize() { return (mySize); } public Dimension minimumSize() { return (preferredSize()); } } // class Display