Auf Thema antworten

Das würde, falls du wirklich Rechtecke zeichnen möchtest, durchaus Sinn machen. Es hat ja niemand gesagt, dass die Skala auf der Grafik auch der Skala deiner Funktion entsprechen muss - umskalieren heisst das Zauberwort, aber dass Rechtecke in diesem Zusammenhang nicht sinnvoll sind wurde ja schon gesagt.


Z.B. hochzählen in 0.1 - Schritten, * 10 und dann zu int casten. So einfach kann die Welt sein ;-)


EDIT - endlich gefunden - ich weiss nicht mehr in welchem Thread das entsanden ist, aber der Plot sieht doch gar nicht so schlecht aus :)


[code=Java]import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.GridLayout;

import java.awt.RenderingHints;


import javax.swing.JComponent;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JSpinner;

import javax.swing.SpinnerNumberModel;

import javax.swing.SwingUtilities;

import javax.swing.event.ChangeEvent;

import javax.swing.event.ChangeListener;


/**

 * Hauptklasse für SimplePlot. Enthält eine main-Methode

 * und erstellt das GUI.

 */

public class SimplePlotMain {

    /**

     * Main-Methode

     *

     * @param args Nicht benutzt

     */

    public static void main (String args[]) {

        // Erzeuge das GUI auf dem Event-Dispatch-Thread

        SwingUtilities.invokeLater(new Runnable() {

            @Override

            public void run() {

                createAndShowGUI();

            }

        });

    }


    /**

     * Erzeuge das GUI und zeige es an

     */

    private static void createAndShowGUI() {

        // Erzeuge einen JFrame

        JFrame frame = new JFrame("SimplePlot");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().setLayout(new BorderLayout());

        frame.setSize(800,600);


        // Erstelle das SimplePlotPanel und füge es zum Frame hinzu

        SimplePlotPanel plotPanel = new SimplePlotPanel();

        frame.getContentPane().add(plotPanel, BorderLayout.CENTER);


        // Erstelle eine Funktion, die geplottet werden soll

        // und weise sie dem SimplePlotPanel zum plotten zu

        Function function = new Function() {

            @Override

            public float compute(float argument) {

                return (float)Math.sin(argument)*argument;

            }

        };

        plotPanel.setFunction(function);


        // Füge ein control-panel für die Einstellungen zum Frame hinzu

        JComponent controlPanel = createControlPanel(plotPanel);

        frame.getContentPane().add(controlPanel, BorderLayout.EAST);


        // Ganz am Ende den Frame anzeigen

        frame.setVisible(true);

    }


    /**

     * Erzeugt ein control-panel mit Spinnern, mit denen man den Bereich

     * einstellen kann, der von der Funktion angezeigt werden soll

     *

     * @param plotPanel Das SimplePlotPanel, auf das die Einstellungen

     * der Spinner übertragen werden

     * @return Das control-panel

     */

    private static JComponent createControlPanel(final SimplePlotPanel plotPanel) {

        JPanel controlPanel = new JPanel(new BorderLayout());

        JPanel panel = new JPanel(new GridLayout(0,2));

        controlPanel.add(panel, BorderLayout.NORTH);


        // Erstelle Spinner für die minimalen und maximalen X- und Y-Werte

        final JSpinner minXSpinner = new JSpinner(

                new SpinnerNumberModel(-1.0, -1000.0, 1000.0, 0.1));

        final JSpinner maxXSpinner = new JSpinner(

                new SpinnerNumberModel( 1.0, -1000.0, 1000.0, 0.1));

        final JSpinner minYSpinner = new JSpinner(

                new SpinnerNumberModel(-1.0, -1000.0, 1000.0, 0.1));

        final JSpinner maxYSpinner = new JSpinner(

                new SpinnerNumberModel( 1.0, -1000.0, 1000.0, 0.1));


        // Füge die Spinner und entsprechende Labels dem Panel hinzu

        panel.add(new JLabel("minX"));

        panel.add(minXSpinner);

        panel.add(new JLabel("maxX"));

        panel.add(maxXSpinner);

        panel.add(new JLabel("minY"));

        panel.add(minYSpinner);

        panel.add(new JLabel("maxY"));

        panel.add(maxYSpinner);


        // Erstelle einen ChangeListener, der bei einer Änderung an

        // den Spinnern die Werte ans SimplePlotPanel überträgt

        ChangeListener changeListener = new ChangeListener() {

            @Override

            public void stateChanged(ChangeEvent event) {

                float minX = ((Double)minXSpinner.getValue()).floatValue();

                float maxX = ((Double)maxXSpinner.getValue()).floatValue();

                float minY = ((Double)minYSpinner.getValue()).floatValue();

                float maxY = ((Double)maxYSpinner.getValue()).floatValue();

                plotPanel.setRangeX(minX, maxX);

                plotPanel.setRangeY(minY, maxY);

            }

        };

        minXSpinner.addChangeListener(changeListener);

        maxXSpinner.addChangeListener(changeListener);

        minYSpinner.addChangeListener(changeListener);

        maxYSpinner.addChangeListener(changeListener);


        // Setze einige Default-Werte, die für die Beispielfunktion

        // hübsch aussehen...

        minXSpinner.setValue(-10.0);

        maxXSpinner.setValue( 10.0);

        minYSpinner.setValue(-10.0);

        maxYSpinner.setValue( 10.0);


        return controlPanel;

    }

}


