Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Projektaufgabe: Ikosaeder zeichnen

Empfohlene Antworten

Veröffentlicht

Hallo!

Ich soll folgende Aufgabe lösen und habe keine Schimmer, wie ich das angehen soll:

"Ikosaeder in Java zeichnen. Alle 20 Seitenflächen bekommen eine Nummer drauf. Ein Käfer soll über alle Flächen reisen(aber nur einmal!) Jede Fläche soll Startfläche sein können. Auf jeder Fläche macht der Käfer eine Pause. Länge der Pausen errechnet sich durch Schrittnummer des Käfers multipliziert mit der Zahl der gerade betretenen Seitenfläche. Wechsel von Seitenfläche zu Seitenfläche dauert 1 Sekunde. Das Betreten der Startfläche ist der erste Schritt."

Aufgabe:

System von Klassen erzeugen, welches ein Ikosaeder in geeigneter Form zeichnet und verwaltet und die Reiseroute des Käfers für die günstigste schnellste Route ausgibt.

-----------------------------------------------------------------------

Kann mir da bitte jemand helfen? Ich habe keine Ahnung, wie ich das bewerkstelligen soll, da ich auch in Java noch nicht ganz so fit bin.

Der Käfer soll nur über benachbarte Seitenflächen laufen können. Zwei Seitenflächen sind dann benachbart, wenn sie eine gemeinsame Kante besitzen.

Ich habs mal aufgemalt, wie das dann dargestellt werden soll:

Bild.JPG

*grübel* Da ich mit Java und Grafik noch nicht wirklich was gemacht habe, ist es mir ein Rätsel, wie ich da mit Objekten rumhandle und ganz allgemein mein UML-Diagramm überhaupt aussehen soll, da ich noch nicht mal weiß, was ich alles brauche :-(

Kann mir da bitte jemand helfen? Ich habe keine Ahnung, wie ich das bewerkstelligen soll, da ich auch in Java noch nicht ganz so fit bin.
Dann lass dochmal deinen Ansatz sehen und erzähle uns wo genau du noch Hilfe brauchst.
ist es mir ein Rätsel, wie ich da mit Objekten rumhandle und ganz allgemein mein UML-Diagramm überhaupt aussehen soll, da ich noch nicht mal weiß, was ich alles brauche :-(

Genau da mußt Du anfangen. Bevor Du überhaupt über eine Visualisierung mit Java nachdenken kannst, solltest Du Dir erst mal über den Algorithmus klar werden. Danach folgt die Konzeptionierung und dann die Realisierung.

Die Aufgabe ist nicht beneidenswert. Ich wüßt' noch keinen Ansatz...

*indiegrübeleckewatschel*

hm... ok ich erzähl mal, was ich mir so für gedanken gemacht habe:

Hauptprog.class (hier wird alles gestartet)

Draw.class (macht mir ein Frame auf und malt ein Ikosaeder auf siehe oben)

Calc.class (berechnet Routen für den Käfer über eine Art Backtracking)

*grml* ich ärger mich gerade, dass ich in java kaum einen Plan habe...

ich weiß echt nicht, wie ich an das Problem grundsätzlich herangehen soll...

Vielleicht könnte man sich diese Form zunutze machen:

sind ja 20 Dreiecke:

Mond_Ikosaeder.jpg

Daran sieht man genau, welches Dreieck welche Nachbarn haben.

Also irgendwie ein System von Dreiecken erzeugen, welche wie oben gemalt werden. Welche Nummer die mal habensollen, ist ja erstmal wurscht.

Da hab ich meine Objekte, mit Eckpunkten und Kanten, über die ich Nachbarschaftsbeziehungen herausfinden könnte.

Das wäre so jetzt mein Ansatz für die Aufgabe.

Nun meine Frage, wie kann ich das mit den Objekten realisieren und zeichnen lassen?

*grml* ich ärger mich gerade, dass ich in java kaum einen Plan habe...

ich weiß echt nicht, wie ich an das Problem grundsätzlich herangehen soll...

Du solltest das ganze erstmal trennen. Schritt 1 ist dir zu überlegen was du für Strukturen brauchst und wie du generell die Daten zeichnen lassen willst. Schritt 2 ist dann das wie also die Implementierung in Java - und da wirst du nicht drumrum kommen, dich mit der Sprache näher zu beschäftigen. Und ohne dich demotivieren zu wollen: Sowas geht nicht von heute auf morgen.

Hallöle,

erstmal zum Verständnis und als Anhaltpunkt dieser Link , damit Du schonmal ein paar Eigenschaften dieses Körpers kennst.

Teilprobleme:

- Das Zeichnen an sich

- Konstruktion eines Ikosaeders: hier

- Erzeugung eines Käfers

- Berechnen einer kürzesten Route über alle Seitenflächen

Ich bin nicht der wirklich starke Entwickler, aber ich denke diese Teilzerlegung trifft es grob.

Du wirst Dich mit Möglichkeiten zur Erzeugung von Grafiken in Java auseinandersetzen müssen. Wenn Du schonmal eine Idee davon hast, wie man 2-Dimensionale Figuren erzeugt, wäre es schon ein Anfang.

Ich denke die Konstruktion eines Isokaeders ist an sich schon recht komplex.

Der Algorhithmus für die Berechnung einer kürzesten Route ist mit Sicherheit auch nicht trivial. Ich vermute, dass Du intern auch allen Kanten einen Namen geben solltest, damit Du weißt aus welchen Kanten eine Seitenfläche besteht (Zuordnung Seitenfläche-Kanten Speichern in Vector o.ä.). Wie ein Vorredner schon gesagt hat, kannst Du dann über Seitenflächen, die eine gemeinsame Kante haben feststellen, wer Nachbar ist.

Das Problem des kürzesten Weges erinnert mich vom Problem her an "Travelling Salesman", wobei ich mich da auch täuschen kann :-)

Es kann auch sein, dass Du mit Sortier-Algorhithmen zum Ziel kommst, Da Du ja auf jeden Fall eine begrenzte Anzahl von Möglichkeiten hast (Jede Fläche hat 3 Nachbarn: also bei der ersten Auswahl 3 Möglichkeiten einen Weg zu gehen, danach nur noch immer 2, da der Vorgänger schon beschritten wurde. Beim letzen Schritt nur noch eine, da die anderen Nachbarn schon beschritten wurden. Ergibt eine obere Grenze von 3+2^18+1. Korrigiert mich, wenn ich falsch liege :-) ).

