# Anzeigen eines Grapfen



## activefresh (17. Apr 2008)

Hi leute,
ich hab ne Frage und ich wäre froh wenn ihr mir helfen könnt. Ich möchte einen Graphen zeichnen und zwar für die 

Funktion f(x)= ax^5+bx^4+cx^3+dx+2+ex+f

Der Benutzer kann a,b,c,d,e,f in ein Textfeld eingeben und das Programm soll ihm dann den Graphen zeichnen.

Das Koordinatensystem hab ich schon. Nur hab ich nicht so wirklich ne ahnung wie ich das machen soll. 
Ich würde mich sehr freuen wenn mir jemand helfen könnte. Nur so ne frgae am rande könnte man die Funktion auch farbig machen???


----------



## ARadauer (17. Apr 2008)

http://members.aon.at/rainerra/krapfen.jpg jam jam jam

ich weiß nicht, obs für das konkrete problem schon eine fertige lösung gibt, abber machs einfach so wie wenn du es mit bleistifft und papier machen würdest....

du hast eine x achse, zb von 0 bis 200, du itterierst von 0 bis 200
und rechnest dir für jeden x wert den y wert aus, dann zeichnest du einfach auf ein panel die resultierenden Punkte als Linienzug...


----------



## activefresh (17. Apr 2008)

Ich muss ganz erlich gestehen, ich hab gehofft das ich vlt nen quelltext hier zusehen bekomme. Meine Java ist nicht grad das beste und ich versuche die Quelltexte durch veränderen und rumprobieren zu verstehen. Ich versteh schon wenn ihr sagt "Kein Bock für jemand die Arbeit zu machen" aber ich wäre euch sehr dankbar. Und ich kann mir irgendwie nicht vorstellen das das für ein Java pro eine so große sache ist


----------



## Niki (17. Apr 2008)

Hmmm, das wird verdammt schwer darzustellen, rechne das mal mit 20 durch (a bis f sind 0.1), da kommt ein y-Wert mit 336842 raus. Da kann man dann verdammt lang scrollen 

Was für Werte werden für a bis f z.B. eingegeben?


----------



## Marco13 (17. Apr 2008)

Den Krapfen hätte ich auch gepostet  :wink: 

Wie groß oder klein die y-Werte sind, ist egal, wenn man es passend skaliert. Abgesehen davon will man ja nicht wirklich die _Werte_ von 0 bis 200 einfügen. Vielleicht will man ja nur das Intervall [0,1] plotten - mit 200 Schritten. Und selbst wenn so große y-Werte rauskommen, dann muss man "nur" den Betragsmäßig größten y-Wert ausrechnen und dann einen Skalierungsfaktor für y wäheln, so, dass der größte Wert noch ins Fenster passt. 

Das "entscheidende" ist also, dass man unterscheidet zwischen "Fensterkoordinaten" (in Pixeln), und "Weltkoordinaten" (die x- und y-Werte für die Funktion).

Ganz grob skizziert hatte ich das kürzlich erst in http://www.java-forum.org/de/viewtopic.php?t=67536&highlight=kondensator

```
public void paint(Graphics g)
    {
        for (int x =...)
        {
            // Berechne (abhängig vom aktuellen Koordinatensystem) den x-Wert, der
            // Zur aktuellen x-Fensterkoordinate passt
            float fx0 = valueFor(x);
            float fx1 = valueFor(x+1);
            float fy0 = function.getY(fx0);
            float fy1 = function.getY(fx1);

            // Berechne aus dem y-Wert die y-Fensterkoordinate
            int y0 = coordinateFor(fy0);
            int y1 = coordinateFor(fy1);
             
            // Liniensegmente Zeichnen
           g.drawLine(x, y0, x+1, y1);
        }
    }
```
aber das ist natürlich nur GANZ grob angedeutet - diese magischen Methoden "valueFor" und "coordinateFor" müßten eben genau die Umrechnung zwischen den Koordinatensystemen machen (und das ganze nicht unbedingt in der paint-Methode :roll: )


----------



## activefresh (17. Apr 2008)

bitte nicht hauen aber ich sehe nicht wo ich eine funktion benutzen. Muss ich nicht irgendwo mein f(x) aufrechnen. Quasi ne Werte Tabelle oder so? Warscheinlich mit na Schleife. Aber müsste man dann nicht nen Wertebereich abstecken??


