package viewer.hoese.algebras; import javax.swing.*; import java.awt.*; import java.awt.geom.*; import java.awt.event.*; import java.util.Vector; import java.util.Iterator; import tools.Reporter; import tools.LineSimplification; /* This class provides a panel able to display several functions. */ public class MultiFunctionPanel extends JPanel{ public MultiFunctionPanel(){ MML = new MouseMotionAdapter(){ public void mouseMoved(MouseEvent e){ lastX = e.getX(); lastY = e.getY(); repaint(); } public void mouseDragged(MouseEvent evt){ mouseMoved(evt); } }; addComponentListener(new ComponentAdapter(){ public void componentResized(ComponentEvent e){ // all functions must be computed new setToNull(); y_computed=false; repaint(); } }); //segmentsComputed = false; setToNull(); y_computed = false; } /** sets all segment vector to be null. * So all segments must be computed newly; */ private void setToNull(){ for(int i=0;i compute functions new } for(int i=0;imax){ double tmp = min; min = max; max = tmp; } if(allFunctions.size()==1){ // the first function xmin = min; xmax = max; } else { if(min xmax){ xmax = max; } } } /** computes a new color from the last one and stores it * in the corresponding vector. **/ private void addColor(){ if(removedColors.size()>0){ allColors.add(removedColors.remove(0)); return; } int r = 0; int g = 0; int b = 0; int number = allFunctions.size()-1; if(number >= 5){ // don't allow white color number++; } int pos = 1; while(number>0){ int next = number % 8; // extract the last 3 bits number = number / 8; int ext = 255 / pos; if( (next & 1) != 0) { r += ext % 256; } if( (next & 2) != 0 ){ g += ext % 256; } if( (next & 4 ) != 0 ){ b += ext % 256; } pos++; } allColors.add(new Color(r,g,b)); } /** Checks whether the given function is displayed. **/ public boolean contains(Function f){ return allFunctions.contains(f); } public void setVirtualSize(double x, double y){ //segmentsComputed=false; setToNull(); y_computed = false; setPreferredSize(new Dimension((int)x,(int)y)); revalidate(); } public boolean remove(Function f){ int index = allFunctions.indexOf(f); if(index < 0){ return false; } allFunctions.remove(index); allSegments.remove(index); removedColors.add(allColors.remove(index)); //segmentsComputed = false; updateInterval(); setToNull(); // may be y value is changed, compute all new y_computed = false; return true; } public void removeAllFunctions(){ allFunctions.clear(); allSegments.clear(); allColors.clear(); removedColors.clear(); y_computed = false; updateInterval(); } private void updateInterval(){ xmin = 0; xmax = 1; for(int i=0;i< allFunctions.size();i++){ boolean first = i==0; Function f = (Function) allFunctions.get(i); double min = f.getInterval().getStart(); double max = f.getInterval().getEnd(); if(first || minxmax){ xmax = max; } } } /* computes the minimum and the maximum y value for the given function **/ private void compute_y(Function f, int witdh, int height, java.awt.geom.Point2D.Double result){ boolean first=true; double dx = xmax-xmin; double y_min= 0; double y_max=0; Double y; for(int i=0;iy_max) y_max=y1; } } } result.x = y_min; result.y = y_max; } /** Computes the minumum and maximum y value of all functions. */ private void compute_y(int width,int height){ java.awt.geom.Point2D.Double p = new java.awt.geom.Point2D.Double(); for(int i=0;iymax){ ymax = p.y; } } } double dy = ymax-ymin; // now, the bounding box of the function is determined // we can compute an affine transformation for bringing the // function to screen double scaleX = 1.0; //width/dx; double scaleY; if(dy!=0){ scaleY = height/dy; }else{ scaleY = 1; } double tx = 0; // -xmin; double ty = -ymin; AffineTransform Flip = new AffineTransform(); at.setTransform(scaleX,0,0,scaleY,scaleX*tx,scaleY*ty); at.preConcatenate(AffineTransform.getTranslateInstance(0,-height)); at.preConcatenate(AffineTransform.getScaleInstance(1,-1)); AffineTransform trans = (AffineTransform.getTranslateInstance(borderSize,borderSize)); at.preConcatenate(trans); try{ AffineTransform ati = at.createInverse(); if(atinv==null){ // create a new matrix if required atinv = new double[6]; } ati.getMatrix(atinv); }catch(Exception e){ Reporter.debug("could not create the inverse matrix"); atinv=null; } } private Vector allFunctions = new Vector(10); private Vector allSegments = new Vector(10); private Vector allColors = new Vector(10); private Vector allComputed = new Vector(10); private Vector removedColors = new Vector(10); private double xmin=0; private double xmax=1; private boolean y_computed=false; private double ymin; private double ymax; private AffineTransform at=new AffineTransform(); private double[] atinv=new double[6]; private boolean crossEnabled=false; private int lastX; private int lastY; private boolean yEnabled=false; private MouseMotionListener MML; private Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR); private Cursor crossCursor = new Cursor(Cursor.CROSSHAIR_CURSOR); private static final int borderSize = 35; //private boolean segmentsComputed=false; private int width; // width for function = whole width - 2*bordersize }