# Ladekurve Kondensator



## Huggybear32 (11. Apr 2008)

Guten Tag erstmal,

Ich stehe vor folgendem Problem:

Ich möchte den Ladevorgang eines Kondensators Visualisieren.
Jedoch will mir partout nicht einfallen wie ich die Formel des Ladevorgangs:

U(t)=U*(1-exp^t/R*C)

in meiner Anwendung darstellen, bzw. in einem Koordinatensystem zeichen soll

Hier der Quelltext:


```
import java.awt.*;
import java.awt.event.*;

public class Kondensator extends Frame

{
	
	int rectWidth  = 30;
    int rectHeight = 12;
	
	private double u_min = 0; 		// Startwert für U

	private double r_start = 0;		// Startwert für den Widerstand

	private double c_start = 0;		// Startwert für die Kapazität

	private TextField tfu_min   = new TextField("");
	private TextField tfr_start = new TextField("");
	private TextField tfc_start = new TextField("");

	
	private Label lbu	= new Label("U=");
	private Label lbr	= new Label("R=");
	private Label lbc	= new Label("C=");
	private Label lbueb = new Label("Ladevorgang eines Kondensators"); // Überschrift des Programms
	private Label lblad = new Label("Ladekurve des Kondensators:");  // Überschrift des Koordinatensystems
	private Label lbrsz = new Label("R"); 	//Beschriftung Schaltplan
	private Label lbusz = new Label("U");  //Beschriftung Schaltplan
    private Label lb_meldung = new Label();

	private Button b1 = new Button("Berechne"); // Button

//------------------------------Frame Kondensator---------------------------------------------

public static void main (String args[])
	
	{
		Kondensator malik = new Kondensator();
	}
	
public Kondensator()
	
	{
	  super("Kondensator");
	  setSize(750,500);
	  setLocation(100,100);
	  setVisible(true);
	  addWindowListener(new WindowAdapter() 
      {
         public void windowClosing(WindowEvent event)
         {
            System.exit(0);
         }
      });
      setLayout(null); // Layout zuweisen	
      
//-------------------------------Bounden und----------------------------------------------

	lbu.setBounds(50,70,15,20); // Bounden der Elemente 
	lbr.setBounds(50,100,15,20);
	lbc.setBounds(50,130,15,20);
	lblad.setBounds(320,160,300,20);
	lbueb.setBounds(235,25,200,20);
	lbrsz.setBounds(90,243,40,15);
	lbusz.setBounds(20,274,20,15);
	lb_meldung.setBounds(20,450,350,20);
	
	tfu_min.setBounds(70,70,35,20);
	tfr_start.setBounds(70,100,35,20);
	tfc_start.setBounds(70,130,35,20);
	b1.setBounds(350,70,120,20);
	
	add(lbu);
	add(lbr);
	add(lbc);
	add(lblad);
	add(lbueb);
	add(lbrsz);
	add(lbusz);
	add(tfu_min);
	add(tfr_start);
	add(tfc_start);
	add(b1);
	add(lb_meldung);
	
	b1.addActionListener(new B1());

	}
//-----------------------------------Schaltplan Kondensator--------------------	
	 public void paint(Graphics g)
     {
      
       g.drawLine(50,236,100,236);					// erste Waagerechte Line
       g.drawRect(100,229, rectWidth, rectHeight);	// Widerstand
       g.drawLine(130,236,180,236);					// Linie vom Widerstand bis zur Ecke
       g.drawLine(180,236,180,283);					// Linie runter bis zum Kondi
       g.drawLine(170,283,190,283);					// Kondi oberer Balken
       g.drawLine(170,287,190,287);					// Kondi unterer Balken
       g.drawLine(180,287,180,331);					// Linie vom Kondie runter
       g.drawLine(180,331,50,331);					// Linie vom Bordstein bis zur Skyline Zurück
       g.drawLine(50,331,50,287);					// Linie von der ecke unten links bis zum Versorger
       g.drawLine(42,287,58,287);					// Linie Versorger Unten
       g.drawLine(37,280,63,280);					// Linie Versorger Oben
       g.drawLine(50,280,50,236);					// Linie vom Versorger bis Oben Ecke
       g.drawLine(39,273,45,273);					// + Horizontal Linie Versorger
       g.drawLine(42,270,42,276);					// + Verikal Linie Versorger
       g.drawLine(39,293,45,293);					// - Linie Versorger
       g.drawLine(185,273,191,273);					// + Horizontal Kondi
       g.drawLine(188,276,188,270);					// + Vertikal Kondi
       g.drawLine(185,293,191,293);					// - Linie Kondi
       
//--------------------------------Beschriftung Schaltplan----------------------
	   
	         
       
//-------------------------------Koordinatensystem-----------------------------     
       g.drawRect(320,180, rectWidth +300, rectHeight +250);
       g.drawLine(345,200,345,422);  // Konstruktion der Y-Achse
       g.drawLine(345,422,630,422);  // Konstruktion der X-Achse
       g.drawLine(630,422,624,428);  // Konstruktion der Pfeile (X-Achse)
       g.drawLine(630,422,624,416);  // Konstruktion der Pfeile (X-Achse)
       g.drawLine(345,200,339,206);  // Konstruktion der Pfeile (Y-Achse)
       g.drawLine(345,200,351,206);  // Konstruktion der Pfeile (Y-Achse)
       g.drawString("Zeitkonstante T",450,438);
       
//´----------------------Ohm-Zeichen-------------------------------------------

	   g.drawArc(110,104,10,10,310,295);    //Kreissegment zeichen
	   g.drawLine(109,114,113,114);			//Ohm Strich Links
	   g.drawLine(117,114,121,114);			//Ohm Strich Rechts
	   
//----------------------µ-Zeichen----------------------------------------------
	   g.drawString("µF",110,143);
	   
	  
//------------------------V-Buchstabe am Textfeld------------------------------

	   g.drawString("(U)V",107,83);
	  
//------------------Button mit Prüfung der Zahlen------------------------------
}
class B1 implements ActionListener  // Button mit umfangreicher Logikprüfung
   {                                   // und eigener Meldungsmethode
   	  public void actionPerformed(ActionEvent ae)
   	  {
   	  	 int nr = 0;
   	  	 lb_meldung.setText("");
   	  	 try
   	  	 {
   	  	 	u_min = Double.parseDouble(tfu_min.getText());
   	  	 }
   	  	 catch(NumberFormatException nfe)
   	  	 {
   	  	 	nr = 1;
   	  	 }
   	  	 try
   	  	 {
   	  	 	r_start = Double.parseDouble(tfr_start.getText());
   	  	 }
   	  	 catch(NumberFormatException nfe)
   	  	 {
   	  	 	nr = 2;
   	  	 }
   	  	 try
   	  	 {
   	  	 	c_start = Double.parseDouble(tfc_start.getText());
   	  	 }
   	  	 catch(NumberFormatException nfe)
   	  	 {
   	  	 	nr = 3;
   	  	 }
	 	
   	  	 if (u_min < 0) nr = 4;
   	  	 if (u_min > 50) nr = 5;
   	  	 if (r_start < 0) nr = 6;
   	  	 if (r_start > 100) nr = 7;
   	  	 if (c_start < 0) nr = 8;
   	  	 if (c_start >100) nr = 9;
   	  	 if (nr == 0)
   	  	 {
   	  	 	repaint();
   	  	 }
   	  	 else
   	  	 {
   	  	 	ausgabe(nr);
   	  	 }
   	  }
   	  public void ausgabe(int nr) // Meldungsmethode
   	  {
   	  	 if (nr == 1)
   	  	 {
   	  	 	tfu_min.requestFocus(); // Cursor auf Element positionieren!!
   	  	 	lb_meldung.setText("Also ne Vernünftige Eingabe wäre nice oO");
   	  	 }
   	  	 else if (nr == 2) 
   	  	 {
   	  	 	tfr_start.requestFocus();
   	  	 	lb_meldung.setText("Bitte in Zahlen schreiben!!");
   	  	 }
   	  	 else if (nr == 3) 
   	  	 {
   	  	 	tfc_start.requestFocus();
   	  	 	lb_meldung.setText("So kann ich nicht arbeiten...Zahl eingeben!!.");
   	  	 }
   	  	 else if (nr == 4) 
   	  	 {
   	  	 	tfu_min.requestFocus();
   	  	 	lb_meldung.setText("Die Spannung sollte schon Positiv sein ;-) ");
   	  	 }
   	  	 else if (nr == 5) 
   	  	 {
   	  	 	tfu_min.requestFocus();
   	  	 	lb_meldung.setText("Ruhig Brauner!");
   	  	 }
   	  	 else if (nr == 6) 
   	  	 {
   	  	 	tfr_start.requestFocus();
   	  	 	lb_meldung.setText("Ein negativer Widerstand? Erzähl mir mehr davon...");
   	  	 }
   	  	 else if (nr == 7) 
   	  	 {
   	  	 	tfr_start.requestFocus();
   	  	 	lb_meldung.setText("Größenwahn??");
   	  	 }
   	  	 else if (nr == 8) 
   	  	 {
   	  	 	tfc_start.requestFocus();
   	  	 	lb_meldung.setText("Also so nicht Freundchen, Positiv wenns geht!");
   	  	 }	
   	  	 else if (nr == 9)
   	  	 {
   	  	 	tfc_start.requestFocus();
   	  	 	lb_meldung.setText("Nicht so große Zahlen Bitte!");	
   	  	 }
   	  }
   }
}
```