Vielleicht hilft Dir das schonmal weiter.

Grüße

Danke soweit erstmal, ich denke ich habe jetzt genügend ansätze.

ich mach das jetzt so:

Class Dreieck: Erzeugt ein Dreieck(int Nr, double coord 1x, coord1y, coord2x, coord2y, coord3x, coord3y)

Class Ikosaeder: Enthält ein TreeSet mit 20 Dreiecken

Class Draw: Zieht sich über versch. getMethoden die Koordinaten der Dreiecke im Treeset des Ikosaeders und malt die hin

Class Calc: keine Ahnung, hab ich noch nicht weiter nachgedacht :D

Nochmal zum Algorhithmus: Ich versuche es anhand dieses Bildes zu erklären:

Ideal wäre es ja, wenn Du jede Seitenfläche nur einmal betrittst. Damit müsstest Du schon nah am Optimum sein (wenn es das nicht sogar ist).

Wenn Du eine Startfläche hast, dann könntest Du so anfangen, dass Du um einen Punkt dieses Dreiecks alle Seitenflächen abläufst. Somit hast Du eine dieser 5-seitigen Pyramiden abgelaufen. Danach musst Du den gesamten Mittelteil ablaufen, was in der Zeichnung weiss ist. Zum Schluß kannst Du auf die 2. 5-seitige Pyramide springen und die ablaufen. Somit hast Du alle Flächen nur einmal betreten und es könnte eine kürzeste Route sein.

Der mathematische Ansatz zur Berechnung eines Minimums liegt sicherlich im Operations Research in der Graphentheorie, wo es um kürzeste Wege geht.

Vielleicht hilft Dir das weiter ;)

zur Java Umsetzung kann ich dir zwar nicht behilflich sein, aber vielleicht mal nen anstoss wegen dem Weg.

Es ist doch:

Bester Weg = kürzeste Zeit für den Weg

Zeit = 1 * Feld1 + 1 + 2 * Feld2 + 1 + 3 * Feld3 + ... + 1 + 20 * Feld20

Feldx = Ziffer auf dem Feld das als xtes betreten wurde.

