# Sinusfunktion



## C.Ahrend (27. Feb 2008)

Hallo liebe Community,

ich habe in Informatik eine Hausaufgabe aufbekommen, die ich zu morgen erledigen muss.

Hier eröffnet sich nur eine Problematik, unser Lehrer hat uns nie etwas über Java erzählt und nun sollen wir ohne Grundlage seine Aufgaben erledigen.

Mir ist durchaus bewusst, dass hier niemandem die Hausaufgaben gemacht werden, das will ich auch gar nicht.

Die Aufgabe ist im Code dargestellt :


```
/* Eine noch nicht sehr schöne Art, die Sinusfunktion zu zeichnen
 * Aufgabe: 1. Schreiben Sie hinter jede noch nicht kommentierte Zeile
 *             die Funktion der dort verwendeten Befehle.
 *          2. Korrigieren Sie die Ausgabe, dass die Sinusfunktion
 *             "schön", d.h. mit gut sichtbarer Wellenform, angezeigt wird.
 *          3. Fügen Sie eine Überschrift als Text und ein
 *             Koordinatensystem ein.
 *             (Achsen mit drawLine(int x1, int y1, int x2, int y2)
 */
import java.applet.*;
import java.awt.*;

public class Funktion1 extends Applet
{
   // Gleichung für die Umrechnung von Grad- in Bogenmaß:
   // b/2*PI = alpha/360 => b = 2*alpha/360
   int x1;      // x-Koordinate des Punktes im Gradmaß von 0 bis 360 Grad
   double x2;   // x-Koordinate des Punktes im Bogenmaß von 0 bis 2*Pi
   int y;       // y-Koordinate des Punktes

   public void paint(Graphics g)
   {
        for (x1=1; x1<=360 ; x1=x1+10) {  // Schleife zur Wiederholung
           x2 = (2*x1*Math.PI/360);       // Umrechnung vom Gradmaß ins Bogenmaß
           y  = (int)(Math.sin(x2));      // Umwandlung des Ergebnisses in eine Ganzzahl
           g.drawOval(x1,y,1,1);          // Zeichnung eines Ovals
           for (int j = 0 ; j < 10000000 ; j = j+1); // Sichtbarmachen des Prozesses
        }
    }
}
```

So das ist nun also der Code den wir bekommen haben.

---

Meine Ideen bzw. Fragen :

1. Habe ich versucht die Zahlen innerhalb der for-Schleife zu ändern genauer gesagt hier :

```
for (x1=1; x1<=360 ; x1=x1+10) {  // Schleife zur Wiederholung
```
Das hat mir aber nicht wirklich weitergeholfen ...

Daraufhin kam ich auf die Idee an dieser Stelle :

```
int x1;      // x-Koordinate des Punktes im Gradmaß von 0 bis 360 Grad
   double x2;   // x-Koordinate des Punktes im Bogenmaß von 0 bis 2*Pi
   int y;       // y-Koordinate des Punktes
```
, Werte einzusetzen, doch auch das blieb ohne Erfolg ...

Mit einigen Befehlen kann ich ja auch etwas anfangen ...

Meine Frage ist nun kann/muss ich irgendwo die Werte verändern. Auch die Änderung der Oval-Zeile brachte mir keinen Erfolg ...

Nun bin ich total am Ende ...


----------



## SlaterB (27. Feb 2008)

Tipp:
1.
versuche ein Konsolenprogramm,
gib die Werte für x und y usw. zunächst mit System.out.println() aus, und schaue ob richtig gerechnet wird
(bei einem Applet evtl. nicht möglich?, in einem normalen Java-Programm auf jeden Fall)

evtl. auch erstmal auf die Schleife + Umrechnung usw verzichten und ganz banal
mit einzelnen Werten wie
double y = Math.sin(4); 
anfangen

2.
versuche erstmal einfache einzelne Punkte, Linien, Kreise in die GUI zu malen,

wenn beides klappt, dann kannst du das ganz langsam kombinieren,
aber ohne Ahnung 10 Dinge auf einmal, da wüßte ich selber kaum wo man da anfangen muss

--------

> unser Lehrer hat uns nie etwas über Java erzählt und nun sollen wir ohne Grundlage seine Aufgaben erledigen