Ich bin  für jede Hilfestellung dankbar!

Mit freundlichem Gruß,

Huggybear


----------



## Marco13 (11. Apr 2008)

Naja, es gibt sicher hunderte von hochkomplexen, ausgefeilten, mächtigen Bibliotheken um Graphen darzustellen und nett aufzubereiten. Aber wenn du sowas in seiner einfachsten Form selbst machen willst, hier ein paar Codeschnipsel als EIN möglicher Ansatz (ob er "gut" ist, sei mal außen vor gelassen)

```
interface Function
{
    float getY(float x);
}

class CapacitorFunction implements Function
{
    public float getY(float x)
    {
        berechne y mit der Formel....
    }
}


class GraphPanel
{
    ... // hier alles hin, was benötigt wird,
    ... // um das Koordinatensystem festzulegen etc.

    private Function function;

    public GraphPanel(Function f)
    {
        this.function = f;
    }

    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);
        }
    }
}
```

Noch als allgemeiner Hinweis: Du solltest das ganze feiner (in mehr Klassen) aufteilen. Die paint-Methode eines Frames zu überschreiben ist ziemlich heikel, und WIE sie überschrieben ist, ist  :autsch: .... Diese ganzen Hand-Getunten Koordinatenangaben.... Überleg' mal, ob man das nicht irgendwie günstiger aufteilen könnte (z.B.(!!!) auch sowas wie ein SchaltplanPanel extends Panel zu erstellen usw....)

