Commander_COM Geschrieben 19. Mai 2005 Geschrieben 19. Mai 2005 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. Zitieren
Commander_COM Geschrieben 19. Mai 2005 Autor Geschrieben 19. Mai 2005 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: *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 :-( Zitieren
perdian Geschrieben 19. Mai 2005 Geschrieben 19. Mai 2005 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. Zitieren
geloescht_Newlukai Geschrieben 19. Mai 2005 Geschrieben 19. Mai 2005 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* Zitieren
Commander_COM Geschrieben 19. Mai 2005 Autor Geschrieben 19. Mai 2005 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... Zitieren
Commander_COM Geschrieben 19. Mai 2005 Autor Geschrieben 19. Mai 2005 Vielleicht könnte man sich diese Form zunutze machen: sind ja 20 Dreiecke: 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? Zitieren
perdian Geschrieben 19. Mai 2005 Geschrieben 19. Mai 2005 *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. Zitieren
Muadibb Geschrieben 19. Mai 2005 Geschrieben 19. Mai 2005 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 Zitieren
Commander_COM Geschrieben 19. Mai 2005 Autor Geschrieben 19. Mai 2005 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 Zitieren
Muadibb Geschrieben 19. Mai 2005 Geschrieben 19. Mai 2005 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 Zitieren
Enno Geschrieben 19. Mai 2005 Geschrieben 19. Mai 2005 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?? Zitieren
Commander_COM Geschrieben 19. Mai 2005 Autor Geschrieben 19. Mai 2005 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: 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(); } } Zitieren
geloescht_Newlukai Geschrieben 20. Mai 2005 Geschrieben 20. Mai 2005 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. Zitieren
Commander_COM Geschrieben 20. Mai 2005 Autor Geschrieben 20. Mai 2005 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: Zitieren
Krain Geschrieben 20. Mai 2005 Geschrieben 20. Mai 2005 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 Zitieren
Commander_COM Geschrieben 20. Mai 2005 Autor Geschrieben 20. Mai 2005 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); } Zitieren
Krain Geschrieben 20. Mai 2005 Geschrieben 20. Mai 2005 //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? Zitieren
Commander_COM Geschrieben 20. Mai 2005 Autor Geschrieben 20. Mai 2005 jaaaaaaaaaaaa, danke. das mit dem getGraphics musste man erstmal kapieren, ich wusste vorher immer nicht, wo dieses blöde Graphics g herkommt Zitieren
Krain Geschrieben 20. Mai 2005 Geschrieben 20. Mai 2005 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. Zitieren
Commander_COM Geschrieben 24. Mai 2005 Autor Geschrieben 24. Mai 2005 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... Zitieren
Commander_COM Geschrieben 26. Mai 2005 Autor Geschrieben 26. Mai 2005 Kann mir denn niemand helfen???? Zitieren
Krain Geschrieben 26. Mai 2005 Geschrieben 26. Mai 2005 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 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 Zitieren
Commander_COM Geschrieben 26. Mai 2005 Autor Geschrieben 26. Mai 2005 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 } Zitieren
Krain Geschrieben 26. Mai 2005 Geschrieben 26. Mai 2005 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 Zitieren
Commander_COM Geschrieben 26. Mai 2005 Autor Geschrieben 26. Mai 2005 ok, dann passt das so :-P danke an alle soweit für die Mithilfe... immer wieder ein klasse Team hier Zitieren
Empfohlene Beiträge
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.