/**

 * Interface für eine allgemeine Funktion, die einen float-Wert

 * in einen anderen float-Wert umrechnet. Solche Funktionen können

 * mit dem SimplePlotPanel geplottet werden.

 */

interface Function {

    /**

     * Berechne den Funktionswert an der angegebenen Stelle

     *

     * @param argument Die Stelle, an der die Funktion berechnet wird

     * @return Den Funktionswert an der angegebenen Stelle

     */

    float compute(float argument);

}




/**

 * Das JPanel in dem eine Funktion geplottet wird

 */

class SimplePlotPanel extends JPanel {

    private static final long serialVersionUID = -6588061082489436970L;


    /**

     * Die Funktion, die geplottet wird

     */

    private Function function;


    /**

     * Der minimale x-Wert für die Funktion

     */

    private float minX = -1.0f;


    /**

     * Der maximale x-Wert für die Funktion

     */

    private float maxX = 1.0f;


    /**

     * Der minimale Y-Wert, der angezeigt werden soll

     */

    private float minY = -1.0f;


    /**

     * Der maximale Y-Wert, der angezeigt werden soll

     */

    private float maxY = 1.0f;


    /**

     * Erstellt das SimplePlotPanel

     */

    public SimplePlotPanel() {

    }


    /**

     * Setze die Fuktion, die geplottet werden soll

     *

     * @param function Die Funktion, die geplottet werden soll

     */

    public void setFunction(Function function) {

        this.function = function;

        repaint();

    }


    /**

     * Setzt den Bereich der Funktion, der geplottet werden soll

     *

     * @param minX Der minimale X-Wert

     * @param maxX Der maximale X-Wert

     */

    public void setRangeX(float minX, float maxX) {

        this.minX = minX;

        this.maxX = maxX;

        repaint();

    }


    /**

     * Setzt den Bereich der Funktion, der geplottet werden soll

     *

     * @param minY Der minimale Y-Wert

     * @param maxY Der maximale Y-Wert

     */

    public void setRangeY(float minY, float maxY) {

        this.minY = minY;

        this.maxY = maxY;

        repaint();

    }


    /**

     * Überschriebene Methode aus JComponent: Zeichnet dieses Panel (also

     * die Funktion) in das übergebene Graphics-Objekt. 

     */

    @Override

    protected void paintComponent(Graphics gr) {

        super.paintComponent(gr);

        Graphics2D g = (Graphics2D)gr;

        g.setColor(Color.WHITE);

        g.fillRect(0,0,getWidth(),getHeight());

        g.setRenderingHint(

                RenderingHints.KEY_ANTIALIASING,

                RenderingHints.VALUE_ANTIALIAS_ON);


        paintAxes(g);

        paintFunction(g);

    }


    /**

     * Rechnet einen x-Wert für die Funktion um in eine x-Position

     * auf diesem JPanel

     *

     * @param x Der x-Wert für die Funktion

     * @return Der x-Wert auf diesem JPanel

     */

    private int toScreenX(float x) {

        float relativeX = (x-minX)/(maxX-minX);

        int screenX = (int)(getWidth() * relativeX);

        return screenX;

    }


    /**

     * Rechnet einen y-Wert der Funktion um in eine y-Position

     * auf diesem JPanel

     *

     * @param y Der y-Wert der Funktion

     * @return Der y-Wert auf diesem JPanel

     */

    private int toScreenY(float y) {

        float relativeY = (y-minY)/(maxY-minY);

        int screenY = getHeight() - 1 - (int)(getHeight() * relativeY);

        return screenY;

    }


    /**

     * Rechnet eine x-Position auf diesem Panel um in den X-Wert für

     * die Funktion, der dort liegt

     *

     * @param x Der x-Wert auf diesem JPanel

     * @return Der x-Wert für die Funktion

     */

    private float toFunctionX(int x) {

        float relativeX = (float)x/getWidth();

        float functionX = minX + relativeX * (maxX - minX);

        return functionX;

    }



    /**

     * Malt einfache Koordinatenachsen in das übergebene Graphics-Objekt

     *

     * @param g Das Graphics-Objekt zum Zeichnen

     */

    private void paintAxes(Graphics2D g) {

        int x0 = toScreenX(0);

        int y0 = toScreenY(0);

        g.setColor(Color.BLACK);

        g.drawLine(0,y0,getWidth(),y0);

        g.drawLine(x0,0,x0,getHeight());

    }


    /**

     * Zeichnet die Funktion in das übergebene Graphics-Objekt

     *

     * @param g Das Graphics-Objekt zum Zeichnen

     */

    private void paintFunction(Graphics2D g) {

        g.setColor(Color.BLUE);


        int previousScreenX = 0;

        float previouseFunctionX = toFunctionX(previousScreenX);

        float previousFunctionY = function.compute(previouseFunctionX);

        int previousScreenY = toScreenY(previousFunctionY);


        for (int screenX=1; screenX<getWidth(); screenX++) {

            float functionX = toFunctionX(screenX);

            float functionY = function.compute(functionX);

            int screenY = toScreenY(functionY);


            g.drawLine(previousScreenX, previousScreenY, screenX, screenY);

            previousScreenX = screenX;

            previousScreenY = screenY;

        }

    }

}

[/code]



Oben