Und Swing ist besser als AWT, aber das nur nebenbei...


----------



## Marco13 (11. Apr 2008)

Oh, hab's gerade mal gestartet: Das Koordinatensystem für die Kurve ist ja schon da.... Weniger aufwändig wäre es, jetzt sowas zu machen wie einen GraphPainter, der im wesentlichen die oben angedeutete paint-Methode ausführt - so, dass das Ergebnis "irgendwie" im schon gezeichneten Koordinatensystem erscheint... Das wäre "einfach", aber IMHO(!) ziemlicher Murks und sehr unflexibel... Wie gesagt: Das ganze ein bißchen aufteile wäre sicher nicht verkehrt...


----------



## Huggybear32 (13. Apr 2008)

Hmmm...naja

vielen dank erstmal...jedoch kann ich mit diesen tipps nicht viel anfangen...
brauche nur eine einfache umsetzung der ladekurve in meiner application.


Gruß,
Huggybear


----------



## Marco13 (13. Apr 2008)

"einfach" und "gut" schließen sich eben oft gegenseitig aus. Aber wenn du weitermurksen willst, hier ein Ansatz.


```
double tMin = minimale Zeit (0)
double tMax = maximale Zeit (dauer)
double uMin = Spannung am Anfang (0)
double uMax = Spannung am ende (U in der Formel)


paint: 

       g.drawLine(345,200,345,422);  // Konstruktion der Y-Achse
       g.drawLine(345,422,630,422);  // Konstruktion der X-Achse 

       ...

       for (int x=0; x<300; x++)
       {
            int x0 = x;
            int x1 = x+1;

            float t0 = ((float)x0/300) * (tMax-tMin);
            float ut0 = ... // U(t0)=U*(1-exp^t0/R*C) 

            float t1 = ((float)x1/300) * (tMax-tMin);
            float ut1 = ... // U(t1)=U*(1-exp^t1/R*C) 

            int y0 = (int)((uMax-uMin)/ut0) * 200;
            int y1 = (int)((uMax-uMin)/ut1) * 200;

            int xx0 = x0 + 345;
            int xx1 = x1 + 345;
            int yy0 = y0 + 200;
            int yy1 = y1 + 200;
              
            g.drawLine(xx0, yy0, xx1, yy1);
       }
```
Das pixelgenaue Zurechtrücken der Kurve, für das du ähnlich viel Zeit aufwenden wirst, wie für das "vernünftige" Implementieren des ganzen, überlasse ich dir. Eigentlich ist das total krampfig, aber das Programm in seiner jetzigen Struktur ist in SO vielerlei Hinsicht *schlecht*, dass es darauf auch nicht mehr ankommt.