hört man hier sowieso täglich, das bringt nix


----------



## Guest (27. Feb 2008)

Du kennst unseren Lehrer ja nicht ... wir haben 3 Blätter bekommen, nix über Befehle gelernt außer :

g.draw ...
g.fill ...

Von den Befehlen rund um Math. ... habe ich noch nie was gehört ...

Zu deinem Lösungsansatzhilfsversuch ^^, wir sollen das ja auf Grundlage dieses Codes machen ...


----------



## xerberuz (27. Feb 2008)

Hi, der Quellcode deines Lehrers ist ja unglaublich grausam. Allein wie schlecht die Pause implementiert ist.

Naja ich hab hier mal ein Beispiel wie man so eine Sinus Funktion malen könnte. Es ist bestimmt nicht perfekt aber vielleicht liefert es dir ein paar Ansatzpunkte.


```
double x;      // x-Koordinate des Punktes im Gradmaß von 0 bis 360 Grad
   double y;       // y-Koordinate des Punktes

   public void paint(Graphics g)
   {
	   Graphics2D g2 = (Graphics2D) g;
	   GeneralPath p = new GeneralPath();
	   p.moveTo(0, 0);
        for (x=0; x<=2*Math.PI ; x=x+0.1) {  
           y  = (Math.sin(x));     
           p.lineTo(x * 100, (y * 100) + 100);
        }
        
        g2.draw(p);
    }
```


----------



## 0x7F800000 (27. Feb 2008)

Mir war wohl langweilig...  :autsch:  Hier sind jedenfalls ein paar nervige nicht doppeltgepufferte  :wink: variationen zum thema Sinusfunktion: fenster bitte vergrößern, da laufen mehrere...


