Java Kreis zeichnen

XHotSniperX

Lt. Junior Grade
Registriert
Jan. 2008
Beiträge
474
Hallo

Ich muss einen vollen Kreis zeichnen mit Java: Anhang Aufgabe

Ich habe bis jetzt das hier gemacht (siehe ab "Add your code here"):

Code:
package Praxis;

import Praxis.ch.unibas.informatik.cs101.ImageWindow;

public class Kreis {

  public static void main(String args[]) {
    //creates a new instance of the ImageWindow Class
    //with a viewable image area of 500x500 pixels
    ImageWindow w = new ImageWindow(500,500);

    //opens the corresponding window (makes it visible)
    w.openWindow();

    //colors the pixel at position 255,100 in the image
    //with the rgb color 254 (red), 0 (green), 0 (blue)


    // Add your code here
    
    
    final int r = 100;
    
    for (int x = 0; x < 500; x++) {
    	for (int y = 0; y < 500; y++) {

    		if (r*r == x*x + y*y)

    			w.setPixel(x, y, 0, 0, 0);		
    		
    		
    	}	
    }		
    

    //redraws the image on the screen so all changes
    //become visible
    w.redraw();
  }
}

Das Ergebnis ist noch kein voller Kreis: siehe Anhang Ergebnis


Ich weiss jetzt nicht ganz, wie ich das machen soll, damit alle Pixel im Kreis und der Rand des Kreises mit Schwarz gezeichnet werden sollen. Habt ihr Ideen?

Vielen Dank im Vorraus!
 

Anhänge

  • aufgabe.jpg
    aufgabe.jpg
    56,1 KB · Aufrufe: 581
  • ergebnis.jpg
    ergebnis.jpg
    18,6 KB · Aufrufe: 689
Zuletzt bearbeitet:
Du vergisst, dass auch Zwischenwerte gültig sein müssen, nicht nur ganze Zahlen. Das heisst für dich, dass du mit Fließkommazahlen (float, besser: double) rechnen musst.

Am besten stellst du die Kreisgleichung nach x um und berechnest nur ein Viertel des Kreises (die Werte mit positivem x und positivem y). Dabei erhälst du Kommazahlen. Runde dann auf ganze Pixel und setze den Punkt. Damit erhälst du schonmal den Rand. Wenn du statt einzelne Punkte zu setzen eine Linie ziehst, füllst du den Kreis.

Die anderen drei Viertel des Kreises kannst du mit den selben Rechenergebnissen setzten, indem du die Vorzeichen der Werte beim Malen änderst.
 
Danke. Ich habe auch schon an float gedacht und habe es jetzt mal versucht mit folgendem Code:

Code:
package Praxis;

import Praxis.ch.unibas.informatik.cs101.ImageWindow;

public class Kreis {

  public static void main(String args[]) {
    //creates a new instance of the ImageWindow Class
    //with a viewable image area of 500x500 pixels
    ImageWindow w = new ImageWindow(500,500);

    //opens the corresponding window (makes it visible)
    w.openWindow();

    //colors the pixel at position 255,100 in the image
    //with the rgb color 254 (red), 0 (green), 0 (blue)


    // Add your code here
    
    
    final double r = 100;
    
    for (double x = 0; x < 500; x++) {
    	for (double y = 0; y < 500; y++) {
			
    		int a = 0;
			int b = 0;
    		
    		if (x == Math.sqrt(r*r - y*y))
    			
    			a = (int)x;
    			b = (int)y;
    			w.setPixel(a, b, 0, 0, 0);		
    		
    		
    	}	
    }		
    

    //redraws the image on the screen so all changes
    //become visible
    w.redraw();
  }
}

Es kommt leider das gleiche Bild raus, ausser ganz links ist ein senkrechter, dünner Steifen zu sehen. Wie kann das sein?
 
Zuletzt bearbeitet:
Du gehst das etwas verkehrt an. Du brauchst nur eine Schleife:
Code:
int x, y;

for (x = 0; x <= r; x++) {
  double b = Math.abs(Math.sqrt(r*r - x*x));
  y = (int) Math.round(b);
  w.setPixel(x, y, 0, 0, 0);
  // Hier noch die anderen drei Viertel des Kreises durch Vorzeichen-Änderung
}
 
