Zum Inhalt springen

Projektaufgabe: Ikosaeder zeichnen


Commander_COM

Empfohlene Beiträge

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 :-(

Link zu diesem Kommentar
Auf anderen Seiten teilen

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*

Link zu diesem Kommentar
Auf anderen Seiten teilen

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...

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

*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.
Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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??

Link zu diesem Kommentar
Auf anderen Seiten teilen

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();

}

}

Link zu diesem Kommentar
Auf anderen Seiten teilen

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:

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

}

Link zu diesem Kommentar
Auf anderen Seiten teilen

//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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was ist dein Draw Objekt? Ein JFrame? Oder ein Canvas?

Leite dir am besten die Draw-Klasse von Canvas ab und füge das Draw-objekt später in einen Frame ein... Ist meiner meinung nach geschickter als direkt auf den Frame zu malen.

Handbuch der Javaprogrammierung - Canvas

Schau dir das mal an... das könnte dir etwas weiterhelfen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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...

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

}

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...