/** GPCompGraph.java * J Scott Cameron * * This Swing component is a graph that will graph the * two Symbolic regression GP's (usually the best and the goal) * over a given domain and range */ import javax.swing.*; import java.awt.*; import java.awt.geom.*; import java.awt.font.*; import GPNode; import Operators; public class GPCompGraph extends JPanel { GPNode test; /* goal GP */ GPNode best; /* best GP found*/ Operators operators; /* class with functions in it */ double hUnit,vUnit; /* horizontal/vertical units/pixel */ double xMin,xMax,yMin,yMax;/* bounds of the graph */ Rectangle2D.Double bounds; /* parameterized constructor */ public GPCompGraph(Operators op,GPNode test, GPNode best,double xMin, double xMax, double yMin, double yMax) { operators = op; this.test = test.copy(); this.best = best.copy(); this.xMin = xMin; this.yMin = yMin; this.yMax = yMax; this.xMax = Math.max(xMin+1,xMax); this.yMax = Math.max(yMin+1,yMax); } /* updates the graph with new bounds and GP's */ public void updateGraph(GPNode test, GPNode best,double xMin, double xMax, double yMin, double yMax) { this.test = test.copy(); this.best = best.copy(); this.xMin = xMin; this.yMin = yMin; this.yMax = yMax; this.xMax = Math.max(xMin+1,xMax); this.yMax = Math.max(yMin+1,yMax); repaint(); } /* translates coordinates to graph-space and draws a point*/ public void drawPoint(Graphics2D g2,double x,double y) { g2.draw(new Rectangle2D.Double((x-xMin)*hUnit+20, (yMax-y)*vUnit+20,1,1) ); } /* translates coordinates to graph-space and draws a ling*/ public void drawLine(Graphics2D g2,double x1,double y1, double x2, double y2) { /* make sure all the points are valid numbers */ if(!((testDouble(x1) || testDouble(y1)) || (testDouble(x2) || testDouble(y2)))) { double x1trans = (x1-xMin)*hUnit+20; double y1trans = (yMax-y1)*vUnit+20; double x2trans = (x2-xMin)*hUnit+20; double y2trans = (yMax-y2)*vUnit+20; Line2D.Double l = new Line2D.Double(x1trans,y1trans, x2trans,y2trans); /* draw only if it intersects the graph */ if(bounds.intersectsLine( l)) g2.draw(l); } } /* test to makes sure throws double is a graphable quantity*/ public boolean testDouble(double d) { return( ( Double.isNaN(d)|| Double.isInfinite(d))); } /* pain the graph */ public void paintComponent(Graphics g) { setBackground(Color.white); super.paintComponent(g); /* get the dimensions */ int w = getSize().width; int h = getSize().height; int i; Graphics2D g2; g2 = (Graphics2D) g; /* set the rendering state to quality and turn * antialiasing on */ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); /* give the graph a twenty pizel margin*/ int graphBottom = h-20; int graphRight = w-20; /* create a font object for drawing text*/ FontRenderContext frc = g2.getFontRenderContext(); Font f = new Font("Helvetica", 1, 8); g2.setColor(Color.black); /* draw the axes */ g2.draw(new Line2D.Double(20,20,20,graphBottom)); g2.draw(new Line2D.Double(20,graphBottom,graphRight,graphBottom)); /* find the interval for tick marks */ double vInterval = ((yMax-yMin)/10); double hInterval = ((xMax-xMin)/10); /* find units/pixel */ vUnit = (graphBottom-20)/(yMax-yMin); hUnit = (graphRight-20)/(xMax-xMin); /* set the bounding rectangle */ bounds = new Rectangle2D.Double(20,20,graphRight,graphBottom); /* draw the tick marks on the axes*/ for(i=0;i<11;i++) { g2.draw(new Line2D.Double(16,20+i*vInterval*vUnit, 20,20+i*vInterval*vUnit)); g2.draw(new Line2D.Double(20+i*hInterval*hUnit,graphBottom+4, 20+i*hInterval*hUnit,graphBottom)); String s = new String((new Integer((int)(yMin + vInterval*(10-i)))).toString()); String s2 = new String((new Integer((int)(xMin + hInterval*(i)))).toString()); TextLayout textTl = new TextLayout(s, f, frc); TextLayout textT2 = new TextLayout(s2, f, frc); Rectangle r= (textTl.getBounds()).getBounds(); Rectangle r2= (textT2.getBounds()).getBounds(); textTl.draw(g2,0.0f,(float)(20+i*vInterval*vUnit+(r.height/2))); textT2.draw(g2,(float)(20+i*hInterval*hUnit-(r2.width/2)), graphBottom+15); } /* draw lines at x=0 and y=0 */ g2.setColor(Color.lightGray); drawLine(g2,0,yMin,0,yMax); drawLine(g2,xMin,0,xMax,0); /* find the beginning of the first line */ double oldXVal,oldYVal,oldYVal2; oldXVal = (-.5/hUnit+xMin); operators.x = new Double(oldXVal); oldYVal =0; oldYVal2 = 0; try { oldYVal= test.value().doubleValue(); oldYVal2 = best.value().doubleValue(); } catch(NoSuchMethodException e) {; } double xVal,yVal,yVal2; /* find/draw lines across each pixel */ for(i=0;i<(graphRight-20);i++) { xVal = ((i+.5)/hUnit+xMin); operators.x = new Double(xVal); yVal =0; yVal2 = 0; try { yVal= test.value().doubleValue(); yVal2 = best.value().doubleValue(); } catch(NoSuchMethodException e) {; } g2.setColor(Color.red); drawLine(g2,xVal,yVal,oldXVal,oldYVal); g2.setColor(Color.blue); drawLine(g2,xVal,yVal2,oldXVal,oldYVal2); oldXVal = xVal; oldYVal = yVal; oldYVal2 = yVal2; } } }