Mercurial > hg > jslab
view src/samer/maths/FunctionPlotter.java @ 5:b67a33c44de7
Remove some crap, etc
author | samer |
---|---|
date | Fri, 05 Apr 2019 21:34:25 +0100 |
parents | bf79fb79ee13 |
children |
line wrap: on
line source
/* * FunctionPlotter.java * * Copyright (c) 2000, Samer Abdallah, King's College London. * All rights reserved. * * This software is provided AS iS and WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ package samer.maths; import samer.maths.Vec.Iterator; import samer.core.*; import samer.core.util.*; import samer.core.types.*; import samer.core.Agent.*; import samer.tools.*; import java.util.*; import java.awt.*; public class FunctionPlotter extends Plotter implements Agent, Observer { private VFunction vfunc; private VMap vmap, xvmap; private boolean autoscale=false; private int type; private Pen pen; private int w, h; Node node=null; int numPoints; public final static int LINE=0; public final static int STEP=1; public final static int FILL=2; public final static int FILL3D=3; public final static int CLOSED=4; public final static int STEPS=5; public FunctionPlotter(VFunction vf) { vfunc=vf; node=Shell.env().node(); w = Shell.getInt("width",240); h = Shell.getInt("height",120); type = Shell.getInt("type", LINE); setAxes( XAXIS|YAXIS); // pen = getPen(); Shell.push("y"); vmap=new VMap(ymap); Shell.pop(); Shell.push("x"); xvmap=new VMap(xmap); Shell.pop(); vmap.addObserver(this); xvmap.addObserver(this); ymap = vmap.getMap(); xmap = xvmap.getMap(); numPoints = Shell.getInt("numpoints",256); // attach commands from this agent to this Viewer exposeCommands( this); exposeCommands( vmap); exposeCommands( xvmap); Shell.registerAgent(this); } protected void realized() { super.realized(); vfunc.addObserver(this); } // .............. Viewer bits ............................. public void update(Observable o, Object s) { if (s==this) return; // &&& if (s==Viewable.DISPOSING) { Shell.releaseViewer(this); } else if (o==vmap) { if (s==VMap.NEW_MAP) ymap = vmap.getMap(); autoscale(); repaint(); } else if (o==xvmap) { if (s==VMap.NEW_MAP) xmap = xvmap.getMap(); autoscale(); repaint(); } else if (vfunc==o) { autoscale(); repaint(); } } public void detach() { Shell.deregisterAgent(this); if (node!=null) { node=null; } if (vfunc!=null) { vfunc.deleteObserver(this); vfunc=null; } super.detach(); } // .............. Agent bits .............................. public void getCommands(Registry r) { r.add("update").add("points"); r.add("line").add("box").add("fill").add("fill3d").add("steps"); r.add("scale").add("autoscale",autoscale); } public void execute(String c, Environment env) throws Exception { if (c.equals("points")) { numPoints=X._int(env.datum(),numPoints); repaint(); } else if (c.equals("line")) { type=LINE; repaint(); } else if (c.equals("box")) { type=CLOSED; repaint(); } else if (c.equals("fill")) { type=FILL; repaint(); } else if (c.equals("fill3d")) { type=FILL3D; repaint(); } else if (c.equals("steps")) { type=STEPS; repaint(); } else if (c.equals("scale")) { scale(); repaint(); } else if (c.equals("autoscale")) { autoscale = X._bool(env.datum(),!autoscale); if (autoscale) { scale(); repaint(); } } } private class FunctionIterator implements Iterator { int i=0, n=numPoints; double x=xmap.inverse(0); double dx=(xmap.inverse(1)-x)/n; Function function=vfunc.getFunction(); public boolean more() { return i<=n; } public double next() { double y=function.apply(x); x+=dx; i++; return y; } } // ................ functionality ........................... public void autoscale() { if (autoscale) scale(); } public void scale() { double max, min, x; Iterator i=new FunctionIterator(); min=max=i.next(); while (i.more()) { x=i.next(); if (x>max) max=x; if (x<min) min=x; } if (ymap instanceof LinearMap) { // leave some space double delta=max-min; min -= 0.1*delta; max += 0.1*delta; } else if (ymap instanceof LogMap) { // somewhat arbitrarily... if (min==0) min=max/10000; } vmap.setDomain(min,max); vmap.changed(this); } synchronized public void paint( Graphics g) { super.paint(g); // draw axes or whatever FunctionIterator i=new FunctionIterator(); double x, y; pen=getPen(g); // pen.assert(); switch (type) { case LINE: x=i.x; pen.moveto(x,i.next()); while (i.more()) { x=i.x; pen.lineto(x,i.next()); } break; case FILL3D: while (i.more()) { pen.moveto(i.x,0); y=i.next(); pen.abs(i.x,y).rectify(); pen.fill3DRect(true); } break; case FILL: while (i.more()) { pen.moveto(i.x,0); y=i.next(); pen.abs(i.x,y).rectify(); pen.fillRect(); } break; } } public Dimension getPreferredSize() { return new Dimension(w,h); } }