Vermutlich sollte ich mich aus dem Thread jetzt lieber raushalten. Das schont die Nerven.... :roll:


----------



## Huggybear32 (13. Apr 2008)

vielen dank für die hilfe ;-)

werde mich jetzt ans rummurksen machen...ich weiß das die vorgehensweise recht bauernhaft ist aber das ist egal...ich muss nur die kurve darstellen und gut ist. Hast mich auf jeden fall ne gute idee nach vorne gebracht
vielen dank nochmal.


----------



## qlimax (14. Apr 2008)

na Huggy,

wie läufts mit deinem Projekt 

hoffe doch das du das noch schaffst.

gruß Micha


----------



## Huggybear32 (15. Apr 2008)

hmm naja bin an der stelle am verzweifeln


```
}
       public void funktionsplot(Graphics g)
       {
        for (int x=0; x<285; x++)
       {
            int x0 = x;
            int x1 = x+1;

            double t0 = tMin+((float)x0/285) * (tMax-tMin);
            double ut0 = u_max * (1-Math.exp(-t0/(r_start*c_start)));
           // double ut0 = u_max * Math.pow(1-e,t0/(r_start*c_start));  marco13's ansatz

            double t1 = tMin+((float)x1/285) * (tMax-tMin);
            double ut1 = u_max * (1-Math.exp(-t1/(r_start*c_start)));

            int y0 = (int)(ut0/(u_max-u_min)) * 200;
            int y1 = (int)(ut1/(u_max-u_min)) * 200;

            int xx0 = x0 + 345;
            int xx1 = x1 + 345;
            int yy0 = y0 + 200;
            int yy1 = y1 + 200;
            g.drawLine(xx0, yy0, xx1, yy1);
              
       System.out.println("t0  "+t0);
       System.out.println("ut0  "+ut0);
       System.out.println("t1  "+t1);
       System.out.println("ut1  "+ut1);    
       }
```

ahhh!!


----------



## Huggybear32 (15. Apr 2008)

wenn jemand einen vorschlag hat, dann nur zu ;-)
steh für alles offen...mir fallen keine ideen mehr ein :-(


----------



## Marco13 (16. Apr 2008)

Es ghet hier nicht um "Ideen". Das ist kein Kreativitätswettbewerb.

```
public void funktionsplot(Graphics g)
    {
        for(int x = 0; x < 300; x++)
        {
            int x0 = x;
            int x1 = x + 1;

            double t0 = ((float) x0 / 300) * (tMax - tMin);
            double ut0 = function(t0);
            int y0 = -(int) ((ut0 / u_max)  * 200);

            double t1 = ((float) x1 / 300) * (tMax - tMin);
            double ut1 = function(t1);
            int y1 = -(int) ((ut1 / u_max) * 200);

            int xx0 = x0 + 345;
            int xx1 = x1 + 345;
            int yy0 = y0 + 200 + 200;
            int yy1 = y1 + 200 + 200;
            g.drawLine(xx0, yy0, xx1, yy1);
        }
    }

    public double function(double t)
    {
        double exponent = - t / (r_start * c_start);
        double power = Math.pow(Math.E, exponent);
        double result = u_max * (1-power);
        return result;
    }
```


----------



## Huggybear32 (16. Apr 2008)

Marco mein Held...;-)

Vielen dank nochmals.


----------

