Då det vore kul med en kurva på det som mäts plus den kurva som
polynomapproximerats och kunna skriva ut denna från NTC-programmet
så har jag dykt ned i kodningen av grafik i Java.
Jag har labbat med att rita axlar i en lagerbild och sedan
plotta kurvan i en annan lagerbild då jag upptäckte att om
jag ville ha en marker för x och y så måste kurvan plottas på
nytt vilket inte blir bra. Att byta en bild går betydligt snabbare
men jag har inte helt testat detta ännu.
I vilket fall så har jag lyckats rita två lager uppepå varandra
med en viss genomskinlighet och det anser jag vara en bra start.
Main...
Kod: Markera allt
import javax.swing.JFrame;
import java.awt.SystemColor;
import javax.swing.JButton;
import javax.swing.Box;
import java.awt.Component;
import java.awt.Dimension;
//import java.awt.EventQueue;
import javax.swing.JSpinner;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.awt.Font;
import java.awt.Label;
import java.awt.Color;
import javax.swing.SpringLayout;
import javax.swing.SpinnerNumberModel;
public class SwingWindow extends JFrame {
private static final long serialVersionUID = 1L;
public final int WINDOW_WIDTH = 800;
public final int WINDOW_HEIGHT = 500;
public static final int CANVAS_WIDTH = 772;
public static final int CANVAS_HEIGHT = 365;
public final int SPINNER_X_STARTVALUE = 0;
public final int SPINNER_Y_STARTVALUE = 0;
// y = 2.31 - 0.0047*x + 1.93*10^-6*x^2
public static final double A = 2.31;
public static final double B = -0.0047;
public static final double C = 0.00000193;
private static JButton b0;
private static JButton b1;
private static JButton b2;
private static JSpinner spinner_X;
private static JSpinner spinner_Y;
private static int spinner_X_value;
private static int spinner_Y_value;
private static Label label_Y;
private static Label label_X;
private JSpinner spinner_dX;
private JSpinner spinner_dY;
public static SwingWindow swingwindow;
/**
* Launch the application.
*/
public static void main(String[] args) {
swingwindow = new SwingWindow();
swingwindow.setVisible(true);
/*EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new SwingWindow();
} catch (Exception e) {
e.printStackTrace();
}
}
}); */
}
/**
* Create the application.
*/
public SwingWindow() {
super("Swing");
setMaximumSize(new Dimension(1000, 800));
getContentPane().setBackground(new Color(240, 230, 140));
getContentPane().setLayout(null);
setBounds(400, 100, WINDOW_WIDTH, WINDOW_HEIGHT);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
setUpGUI();
}
/**
* Initialize the contents of the frame.
*/
private void setUpGUI() {
JPanel panel = new JPanel();
panel.setBackground(SystemColor.menu);
panel.setBounds(5, 376, 575, 76);
getContentPane().add(panel);
SpringLayout sl_panel = new SpringLayout();
panel.setLayout(sl_panel);
Box horizontalBox_1 = Box.createHorizontalBox();
sl_panel.putConstraint(SpringLayout.WEST, horizontalBox_1, 10, SpringLayout.WEST, panel);
sl_panel.putConstraint(SpringLayout.EAST, horizontalBox_1, -10, SpringLayout.EAST, panel);
horizontalBox_1.setOpaque(true);
sl_panel.putConstraint(SpringLayout.NORTH, horizontalBox_1, 11, SpringLayout.NORTH, panel);
panel.add(horizontalBox_1);
JLabel lblYMarker = new JLabel("Y1 marker");
horizontalBox_1.add(lblYMarker);
Component rigidArea = Box.createRigidArea(new Dimension(20, 20));
rigidArea.setMinimumSize(new Dimension(15, 20));
rigidArea.setPreferredSize(new Dimension(15, 20));
rigidArea.setMaximumSize(new Dimension(15, 20));
horizontalBox_1.add(rigidArea);
spinner_Y = new JSpinner();
spinner_Y.setDoubleBuffered(true);
spinner_Y.setMinimumSize(new Dimension(50, 20));
spinner_Y.setPreferredSize(new Dimension(50, 20));
spinner_Y.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
spinner_Y_value = (int) spinner_Y.getValue();
label_Y.setText(String.valueOf(spinner_Y_value));
//canvas.setNewY(spinner_Y_value);
}
});
horizontalBox_1.add(spinner_Y);
Component rigidArea_5 = Box.createRigidArea(new Dimension(20, 20));
rigidArea_5.setMinimumSize(new Dimension(15, 20));
rigidArea_5.setPreferredSize(new Dimension(15, 20));
rigidArea_5.setMaximumSize(new Dimension(15, 20));
horizontalBox_1.add(rigidArea_5);
JLabel lblXMarker = new JLabel("X1 marker");
horizontalBox_1.add(lblXMarker);
Component rigidArea_1 = Box.createRigidArea(new Dimension(20, 20));
rigidArea_1.setMinimumSize(new Dimension(15, 20));
rigidArea_1.setPreferredSize(new Dimension(15, 20));
rigidArea_1.setMaximumSize(new Dimension(15, 20));
horizontalBox_1.add(rigidArea_1);
spinner_X = new JSpinner();
spinner_X.setModel(new SpinnerNumberModel(0, 0, 700, 1));
spinner_X.setDoubleBuffered(true);
spinner_X.setMinimumSize(new Dimension(50, 20));
spinner_X.setPreferredSize(new Dimension(50, 20));
spinner_X.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
spinner_X_value = (int) spinner_X.getValue();
label_X.setText(String.valueOf(spinner_X_value));
// canvas.setMarkerLineX1pos(spinner_X_value);
// canvas.repaint();
}
});
horizontalBox_1.add(spinner_X);
Component rigidArea_8 = Box.createRigidArea(new Dimension(20, 20));
rigidArea_8.setMinimumSize(new Dimension(15, 20));
rigidArea_8.setPreferredSize(new Dimension(15, 20));
rigidArea_8.setMaximumSize(new Dimension(15, 20));
horizontalBox_1.add(rigidArea_8);
JLabel lblXMarker_1 = new JLabel("Y2 marker");
horizontalBox_1.add(lblXMarker_1);
Component rigidArea_6 = Box.createRigidArea(new Dimension(20, 20));
rigidArea_6.setMinimumSize(new Dimension(15, 20));
rigidArea_6.setPreferredSize(new Dimension(15, 20));
rigidArea_6.setMaximumSize(new Dimension(15, 20));
horizontalBox_1.add(rigidArea_6);
spinner_dY = new JSpinner();
spinner_dY.setDoubleBuffered(true);
spinner_dY.setMinimumSize(new Dimension(50, 20));
spinner_dY.setPreferredSize(new Dimension(50, 20));
horizontalBox_1.add(spinner_dY);
Component rigidArea_7 = Box.createRigidArea(new Dimension(20, 20));
rigidArea_7.setMinimumSize(new Dimension(15, 20));
rigidArea_7.setPreferredSize(new Dimension(15, 20));
rigidArea_7.setMaximumSize(new Dimension(15, 20));
horizontalBox_1.add(rigidArea_7);
JLabel lblXMarker_2 = new JLabel("X2 marker");
horizontalBox_1.add(lblXMarker_2);
Component rigidArea_9 = Box.createRigidArea(new Dimension(20, 20));
rigidArea_9.setMinimumSize(new Dimension(15, 20));
rigidArea_9.setPreferredSize(new Dimension(15, 20));
rigidArea_9.setMaximumSize(new Dimension(15, 20));
horizontalBox_1.add(rigidArea_9);
spinner_dX = new JSpinner();
spinner_dX.setDoubleBuffered(true);
spinner_dX.setPreferredSize(new Dimension(50, 20));
spinner_dX.setMinimumSize(new Dimension(40, 20));
horizontalBox_1.add(spinner_dX);
Box horizontalBox = Box.createHorizontalBox();
sl_panel.putConstraint(SpringLayout.WEST, horizontalBox, 10, SpringLayout.WEST, panel);
sl_panel.putConstraint(SpringLayout.EAST, horizontalBox, -10, SpringLayout.EAST, panel);
horizontalBox.setAlignmentX(0.0f);
sl_panel.putConstraint(SpringLayout.NORTH, horizontalBox, 42, SpringLayout.NORTH, panel);
panel.add(horizontalBox);
b0 = new JButton("Plotta Kurva");
b0.setDoubleBuffered(true);
b0.setPreferredSize(new Dimension(130, 23));
b0.setMaximumSize(new Dimension(130, 23));
b0.addActionListener(new Listener().new PlotFunction());
horizontalBox.add(b0);
Component rigidArea_2 = Box.createRigidArea(new Dimension(20, 20));
rigidArea_2.setMaximumSize(new Dimension(22, 20));
rigidArea_2.setMinimumSize(new Dimension(22, 20));
rigidArea_2.setPreferredSize(new Dimension(22, 20));
horizontalBox.add(rigidArea_2);
b1 = new JButton("Radera Kurva");
b1.setDoubleBuffered(true);
b1.setPreferredSize(new Dimension(130, 23));
b1.setMaximumSize(new Dimension(130, 23));
b1.addActionListener(new Listener().new Repaint());
horizontalBox.add(b1);
Component rigidArea_3 = Box.createRigidArea(new Dimension(20, 20));
rigidArea_3.setMaximumSize(new Dimension(22, 20));
rigidArea_3.setMinimumSize(new Dimension(22, 20));
rigidArea_3.setPreferredSize(new Dimension(22, 20));
horizontalBox.add(rigidArea_3);
b2 = new JButton("Render Canvas");
b2.setDoubleBuffered(true);
b2.setPreferredSize(new Dimension(130, 23));
b2.setMaximumSize(new Dimension(130, 23));
b2.addActionListener(new Listener().new Render());
horizontalBox.add(b2);
JButton b3 = new JButton("Avsluta");
b3.setDoubleBuffered(true);
b3.setMinimumSize(new Dimension(72, 23));
b3.setPreferredSize(new Dimension(130, 23));
b3.setMaximumSize(new Dimension(130, 23));
b3.addActionListener(new Listener().new Avbryt());
Component rigidArea_4 = Box.createRigidArea(new Dimension(20, 20));
rigidArea_4.setMaximumSize(new Dimension(22, 20));
rigidArea_4.setMinimumSize(new Dimension(22, 20));
rigidArea_4.setPreferredSize(new Dimension(22, 20));
horizontalBox.add(rigidArea_4);
horizontalBox.add(b3);
JPanel panel_1 = new JPanel();
panel_1.setOpaque(false);
panel_1.setForeground(new Color(0, 0, 0));
panel_1.setBackground(new Color(255, 255, 255));
panel_1.setBounds(612, 376, 165, 20);
getContentPane().add(panel_1);
panel_1.setLayout(null);
label_Y = new Label(String.valueOf(SPINNER_Y_STARTVALUE));
label_Y.setFont(new Font("Arial Black", Font.BOLD, 15));
label_Y.setAlignment(Label.CENTER);
label_Y.setForeground(Color.BLACK);
label_Y.setBackground(Color.YELLOW);
label_Y.setBounds(0, 0, 80, 20);
panel_1.add(label_Y);
label_X = new Label(String.valueOf(SPINNER_X_STARTVALUE));
label_X.setForeground(Color.BLACK);
label_X.setFont(new Font("Arial Black", Font.BOLD, 15));
label_X.setBackground(Color.YELLOW);
label_X.setAlignment(Label.CENTER);
label_X.setBounds(85, 0, 80, 20);
panel_1.add(label_X);
CanvasGraph canvas = new CanvasGraph(5,5,CANVAS_WIDTH,CANVAS_HEIGHT);
getContentPane().add(canvas);
//getContentPane().add(drawpanel);
// getContentPane().add(canvas);
}
}
Canvas att rita rektanglar med innehåll i...
Kod: Markera allt
import java.awt.AlphaComposite;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
public class CanvasGraph extends Canvas {
private static final long serialVersionUID = 1L;
public static final int AXIS_MARGIN = 68; // totala marginalen ovan+under och vänster+höger
public static final int X_MARKERS_SPACE = 20; // antal pixlar mellan varje markör på x-axeln
public static final int Y_MARKERS_SPACE = 10; // sätter steglängden hos markörer
public static final int MARKER_LENGTH = 1; // markörernas halva längd
public static final int SCALEFACTOR_Y = 100; // y-axeln ska visa 100ggr mindre värden än dess längd i pixlar
private int canvasWidth;
private int canvasHeight;
private ImageA imgA;
private ImageB imgB;
private int rule;
private static Point2D origo;
/*
* Konstruktor. Skapar en canvas med höjd, bredd och placeras
* med offset i x- och y-led i den behållare där den ingår.
* Ritar en Canvas som buffrade bilder sedan placeras på.
*/
public CanvasGraph(int offsetX, int offsetY,int width, int height) {
canvasWidth = width;
canvasHeight = height;
//setBackground(Color.WHITE);
setBounds(offsetX, offsetY, width, height);
rule = AlphaComposite.SRC_OVER;
imgA = new ImageA(canvasWidth,canvasHeight,Color.WHITE); // skapa en buffrad bild med x-y-axel
imgB = new ImageB(canvasWidth-AXIS_MARGIN,canvasHeight-AXIS_MARGIN,Color.BLUE); // skapa en buffrad bild med plottad funktion
}
public void paint(Graphics gr) {
super.paint(gr);
Graphics2D g = (Graphics2D) gr;
g.drawImage(imgA, null, 0, 0); // rita den buffrade bilden
float alpha = 0.5f; // genomskinlighetsgrad för nästa bild
AlphaComposite comp = AlphaComposite.getInstance(rule, alpha);
g.setComposite(comp);
g.drawImage(imgB, null, (int) origo.getX(),AXIS_MARGIN/2); // rita den buffrade bilden
g.dispose();
}
public static void setOrigo(Point2D origo) {
CanvasGraph.origo = origo;
}
public static Point2D getOrigo() {
return origo;
}
}
Buffrad bild som innehåller axlar...
Kod: Markera allt
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
/*
* Skapar en buffrad bild som ligger i botten av ett lager med flera bilder.
* Bilden består av en färgad rektangel som det går att rita i.
* Denna basbild innehåller en skalad x- och y-axel.
*/
public class ImageA extends BufferedImage {
private Graphics2D g;
private Rectangle2D rek;
private int canvasWidth;
private int canvasHeight;
private int xAxisLength;
private int yAxisLength;
private int xAxisStart;
private int xAxisEnd;
private int yAxisStart;
private int yAxisEnd;
private Point2D xEnd;
private Point2D yEnd;
private Point2D origo;
private int numberOfxMarkers;
private int numberOfyMarkers;
public ImageA(int width, int height, Color color) {
super(width, height, BufferedImage.TYPE_INT_ARGB);
canvasWidth = width;
canvasHeight = height;
g = this.createGraphics();
g.setStroke(new BasicStroke(1.0f));
rek = new Rectangle2D.Double(0,0,width,height);
g.setPaint(color);
g.fill(rek);
g.draw(rek);
g.setPaint(Color.BLACK);
drawAxis();
drawMarkers();
g.dispose();
}
private void drawMarkers() {
numberOfxMarkers = xAxisLength/CanvasGraph.X_MARKERS_SPACE;
numberOfyMarkers = yAxisLength/CanvasGraph.Y_MARKERS_SPACE;
int dx = xAxisLength/numberOfxMarkers;
int dy = yAxisLength/numberOfyMarkers;
int xs = xAxisStart;
int xe = xAxisEnd;
int ys = yAxisStart;
int ye = yAxisEnd;
Font font = new Font("SansSerif", Font.PLAIN, 14);
AffineTransform affineTransform = new AffineTransform();
affineTransform.rotate(Math.toRadians(90), 0, 0);
Font rotatedFont = font.deriveFont(affineTransform);
g.setFont(rotatedFont);
for(int i=xs;i<=xe;i+=dx) { // börja rita x-markörer från origo
drawXMarker(i,i-xs);
}
font = new Font("SansSerif", Font.PLAIN, 11);
affineTransform = new AffineTransform();
affineTransform.rotate(Math.toRadians(0), 0, 0);
rotatedFont = font.deriveFont(affineTransform);
g.setFont(rotatedFont);
for(int i=ys;i>=ye;i-=dy) { // börja rita y-markörer från origo
drawYMarker(i,(ys-i)/100.0);
}
}
/*
* Ritar markörer utmed x-axeln på de positioner som anges av
* parametern xpos.
*/
private void drawXMarker(int xpos,int scaleNumber) {
String s = String.valueOf(scaleNumber);
Point xm1 = new Point(xpos,(int)origo.getY()+CanvasGraph.MARKER_LENGTH);
Point xm2 = new Point(xpos,(int)origo.getY()-CanvasGraph.MARKER_LENGTH);
Line2D.Double marker = new Line2D.Double(xm1,xm2);
g.draw(marker);
drawXScale(s,xpos-3,(int)(origo.getY()+5));
}
/*
* Ritar markörer utmed y-axeln på de positioner som anges av
* parametern ypos.
*/
private void drawYMarker(int ypos, double scaleNumber) {
String s = String.valueOf(scaleNumber);
Point ym1 = new Point((int)origo.getX()-CanvasGraph.MARKER_LENGTH,ypos);
Point ym2 = new Point((int)origo.getX()+CanvasGraph.MARKER_LENGTH,ypos);
Line2D.Double marker = new Line2D.Double(ym1,ym2);
g.draw(marker);
drawYScale(s,(int)(origo.getX()),ypos);
}
/*
* Graderar x-axeln med tal
*/
private void drawXScale(String s, int xpos, int ypos) {
g.setPaint(Color.BLUE);
g.drawString(s, xpos-1, ypos+1);
}
/*
* Graderar y-axeln med tal
*/
private void drawYScale(String s, int xpos, int ypos) {
g.setPaint(Color.RED);
g.drawString(s, xpos-20, ypos+3);
}
private void drawAxis() {
xAxisLength = canvasWidth - CanvasGraph.AXIS_MARGIN;
yAxisLength = canvasHeight- CanvasGraph.AXIS_MARGIN;
xAxisStart = canvasWidth - xAxisLength - CanvasGraph.AXIS_MARGIN/2;
yAxisEnd = canvasHeight - yAxisLength - CanvasGraph.AXIS_MARGIN/2;
yAxisStart = canvasHeight - CanvasGraph.AXIS_MARGIN/2;
xAxisEnd = xAxisLength + xAxisStart;
CanvasGraph.setOrigo(new Point(xAxisStart,yAxisStart));
origo = CanvasGraph.getOrigo();
xEnd = new Point(xAxisEnd,yAxisStart);
yEnd = new Point(xAxisStart,yAxisEnd);
Line2D.Double xAxel = new Line2D.Double(origo,xEnd);
Line2D.Double yAxel = new Line2D.Double(origo, yEnd);
g.draw(xAxel);
g.draw(yAxel);
}
}
Buffrad bild som håller den plottade kurvan...
Kod: Markera allt
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
/*
* Skapar en buffrad bild.
* Bilden består av en färgad rektangel som det går att rita i.
* Denna bild innehåller en plottad kurva.
*/
public class ImageB extends BufferedImage {
private Graphics2D g;
private Rectangle2D rek;
private Point2D origo;
public ImageB(int width, int height, Color color) {
super(width, height, BufferedImage.TYPE_INT_ARGB);
origo = CanvasGraph.getOrigo();
g = this.createGraphics();
g.setStroke(new BasicStroke(1.0f));
rek = new Rectangle2D.Double(0,0,width,height);
g.setPaint(color);
g.fill(rek);
g.draw(rek);
g.setPaint(Color.BLACK);
plotFunction(SwingWindow.A,SwingWindow.B,SwingWindow.C);
g.dispose();
}
/*
* Ritar en funktion y(x) i x-y-grafen. y(x) = a + bx + cx^2
* y = 2.31 - 0.0047*R + 1.93*10^-6*R^2
*/
private void plotFunction(double a, double b, double c) {
double x1 = 0;
double y1 = 0;
double x2 = 0;
double y2 = 0;
while(y2>=0) {
y2 = (a + b*x2 + c*Math.pow(x2, 2))*100;
g.drawLine(x(x1), y(y1), x(x2), y(y2));
x1 = x2;
y1 = y2;
x2 = x2+1;
}
}
/*
* Parametern x refererar till en x-koordinat med ett origo som har x=0 och y=0
* Returnerar den absoluta x-koordinaten i förhållande till det origo
* som ritats i canvas med de faktiska x- och y-koordinaterna.
*/
private int x(double x) {
return (int)(origo.getX()+x-CanvasGraph.AXIS_MARGIN/2);
}
/*
* Parametern y refererar till en y-koordinat med ett origo som har x=0 och y=0
* Returnerar den absoluta y-koordinaten i förhållande till det origo
* som ritats i canvas med de faktiska x- och y-koordinaterna.
*/
private int y(double y) {
return (int)(origo.getY()-y-CanvasGraph.AXIS_MARGIN/2);
}
}
En lyssnarklass för knappar fast den nyttjar jag inte till något vettigt ännu...
Kod: Markera allt
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
public class Listener extends JFrame {
private static final long serialVersionUID = 1L;
public Listener() {
}
public class Avbryt implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
public class PlotFunction implements ActionListener {
public void actionPerformed(ActionEvent e) {
// SwingWindow.getCanvas().plotFunction(SwingWindow.A,SwingWindow.B,SwingWindow.C);
}
}
public class Repaint implements ActionListener {
public void actionPerformed(ActionEvent e) {
// SwingWindow.getCanvas().repaint();
}
}
public class Render implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("RENDER");
}
}
}