----------



## Niki (17. Apr 2008)

Soda, das war ja mal ne nette Aufgabe für einen Donnerstag Vormittag:

```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class JFGraph extends JFrame {

	private JTextField tfA = null;
	private JTextField tfB = null;
	private JTextField tfC = null;
	private JTextField tfD = null;
	private JTextField tfE = null;
	private JTextField tfF = null;

	public JFGraph() {
		super("Graph");

		guiInit();
		pack();
		setLocationRelativeTo(null);
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
	}

	private void guiInit() {
		getContentPane().setLayout(new BorderLayout());

		JScrollPane scroller = new JScrollPane();

		final GraphPanel gp = new GraphPanel();

		gp.setBackground(Color.WHITE);

		scroller.getViewport().add(gp);

		getContentPane().add(scroller, BorderLayout.CENTER);

		tfA = new JTextField();
		tfB = new JTextField();
		tfC = new JTextField();
		tfD = new JTextField();
		tfE = new JTextField();
		tfF = new JTextField();

		JPanel jpTF = new JPanel();
		GridLayout gl = new GridLayout(6, 2);
		jpTF.setLayout(gl);
		jpTF.add(new JLabel("a:"));
		jpTF.add(tfA);
		jpTF.add(new JLabel("b:"));
		jpTF.add(tfB);
		jpTF.add(new JLabel("c:"));
		jpTF.add(tfC);
		jpTF.add(new JLabel("d"));
		jpTF.add(tfD);
		jpTF.add(new JLabel("e:"));
		jpTF.add(tfE);
		jpTF.add(new JLabel("f:"));
		jpTF.add(tfF);

		tfA.setText("0.00001");
		tfB.setText("0.001");
		tfC.setText("0.001");
		tfD.setText("0.001");
		tfE.setText("0.001");
		tfF.setText("0.001");

		getContentPane().add(jpTF, BorderLayout.NORTH);

		JButton jbAnzeigen = new JButton("Anzeigen");
		jbAnzeigen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				try {
					double a = Double.parseDouble(tfA.getText());
					double b = Double.parseDouble(tfB.getText());
					double c = Double.parseDouble(tfC.getText());
					double d = Double.parseDouble(tfD.getText());
					double e = Double.parseDouble(tfE.getText());
					double f = Double.parseDouble(tfF.getText());

					double[][] xy = new double[gp.getWidth() - 10][2];
					for (int i = 0; i < xy.length; i++) {
						xy[i][0] = i;
						xy[i][1] = function(a, b, c, d, e, f, i);
					}

					int w = (int) xy[xy.length - 1][0];
					int h = (int) xy[xy.length - 1][1];
					Dimension dim = new Dimension(w + 10, h + 10);
					gp.setPreferredSize(dim);
					gp.setMinimumSize(dim);
					gp.setMaximumSize(dim);

					gp.setXY(xy);
				} catch (NumberFormatException ex) {
					ex.printStackTrace();
					JOptionPane
							.showMessageDialog(
									JFGraph.this,
									ex.getMessage() != null
											&& ex.getMessage().length() > 0 ? ex
											.getMessage()
											: "Es ist ein Fehler aufgetreten\nSiehe mehr in der Konsole",
									"Fehler", JOptionPane.ERROR_MESSAGE);
				}
			}
		});

		getContentPane().add(jbAnzeigen, BorderLayout.SOUTH);

	}

	public static void main(String[] args) {
		new JFGraph().setVisible(true);

	}

	private class GraphPanel extends JPanel {

		private double[][] xy = null;

		private GraphPanel() {

		}

		public void setXY(double[][] xy) {
			this.xy = xy;

			revalidate();
			repaint();
		}

		@Override
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);

			if (this.xy == null)
				return;

			int w = getWidth();
			int h = getHeight();

			g.drawLine(5, h - 5, w - 5, h - 5);
			g.drawLine(5, h - 5, 5, 5);

			g.setColor(Color.RED);

			int originX = 5;
			int originY = getHeight() - 5;

			int[][] xy = new int[this.xy.length][2];

			for (int i = 0; i < xy.length; i++) {
				xy[i] = fromOrigin(originX, originY, this.xy[i][0],
						this.xy[i][1]);
			}

			Point p = new Point(xy[0][0], xy[0][1]);
			for (int i = 1; i < xy.length; i++) {
				Point _p = new Point(xy[i][0], xy[i][1]);
				g.drawLine(p.x, p.y, _p.x, _p.y);
				p = _p;
			}
		}

		private int[] fromOrigin(int originX, int originY, double x, double y) {

			int _x = (int) (originX + x);
			int _y = (int) (originY - y);

			return new int[] { _x, _y };

		}
	}

	public static double function(double a, double b, double c, double d,
			double e, double f, double x) {
		double y = 0;

		y = a * (Math.pow(x, 5));
		y += b * (Math.pow(x, 4));
		y += c * (Math.pow(x, 3));
		y += d * (Math.pow(x, 2));
		y += e * x;
		y += f;

		return y;
	}
}
```