Also währe doch der Geschickteste Weg:

20 19 18 17 16 15 ... 2 1

Da dies nicht immer geht Ist es doch aber anzustreben das das Feld mit der 1 immer der Zielpunkt ist, also das 20te betretene Feld. Damit verweilt er hier 20s. Und von dort aus das Feld mti der kleinsten Nummer als Nachbarn suchen.

Idee??

Wie kann ich Dreiecke zeichnen lassen?

ich habejetzt eine Ikosaeder.class in der ein TreeSet gefüllt mit Objects des Typs Dreieck ist, deren Koordinaten ich über die Methoden

dreieck.getCoord1x();

dreieck.getCoord1y();

für den 1. Punkt bekomme. für 2. und dritten Punkt einfahc die 1 gegen 2/3 ersetzen.

Wie schreibe ich jetzt eine Draw.class, die mir z.b. das so hier zeichnet:

Draw zeichne = new Draw();

zeichne.drawtriangle(Dreieck);

Ergebnis:

Gleichschenkliges_spitzwinkliges_Dreieck.png:D

Ich habe schon das hier:

import java.awt.*;

import java.awt.event.*;

public class Draw extends Frame {

public Draw() {

super("Ikosaeder");

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent evt) { System.exit(0); } });

int frameWidth = 1024;

int frameHeight = 768;

setSize(frameWidth, frameHeight);

setLayout(new BorderLayout());

setVisible(true);

}

public void paint( Graphics g )

{

g.drawLine( 50,50, 100,100);

}

public static void main(String[] args) {

Draw ExeLevel = new Draw();

}

}

Am besten beschäftigst Du Dich mit einem Tutorial ein wenig damit. Im Groben: Du hast eine Zeichenfläche vom Typ Canvas und kannst Dir über CanvasObj.getGraphics den Grafikkontext besorgen und auf diesem dann zeichnen.

Ich raff das einfach net mit der Paint-Methode. Die soll ich nun irgendwie überschreiben, aber ich find auch kein richtiges Tutorial wo mir mal das erklärt wird, was ich eigentlich machen will.

soll so aussehen:

main{

paint(Dreieck);

}

public void paint(Dreieck d){

getcoordsvomDreieck;

drawpolygon(koordinaten);

}

was muss ich denn nun tun, damit das so geht?

geht das überhaupt so?

hilfe?! :confused:

Wie wäre es wenn du in deiner Dreieckklasse eine paint-Methode implementierst, und dieser das Graphics-Objekt mitgibst?

etwa in der Art:


class Dreieck() {

private Point koord1;
private Point koord2;
private Point koord3;

// Konstruktor spar ich mir hier

public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.drawLine(koord1.getX(), koord1.getY(),koord2.getX(), koord2.getY();
g.drawLine(koord2.getX(), koord2.getY(),koord3.getX(), koord3.getY();
g.drawLine(koord1.getX(), koord1.getY(),koord3.getX(), koord3.getY();
}
}
[/PHP]

Ich weiß jetzt nicht, ob die Methodenaufrufe so stimmen... aber man könnte es auch über die drawPolygon-Methode machen.

Und in der paint-Methode in der Starterklasse rufst du einfach in einer Schleife alle Dreiecke des Ikosaeders mit dem Graphics-Objekt auf.

Das ganze geht sicher auch besser. Ist mir nur eben spontan eingefallen, wie ich es erst mal lösen würde.

gruss

markus

Er zeichnet mir das jetzt erstmal (auch wenn die Koordinaten nicht so ganz hinhauen, aber das ist erstmal egal)

ABER: wie bekomme ich das hin, dass die Paint-mehtode weiß, dass sie das Set vom Ikosaeder nehmen soll, um sich die Koordinaten zu holen?

in der main rufe ich auf:

Ikosaeder Iko = new Ikosaeder(150);

Draw fenster = new Draw(Iko);

mein quelltext der draw.class:

public Draw(Ikosaeder Iko){

// Frame-Initialisierung

super("Ikosaeder - Aufgabe");

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent evt) { System.exit(0); } });

int frameWidth = 1024;

int frameHeight = 768;

setSize(frameWidth, frameHeight);

setLayout(new BorderLayout());

setVisible(true);

}