Netter Ansatz Cobinja, aber mit füllen wirds dann schwer.

Mein Vorschlag:
Code:
int r = 100;
for (int x = 0; x < 500; x++) {
  for (int y = 0; y < 500; y++) {
    if (r * r > x * x + y * y)
      w.setPixel(x, y, 0, 0, 0);
  }
}

Ganzer gefüllter Kreis zentriert ist damit durch ein paar kleinere Änderungen auch problemlos möglich.
 
Ahhh so meinste das.. quasi jedem x ein y berechnen und das dann als int speichern und zeichnen. alles klar

aber irgendwie wird dann mein kreisrand nicht vollständig durchgezogen
Ergänzung ()

lynxx schrieb:
Netter Ansatz Cobinja, aber mit füllen wirds dann schwer.

Mein Vorschlag:
Code:
int r = 100;
for (int x = 0; x < 500; x++) {
  for (int y = 0; y < 500; y++) {
    if (r * r > x * x + y * y)
      w.setPixel(x, y, 0, 0, 0);
  }
}

Ganzer gefüllter Kreis zentriert ist damit durch ein paar kleinere Änderungen auch problemlos möglich.

Hey danke euch beiden.. so hat es super geklappt :) Das war fast mein Code am Anfang ausser, dass du ">" statt "==" verwendet hast. man man man wie komm ich denn nicht selbst drauf xD

Danke euch beiden!
 

Anhänge

  • Unbenannt.png
    Unbenannt.png
    25,6 KB · Aufrufe: 515
Zuletzt bearbeitet:
Tüftelst Du noch ? Ist nicht so schwer .. :D Falls Du selbst nicht drauf kommst ..
Code:
int r = 100;
for (int x = -250; x < 250; x++) {
  for (int y = -250; y < 250; y++) {
    if (r * r > x * x + y * y)
      w.setPixel(x + 250, y + 250, 0, 0, 0);
  }
}
 
Zuletzt bearbeitet:
hehe danke, du hast mich irgendwie gehört hab ich das gefühl :)

hatte das mit -250 nicht probiert xD

Bin halt noch ganz neu in der Programmierwelt :):)
 
lynxx schrieb:
aber mit füllen wirds dann schwer.
Wirklich?
Code:
int x, y;

for (x = 0; x <= r; x++) {
  double b = Math.abs(Math.sqrt(r*r - x*x));
  y = (int) Math.round(b);
  for (int i = 0; i <= y; i++)
    w.setPixel(x, i, 0, 0, 0);
  // Hier noch die anderen drei Viertel des Kreises durch Vorzeichen-Änderung
}

Für Zeichnen in der Bildmitte einfach beim Zeichnen um 250 Pixel verschieben
 
XHotSniperX schrieb:
Bin halt noch ganz neu in der Programmierwelt :):)
Oh, ich dachte Du bist beim ETH Zurich, Department of Computer Science .. weil Du C# Primes mit Paralleler Programmierung für Performance gepostest hast ...

Da solltest Du erstmal eine serielle Abarbeitung schreiben, parallelisieren geht recht einfach mit ThreadPool, Hier ein Code-Snippet dazu.

Cobinja schrieb:

Ja ok, Deine Lösung ist schneller, dafür zeigt meine besser welche Bedingung im innern der Kreises gilt und das war ja auch Teil der Aufgabe. :p

Code:
int r = 100;
for (int x = -r; x < r; x++) {
 int y = (int)Math.Round(Math.Sqrt(r * r - x * x));
 for (int i = -y; i < y; i++)
  w.setPixel(x + 250, i + 250, 0, 0, 0);
}
 
Hehe jaja da hast du schon Recht mit der ETH aber das war im März dieses Jahres...

Paar Monate im Programmieren ist nichts... :) Da hatte ich noch nicht mal mit Java angefangen
 
also die zwei verschachtelten for schleifen mit jeweils 500 durchgängen sind ganz ganz arg böse^^ versuch das ganze mal mit rekursion und dreiecken, so macht man das eigentlich...
 
Zurück
Oben