```
import java.applet.*;
import java.awt.*;

public class SinusApplet extends Applet{
	
	//irgendeine funktion...
	private static interface Function{
		public double calculate(double x);
	}
	
	//thread, der alles zeichnet
	private static class AnimationThread extends Thread{
		
		//so eine art "struct",
		//das die koordinaten eines Punktes in 2D speichert
		//(nur für den fall dass ihr die ganzen vorgefertigten
		//Sachen nicht anwenden dürft, eigentlich überflüssig)
		public static class Vector2D{
			public double x,y;
			public Vector2D(double _x, double _y){x=_x; y=_y;}
		}
		
		private static class ScreenCoords{
			public int pixel_x,pixel_y;
			public ScreenCoords(ScreenCoords s){pixel_x=s.pixel_x; pixel_y=s.pixel_y;}
			public ScreenCoords(int _x, int _y){pixel_x=_x; pixel_y=_y;}
		}
		
		
		//member vars
		Graphics g; //referenz zum Graphics-Objekt des Applets
		Rectangle bounds; //wo soll alles gezeichnet werden
		//ecken eines 2D-Quaders, der dargestellt werden soll:
		Vector2D minVertex, maxVertex;
		//zu zeichnende funktion
		Function f;
		
		
		public AnimationThread(Graphics _g, 
								Vector2D _minVertex,
								Vector2D _maxVertex,
								Rectangle _bounds,
								Function _f){
			g=_g;
			minVertex=_minVertex; 
			maxVertex=_maxVertex;
			bounds=_bounds;
			f=_f;
		}
		
		public void run(){
			while(true){
			
			
			//es werden öfters striche gezeichnet
			//hier screenCoords vom start und endpunkt
			ScreenCoords start,end;
			
			//clipping area ändern
			Shape originalClippingArea=g.getClip();
			g.setClip(bounds);
			
			//hintergrund löschen
			g.setColor(new Color(220,255,220));
			g.fillRect(bounds.x,bounds.y,bounds.width,bounds.height);
			
			//koordinatenachsen zeichnen
			g.setColor(Color.BLACK);
			//y-achse
			start=toScreenCoords(new Vector2D(0,minVertex.y));
			end=toScreenCoords(new Vector2D(0,maxVertex.y));
			g.drawLine(start.pixel_x, start.pixel_y, end.pixel_x, end.pixel_y);
			//x-achse
			start=toScreenCoords(new Vector2D(minVertex.x,0));
			end=toScreenCoords(new Vector2D(maxVertex.x,0));
			g.drawLine(start.pixel_x, start.pixel_y, end.pixel_x, end.pixel_y);	
			
			//pen gibt an, wo sich der "virtuelle bleistift" gerade
			//befindet, es soll ja ein zeichenvorgang dargestellt 
			//werden...
			
			for(int pen=bounds.x; pen<bounds.x+bounds.width; pen++){
				
				//graph zeichnen
				//irgendwo auserhalb des zeichenbereichs beginnen
				start=toScreenCoords(new Vector2D(minVertex.x-10, minVertex.y));
				
				//den graphen vom linken rand bis zum virtuellen stift zeichnen
				g.setColor(Color.RED);
				for(int px=bounds.x; px<pen; px++){
					end.pixel_x=px;
					//eine ziemlich verschwenderische umrechnung hier, 
					//geht sicher 1000 mal schneller,
					//hab aber keine lust viel zu tippen^^
					end.pixel_y=
					toScreenCoords(new Vector2D(0,f.calculate(toRealCoords(new ScreenCoords(px,0)).x))).pixel_y;
					g.drawLine(start.pixel_x, start.pixel_y, end.pixel_x, end.pixel_y);
					start=new ScreenCoords(end);
				}
			
				try{
					sleep(10);
				}catch(InterruptedException e){}
			}
			
			//clipping area zurücksetzen
			g.setClip(originalClippingArea);
			
			try{
				sleep(2000);
			}catch(InterruptedException e){}
			}
		}
		
		//hilfsfunktion zum umrechnen in die bildschirmkoordinaten
		private ScreenCoords toScreenCoords(Vector2D v){
			return new ScreenCoords(
					(int)(bounds.x+(v.x-minVertex.x)*bounds.width/(maxVertex.x-minVertex.x)),
					(int)(bounds.y+(v.y-minVertex.y)*bounds.height/(maxVertex.y-minVertex.y)));
		}
		
		private Vector2D toRealCoords(ScreenCoords s){
			return new Vector2D(
					minVertex.x+(s.pixel_x-bounds.x)*(maxVertex.x-minVertex.x)/bounds.width,
					minVertex.y+(s.pixel_y-bounds.y)*(maxVertex.y-minVertex.y)/bounds.height);
		}
	}//ende der Thread-definition
	
	//Applet
	public void init(){
		
		//haufen funktionen
		Function[] functions={
		new Function(){ public double calculate(double x){ return Math.sin(x); }},
		new Function(){ public double calculate(double x){ return 0.1*Math.exp(x)*Math.sin(20*x); }},
		new Function(){ public double calculate(double x){ return 0.5*Math.atan(x)*Math.sin(Math.cos(x)*x); }},
		new Function(){ public double calculate(double x){ return Math.exp(-x*x)*Math.sin(12*x); }} ,
		new Function(){ public double calculate(double x){ return Math.sin(17*x)+Math.sin(19*x); }},
		new Function(){ public double calculate(double x){ return 0.3*(Math.sin(17*x)+Math.sin(19*x)+Math.sin(13*x)); }},
		new Function(){ public double calculate(double x){ return Math.sin(17*x)*Math.sin(19*x); }},
		new Function(){ public double calculate(double x){ return Math.sin(30/x)*x; }},
		new Function(){ public double calculate(double x){ return Math.sin(30/x+0.01*x*x*x)*x*x; }},
		new Function(){ public double calculate(double x){ return Math.sin(x)+Math.sin(x*x); }},
		};
		
		for(int i=0; i<functions.length; i++){
			AnimationThread t=new AnimationThread(this.getGraphics(),
													new AnimationThread.Vector2D(-5,-2),
													new AnimationThread.Vector2D(5,2),
													new Rectangle(410*(i%2),120*(i/2),400,110),
													functions[i]);
			t.start();
		}
	}
	
}
```
bin mir nicht so sicher obs dir was hilft... wahrscheinlich eher weniger :roll:  Aber ich finds lustig den threads zuzuschauen, wie die alle unterschiedlich schnell laufen, find ich recht witzig...

Die aufgabe find ich etwas komisch gewählt für den allerersten übungszettel... :?:


----------