public void paint(Graphics g){

Ikosaeder Iko = new Ikosaeder(150);

Iterator it=Iko.getDreieckSet().iterator();

//soll ja hier nicht stehen

// will das am liebsten so

//aufrufen: public void paint(Graphics g, Ikosaeder Iko){...}

//dann malt ers aber nicht mehr :-(

//er malt ja jetzt nur im quelltext festgelegt 150er Ikosaeder

//soll aber die werte aus der main nehmen

//wie bringe ich das der paint-methode bei?

while (it.hasNext()){

Dreieck d = (Dreieck)it.next();

d.draw(g);

}

//er malt ja jetzt nur im quelltext festgelegt 150er Ikosaeder

//soll aber die werte aus der main nehmen

//wie bringe ich das der paint-methode bei?

Ich verstehe die Frage nicht wirklich. Bzw. ich sehe nicht wirklich wo dein Problem liegt.

Wenn ich dich recht verstehe, willst du die Art des Ikosaeders nicht fest kodieren, sondern es soll über die Kommandozeile, bzw. sogar über ein Optionsfenster mitgegeben werden?

Aber wo liegt dann dein Problem?


public class MAIN {
public static void main(String[] args) {
Ikosaeder iko = new Ikosaeder(args[0]);
Draw dr = new Draw();
iko.paint(dr.getGraphics);
dr.show();
}
}

class Ikosaeder {
// hier das Array der Dreiecke erzeugen etc...
// des weiteren eine paint-Methode, die über das Array läuft
}

class Dreieck {
// hier eine paint-methode die das Dreieck auf dein Zeichenfläche zeichnet, die du aus dem Draw-Objekt erhältst
}
[/PHP]

Meintest du es so?

jaaaaaaaaaaaa, danke. das mit dem getGraphics musste man erstmal kapieren, ich wusste vorher immer nicht, wo dieses blöde Graphics g herkommt

Huhu,

kann mir bitte mal jemand beim coden helfen, ich komm noch nicht so ganz klar, das ganze Problem der Wegfindung rekursiv(denn so sollen wirs machen) zu lösen.

Ich habe bislang das hier:

public class Calculate{

private Weg aktWeg = new Weg();

private Weg optWeg = new Weg();

private int laenge;

/**

* rekursive Methode zur Wegbestimmung

*/

public void berechne(Ikosaeder Iko, Dreieck d){

aktWeg.addWegpunkt(d); //Wegpunkt addieren

laenge=laenge+1; //Weglänge erhöhen

ArrayList Nachbarn = new ArrayList(); //Nachbarn initialisieren

Nachbarn.add(Iko.getDreieckn(d.getNachbar1()));

Nachbarn.add(Iko.getDreieckn(d.getNachbar2()));

Nachbarn.add(Iko.getDreieckn(d.getNachbar3()));

for(int i=1;i<=3;i++){

if(laenge<3){

berechne(Iko, (Dreieck)Nachbarn.get(0));

Nachbarn.remove(0);

laenge=laenge-1;

}

}

//if(aktWeg.getLaenge()

}

}

Geht leider nicht, weil ich nicht mehr durchblicke... :confused:

Erklärung: die Methode bekommt einen Ikosaeder und ein Startdreieck übergeben. Danach werden vom Dreieck die Nachbarn bestimmt.(sind auch dreiecke). Danach soll die gleiche Methode wieder aufgerufen werden mit den Nachbardreiecken. usw... So und da wirds mir irgendwie zu kompliziert.

Irgendwann sollen in aktWeg ein Weg gespeichert sein. der kommt dann in optWeg und wird dann dort weiterverarbeitet, aber das soll uns erstmal hier nicht weiter stören.

Abbruchbedingungen wären: 1. der Weg ist 20 Dreiecke lang -> gültiger Weg, abspeichern in optWeg

2. das Dreieck wurde schon mal betreten-> Schritt zurück

3. Es geht gar nicht mehr weiter-> verlaufen! Schritt zurück

das problem ist, dass ich nicht mehr durchblicke und keine möglichkeiten sehe, irgendwie stück für stück zu programmieren und zu schauen, wies funktioniert, man muss diesen rekursiven Block irgendwie auf einmal richtig am Stück schreiben oder?

ich blick nich mehr durch... hilfe....

ich dachte ich mache ne arraylist wo die nachbarn drin sind. und wenn die rekursive schleife zurückspringt, dann löscht er diesen nachbarn. was mache ich aber wenn der weg ein wenig um die ecke geht? irgendwie muss ich speichern, wo der schon drauf war *verzweifel* meine Birne is auch noch total platt.... nach 5-6 stunden nur programmieren kriegt man irgendwie keinen klaren Kopf mehr...

Kann mir denn niemand helfen????

Eine Lösung dafür habe ich nunmal nicht...

Habe mir allerdings auch Gedanken dazu gemacht - vielleicht helfen die dir weiter.

Aber nicht Lachen, bin nunmal kein Studierter :D

Jetzt erst mal abgesehen von der Rekursion. Dein Problem:

Du suchst den kürzesten bzw. überhaupt einen Pfad über alle Flächen!?

Dazu würd ich zunächst in meiner Dreieck-Klasse das Feld betreten[boolean] hinzunehmen, sowie in jedem Dreieck die Referenz auf die drei Nachbarn halten.

Logisches Vorgehen für die Rekursion:

1. Startdreieck bestimmen.

2. Suche freie Nachbarn [geht über das Feld "betreten" dann ja leicht]

3. Wenn du in eine Sackgasse läufst gehst du einfach so weit zurück, bis du einen alternativen Weg auswählen kannst.

Hab zwar keine Vorstellung wie man das am besten macht, aber vielleicht hilfts dir ja weiter :confused:

gruss

markus

So fertig. *puh* Wens interessiert, unten der Quelltext.

Mir gefällts zwar vom Stil her nicht so... wegen set-Methoden usw. aber es funktioniert wenigstens...

Hat einer vielleicht noch ne Idee, wie ich das mit der set-Methode, bzw. add-Methode wegkriege?

Ich vermute, das ist kein schöner objektorientierter Stil, da solche Eigenschaften doch sicher private sein sollten, oder...

public void berechne(Ikosaeder Iko, Dreieck d){

aktWeg.addWegpunkt(d); //Wegpunkt addieren

laenge=laenge+1; //Weglänge erhöhen

LinkedList Nachbarn = new LinkedList(); //Nachbarn initialisieren

d.setBetreten(true); //Dreieck ist betreten

Dreieck n1 = (Dreieck)Iko.getDreiecki(d.getNachbar1()); //Nachbarn finden,

Dreieck n2 = (Dreieck)Iko.getDreiecki(d.getNachbar2()); //die noch nicht

Dreieck n3 = (Dreieck)Iko.getDreiecki(d.getNachbar3()); //betreten wurden

if (n1.getBetreten()==false)Nachbarn.add(n1);

if (n2.getBetreten()==false)Nachbarn.add(n2);

if (n3.getBetreten()==false)Nachbarn.add(n3);

Iterator it = Nachbarn.iterator();

while(it.hasNext()){ //solange es unbetretene Nachbarn gibt

Dreieck n = (Dreieck)it.next();

berechne(Iko, n); //hier ist die Rekursion

aktWeg.removeLast(); //beim Zurückgehen Feld wieder freimachen

}

//Test-abschnitt für Inhalte der Wege

/*if(laenge==20){

System.out.println("\n\nLaenge:"+laenge+" Dauer: "+aktWeg.getDauer()+

" Dauer optWeg: "+optWeg.getDauer()+"\n");

aktWeg.toString();

} */

if(optWeg.getDauer()==19 & laenge==20){ //erster Durchlauf optWeg mit

optWeg.clone(aktWeg); // aktWeg füllen

}

if(optWeg.getDauer() > aktWeg.getDauer() & laenge==20){

optWeg.clone(aktWeg); //in den nächsten Durchläufen

//den optimalen Weg herausfinden

System.out.println(optWeg.toString() + " " + optWeg.getDauer());

}

d.setBetreten(false); //Betreten-Tag wieder rückgängig machen

laenge--; //Länge dekrementieren wege Rückschritt

}

Was soll daran nicht Objektorientiert sein?

So in der Art hatte ich mir das gedacht...

Es ist doch Sinn der OOP Zugriff auf Objektvariablen nur über Getter und Setter-Methiden zuzulassen.

Für mich sieht die Fuktion recht stimmig aus.

gruss

markus

ok, dann passt das so :-P

danke an alle soweit für die Mithilfe...

immer wieder ein klasse Team hier

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.