----------



## activefresh (17. Apr 2008)

Hui und das mal eben aus dem Handgelenk. Vielen Dank für eine Mühe. Aber leider kann ich damit nicht so viel mit anfangen. Ich wollte eigentlich die Funktion f(x)=ax^5+bx^4+cx+3+dx+2+ex+f als Graph dagestellt haben. Also a-f werden vom benutzer eingegeben und dann sollen für x z.B. die werte -10 bis 10 in 0,001 Schritten und immer ein Punkt da gesetzt wird weil viele Punkte ganz na bei sammen ist doch auch eine Linie.


----------



## Niki (17. Apr 2008)

Schade dass es dir nichts bringt, ich hab mir soviel Mühe gegeben 

Vielleicht kannst du es ja ändern so wie du es brauchst. Ich mach nichts anderes als für jeden Punkt auf der x-Achse ein y zu berechnen und die Punkte miteinander zu verbinden.


----------



## activefresh (17. Apr 2008)

also bei mir das das Programm nicht gezeichnet. Ich hatte nur a bis f mit textfeldern


----------



## Marco13 (17. Apr 2008)

_Aber leider kann ich damit nicht so viel mit anfangen. _
Warum? :
_Ich wollte eigentlich die Funktion f(x)=ax^5+bx^4+cx+3+dx+2+ex+f als Graph dagestellt haben. Also a-f werden vom benutzer eingegeben ..._
Bis hierhin passt's nämlich noch, und...
_und dann sollen für x z.B. die werte -10 bis 10 in 0,001 Schritten und immer ein Punkt da gesetzt wird weil viele Punkte ganz na bei sammen ist doch auch eine Linie._
...DAS solltest du sowieso bleiben lassen. Abgesehen davon, dass dort die Funktion 20000 Mal ausgewertet werden muss, obwohl der Bildschirm nur 200 Pixel breit ist, ist "eine Linie" eben doch was anderes als "viele nebeneinander liegende Punkte". Eine Linie ist eher "*unendlich* viele nebeneinander liegende Punkte", d.h. wenn du nur Punkte setzen würdest, würde deine Linie an einigen stellen "fett" aussehen, und an anderen wäre sie vielleicht unterbrochen oder krisselig. Das einzige, was du noch machen musst, um das Intervall abzubilden, ist, die passenden x-Werte zu verwenden. Du änderst dazu einfach das hier

```
for (int i = 0; i < xy.length; i++) {
                  xy[i][0] = i;
                  xy[i][1] = function(a, b, c, d, e, f, i);
               }
```
in sowas wie

```
double x0 = -10.0;
               double x1 = 10.0;
               double dx = x1-x0;
               double stepX = dx / xy.length;

               for (int i = 0; i < xy.length; i++) 
               {
                  double x = x0 + i * stepX;
                  xy[i][0] = x;
                  xy[i][1] = function(a, b, c, d, e, f, x);
               }
```


----------



## activefresh (17. Apr 2008)

also wie schon gesagt ich kann Zahlen in die Textfelder eingeben aber wenn ich den Button drücke passiert nix


----------



## Niki (17. Apr 2008)

Vergrößer mal das Fenser, zwischen dem Button und den TextFeldern ist der Graph


----------



## activefresh (17. Apr 2008)

ahhhhh jetzt macht es sinn. Vielen Dank super Programm. Hilft mir echt weiter :applaus:  :applaus:  :applaus:


----------

