Entwickler-Ecke
Multimedia / Grafik - Polyeder mit OpenGL
Mathematiker - Di 21.08.12 13:54
Titel: Polyeder mit OpenGL
Hallo,
das nachfolgende Programm stellt meinen ersten Versuch mit OpenGL dar, wobei ich eigentlich nur Erklärungen aus verschiedenen OpenGL-Tutorials auf mein Problem angewandt habe.
Dargestellt werden verschiedene Polyeder, wobei sich hier im Programm nur wenige Beispiele befinden.
Das Programm funktioniert meiner Meinung nach auch ganz gut, wenn da nicht ein Schönheitsfehler wäre. Eigentlich möchte ich, dass die Körperflächen fast gleiche Farben haben und entsprechend heller oder dunkler sind, je nachdem wie Licht einfällt.
Aus einem Tutorial habe ich, dass man mit den Befehlen
Delphi-Quelltext
1: 2: 3: 4: 5:
| glMaterialfv(GL_FRONT, GL_DIFFUSE, @mat_diffuse[0]); glLightfv(GL_LIGHT0, GL_AMBIENT, @light_ambient[0]); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); |
dies realisiert. Bei mir funktioniert es aber nicht. Entweder werden die Anweisungen ignoriert oder, wenn ich glColor3f entferne, alle Flächen sind gleichgefärbt, wodurch man keinen Körper mehr erkennt.
Es wäre schön, wenn einer von Euch einen Hinweis auf meinen Fehler hätte.
Beste Grüße
Mathematiker
Nachfolgend gebe ich nur einen Teil des Quelltextes an. Der vollständige Text ist im Anhang.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81:
| const mat_specular : Array[0..3] of GlFloat = (1.0, 1.0, 1.0, 1.0); mat_shininess : Array[0..0] of GlFloat = (50.0); mat_ambient : Array[0..3] of GlFloat = (0.4, 0.4, 0.4, 1.0); mat_diffuse : Array[0..3] of GlFloat = (0.4, 0.8, 0.4, 1.0); light_position : Array[0..3] of GlFloat = (10.0, 10.0, 0.0, 1.0); light_ambient : Array[0..3] of GlFloat = (0.8, 0.8, 0.8, 1.0); light_diffuse : Array[0..3] of GlFloat = (0.8, 0.8, 0.8, 1.0);
procedure seite; var nn,z:integer; begin glMaterialfv(GL_FRONT, GL_SPECULAR, @mat_specular[0]); glMaterialfv(GL_FRONT, GL_SHININESS, @mat_shininess[0]); glMaterialfv(GL_FRONT, GL_AMBIENT, @mat_ambient[0]); glMaterialfv(GL_FRONT, GL_DIFFUSE, @mat_diffuse[0]);
glLightfv(GL_LIGHT0, GL_AMBIENT, @light_ambient[0]); glLightfv(GL_LIGHT0, GL_DIFFUSE, @light_diffuse[0]); glLightfv(GL_LIGHT0, GL_POSITION, @light_position[0]);
glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); w:=flaechenfeld[0]/100; nn:=1; z:=0; glBegin(GL_TRIANGLE_fan); repeat if flaechenfeld[nn]=-1 then begin glEnd(); z:=0; if nn<punktzahl then begin glBegin(GL_TRIANGLE_fan); end; end else begin case z of 0 : glColor3f(1,0,0); 1 : glColor3f(0.95,0.95,0.95); 2 : glColor3f(0,0,1); 3 : glColor3f(0,1,0); 4 : glColor3f(0,1,1); 5 : glColor3f(1,0,1); 6 : glColor3f(1,1,0); 7 : glColor3f(0.9,0.4,0.4); 8 : glColor3f(0.4,0.9,0.4); 9 : glColor3f(0.4,0.4,0.9); 10 : glColor3f(1,0.4,0.4); else glColor3f(1,0.4,0); end; inc(z); glVertex3f(w*ppx[flaechenfeld[nn],0], w*ppx[flaechenfeld[nn],1], w*ppx[flaechenfeld[nn],2]); end; inc(nn); until nn>punktzahl; end; ...
procedure drawscene; var f:real; begin starttime:=gettickcount; glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glpushmatrix; f:=5+vv; glTranslatef(f,f,f); glRotatef(-rotang, 1, -0.3, -1); if nr=0 then poly0 else seite; glPopMatrix; glFinish; SwapBuffers(DC); elapsedframetime:=gettickcount-starttime; end; |
Nachtrag: In der Revision 6 sind jetzt 150 Polyeder enthalten. Außerdem kann der Hintergrund umgeschaltet werden.
Nachtrag 2: Das Programm zur Darstellung der Polyeder wird jetzt unter
http://www.entwickler-ecke.de/viewtopic.php?p=666870#666870 im Open Source-Bereich fortgeführt.
Xion - Di 21.08.12 19:35
Hi,
es gibt da eine ganz wesentliche Regel, die man wissen muss wenn es um OpenGL geht:
Wenn du Licht verwendest, werden Color-Befehle ignoriert! (moderiert: siehe Bergmann89s Posting).
Es gibt da einmal das Color-Konzept, damit kann man so Bilder machen wie du zeigst. Und zwar einfach und intuitiv.
Wenn du Licht verwendest, geht das alles über die Materialien. Materialien sind deutlich komplexer und zum Teil etwas wirr, wenn man die Grundlagen nicht kennt. Es gibt folgende Lichtquellen und Materialien, welche bezüglich diesen Lichtquellen definiert sind:
:arrow: Ambient
Das ist Umgebungslicht ohne Richtung.
:arrow: Diffuse
Das ist das Licht von Lampen, die aus einer bestimmten Richtung strahlen (also das Gegenteil von Ambient wenn man so will, welches keine Richtung hat und von überall kommt).
:arrow: Specular
Spekulare Lichteffekte treten immer dann auf, wenn man in einem bestimmten Winkel auf ein Objekt guckt. Man könnte "Glanzeffekt" dazu sagen.
Noch als Anmerkung: OpenGL kennt keine Schatten von Haus aus.
Zu jedem Lichttyp gibts dann auch ein Material. Wenn du ein Material nimmst, und mat_ambient (bei dir) auf schwarz stellst, aber mat_diffuse auf weiß, dann wird Ambientes Licht dein Objekt nicht beleuchten. Du kannst also mit den Materialien auf die einzelnen Lichttypen reagieren.
Jetzt zu deinem Problem:
Du hast bereits eine Lampe, die diffus grau (light_diffuse=0.8 ) leuchtet. Die würde ich erstmal auf weiß setzen (light_diffuse=1.0). Statt glColor (was bei aktiviertem Licht nichts bewirkt) setzt du jetzt einfach das diffuse Material (mat_diffuse) auf deine gewünschte Farbe. Evtl wäre es sinnvoll, die Farben auch bei mat_ambient zu setzen, sonst siehst du nur Farben wenn die Lampe darauf leuchtet, aber dort wo sie nicht hinleuchtet ("hinten") ist alles einfarbig. Kommt halt immer drauf an, was man bewirken möchte ;)
mat_specular würde ich auf 1 lassen, denn dann hast du einen einheitlichen weißen Glanzeffekt. Achja, und du solltest den Ambient-Anteil reduzieren, sonst siehst du nicht viel ;)
PS:
mit den folgenden Befehlen kannst du die Leuchtkraft deiner Lichtquelle beeinflussen (die Werte geben dabei immer die Abnahme der bezüglich der Entfernung an).
Delphi-Quelltext
1: 2: 3:
| glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0); glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0); |
Was dein nächstes Problem sein wird (ich sehe es gerade vor mir ;)): Shading
OpenGL berechnet die Farbe nur pro Eckpunkt eines Dreiecks und interpoliert dann (nennt sich Gouraud Shading). Das hat zur Folge, dass dein Licht nur mit den sehr weit auseinander liegenden Ecken berechnet wird. Um einen schönenn Übergang zu haben, wirst du wohl deine Dreiecke detailierter machen müssen (bestehend aus vielen kleinen Rechtecken/Dreiecken).
Mathematiker - Di 21.08.12 20:20
Hallo Xion,
erst einmal vielen Dank für die sehr umfangreiche Hilfe. Mein Gefühl war schon vorher, dass OpenGL nichts ist, was man "so nebenbei" erlernt. Du hast es noch bestätigt. Folglich kommt noch eine Menge Arbeit auf mich zu.
Ich habe Deine Hinweise eingebaut, und siehe da, es ändert sich die Helligkeit der Flächen. Damit kann ich weiter experimentieren.
Etwas verwundert bin ich aber, dass alle Flächen gleichzeitig ihre Helligkeit ändern, sogar bis zu schwarz. Durch das ambiente Licht müsste doch immer etwas zu sehen sein. Oder rotiert die Lichtquelle?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:
| procedure seite; const mat_specular : Array[0..3] of GlFloat = (1.0, 1.0, 1.0, 1.0); mat_shininess : Array[0..0] of GlFloat = (50.0); mat_ambient : Array[0..3] of GlFloat = (1, 1, 1, 1.0); mat_diffuse : Array[0..3] of GlFloat = (0.9, 0, 0, 1.0); light_position : Array[0..3] of GlFloat = (10.0, 10.0, 10.0, 1.0); light_ambient : Array[0..3] of GlFloat = (1, 1, 1, 1.0); light_diffuse : Array[0..3] of GlFloat = (1.0, 1.0, 1.0, 1.0); var i,nn,z:integer; procedure farbe; var i:integer; begin case z mod 6 of 0 : begin mat_diffuse[0]:=1; mat_diffuse[1]:=0; mat_diffuse[2]:=0; end; 1 : begin mat_diffuse[0]:=0.95; mat_diffuse[1]:=0.95; mat_diffuse[2]:=0.95; end; 2 : begin mat_diffuse[0]:=0; mat_diffuse[1]:=0; mat_diffuse[2]:=1; end; 3 : begin mat_diffuse[0]:=0; mat_diffuse[1]:=1; mat_diffuse[2]:=0; end; 4 : begin mat_diffuse[0]:=0; mat_diffuse[1]:=1; mat_diffuse[2]:=1; end; 5 : begin mat_diffuse[0]:=1; mat_diffuse[1]:=0; mat_diffuse[2]:=1; end; end; for i:=0 to 2 do mat_ambient[i]:=mat_diffuse[i]; glMaterialfv(GL_FRONT, GL_SPECULAR, @mat_specular[0]); glMaterialfv(GL_FRONT, GL_SHININESS, @mat_shininess[0]); glMaterialfv(GL_FRONT, GL_AMBIENT, @mat_ambient[0]); glMaterialfv(GL_FRONT, GL_DIFFUSE, @mat_diffuse[0]); glLightfv(GL_LIGHT0, GL_AMBIENT, @light_ambient[0]); glLightfv(GL_LIGHT0, GL_DIFFUSE, @light_diffuse[0]); glLightfv(GL_LIGHT0, GL_POSITION, @light_position[0]); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1); end; begin glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); w:=flaechenfeld[0]/100; nn:=1; z:=0; glBegin(GL_TRIANGLE_fan); repeat if flaechenfeld[nn]=-1 then begin glEnd(); if nn<punktzahl then begin glBegin(GL_TRIANGLE_fan); z:=0; end; end else begin inc(z); farbe; glVertex3f(w*ppx[flaechenfeld[nn],0], w*ppx[flaechenfeld[nn],1], w*ppx[flaechenfeld[nn],2]); end; inc(nn); until nn>punktzahl; end; |
Das Zerlegen der Flächen in kleinere Teilflächen wird ein Problem werden.
Die Berechnung der Raumkoordinaten der Punkte der Sternpolyeder war schon eine mathematische Herausforderung. Weiteres Zerlegen wird eine Menge Arbeit. Aber auch das werde ich versuchen.
Beste Grüße
Mathematiker
Delphi-Laie - Di 21.08.12 21:03
Mathematiker hat folgendes geschrieben : |
Mein Gefühl war schon vorher, dass OpenGL nichts ist, was man "so nebenbei" erlernt. |
Mit Sicherheit (nicht).
Für Computergraphik gibt es doch längst eigene Lehrstühle, Informatikvertiefungsrichtungen und Berufe.
Allein mit den vielen Beleuchtungsparametern "rumzumachen" und überhaupt nur ein Gefühl dafür zu bekommen, wie welcher von welchem abhängt, kann man schon Stunden zubringen (ich kenne das von CAD). Ich probierte mich mal (erfolgreich) an einem Bildschirmschoner, der das Rauschbild eines Farbfernsehers simulieren soll (da es seit fast Jahrzehnten die Rauschunterdrückung gibt und inzwischen das Digitale siegte, kennen viele den "Anblick" des fehlenden oder gar zu schlechten Empfanges gar nicht mehr). Allein schon der Zusammenhang zwischen Helligkeit, Kontrast und Sättigung war nicht "mal eben so" programmiert.
Dein Programm ist ein schöner Schmaus für die Augen. Mein Favorit der Körper ist ein konvexer und in bezug auf die Seitenflächenanzahl noch trivialer, nämlich das Trigondodekaeder (noch häufiger im Internet unter "snub desphenoid" zu finden). Doch der ist nur scheinbar trivial, denn der hat es in sich! Ich bekam ihn - im Gegensatz zu anderen Polyedern - nicht mit CAD konstruiert, kapitulierte schließlich und wählte die unelegante Notlösung, seine Eckpunktkoordinaten, die ich auf Wolframs Internetseite(n) fand, einzugeben. Auch die Volumenformel, die man dort für ihn findet, zeigt, daß das scheinbar doch ziemlich einfache tatsächlich doch recht kompliziert sein kann.
Mathematiker - Di 21.08.12 22:10
Hallo Delphi-Laie,
Delphi-Laie hat folgendes geschrieben : |
Mein Favorit der Körper ist ein konvexer und in bezug auf die Seitenflächenanzahl noch trivialer, nämlich das Trigondodekaeder (noch häufiger im Internet unter "snub desphenoid" zu finden). Doch der ist nur scheinbar trivial, denn der hat es in sich! |
Auch die für den ersten Blick unscheinbaren Polyeder sind oft sehr interessant. Der von Dir genannte Körper wird im deutschsprachigen Raum auch gekürzter oder stumpfer Doppelkeil genannt und gehört zu den Johnson Polyedern.
Die Tücke ist, dass die Punktkoordinaten sich berechnen zu (meine Lösung ist kürzer als die bei mathworld.com):
Quelltext
1: 2: 3: 4: 5: 6:
| x ; y ; z ±1/2 ; 0 ; 0 0 ; ±x ; h-k ±x ; 0 ; k 0 ; ±1/2 ; h mit h = Wurzel(2·k²+1/2) ; x = Wurzel(3/4-(h-k)²) und k ist die positive Wurzel von 16·x^6+8·x^4-15·x²-8=0 |
Da die Gleichung, nach Reduktion, eine irreduzible 3.Grades ist, wird es nichts mit einer Konstruktion allein mit Zirkel und Lineal. Ich habe keine Ahnung von CAD, vermute aber dass es deshalb nicht geht.
In der 1.Revision habe ich das Polyeder zusätzlich eingefügt. Solange ich das mit den Lichteffekten nicht richtig hinbekomme, lasse ich auch erst einmal meine "bunten" Seitenflächen. Sieht ja auch ganz nett aus. :)
Beste Grüße
Mathematiker
Xion - Di 21.08.12 22:22
Mathematiker hat folgendes geschrieben : |
Etwas verwundert bin ich aber, dass alle Flächen gleichzeitig ihre Helligkeit ändern, sogar bis zu schwarz. Durch das ambiente Licht müsste doch immer etwas zu sehen sein. Oder rotiert die Lichtquelle?
|
Die Lichtquelle rotiert mit, ja, weil zu zuerst glRotate aufrufst und anschließend die Lichtquelle platzierst. Ich habe jetzt eine Weile gegrübelt warum das so seltsam mit dem Licht aussieht. Es sieht für mich so aus, als hätten alle Flächen den selben Normalenvektor (nach dem wird die Beleuchtung berechnet). Klingt vielleicht total bescheuert, dass man den verstellen kann (wie die Normale einer Fläche aussieht ist ja eigentlich klar), aber man kann den pro Eckpunkt setzen. Bei einer Kugel z.B. können die Normalen der einzelnen Eckpunkte so genau richtig berechnet werden (wir erinnern uns: Gouraud-Shading, also Berechnung pro Eckpunkt) wie es für eine Kugel wäre. Wenn wir pro Fläche die Normale benutzen, dann gäbe es Kanten (wir haben dann Flat-Shading, also die Fläche hat komplett die selbe Farbe). Mit den Normalen hatte sich selbst auch schonmal Probleme, sonst wäre ich da jetzt nicht drauf gekommen. Das mit dem ambienten Anteil ist in der Tat komisch.
Eine Normale kannst du so setzen (jeweils vor glVertex):
Mit
Delphi-Quelltext
1:
| glEnable(GL_NORMALIZE); |
werden sie automatisch auf Länge 1 umgerechnet. (wichtig!)
Du musst mal sehen ob das was bringt. Mit dem alten Code gings ja noch. Ich weiß aber auch nicht genau warum (war auch auf einem andren Rechner bei mir, aber daran sollte es nicht liegen). Habs jetzt so auf Anhieb nicht hingekriegt, die Normalen richtig zu setzen.
Mathematiker hat folgendes geschrieben : |
Das Zerlegen der Flächen in kleinere Teilflächen wird ein Problem werden. |
Ich glaube das ist nicht so schlimm. Du hast jetzt die Eckpunkte A,B,C. Sagen wir mal der Einfachheit halber, das Rechteck A,B,C,C. Dann kannst du das leicht in Stücke schneiden (also statt Kante B->A dann x*(B-A)/n -> (x+1)*(B-A)/n). Naja, oder so ähnlich, du bist hier der Mathematiker :mrgreen:
Mathematiker - Di 21.08.12 22:47
Hallo Xion,
Xion hat folgendes geschrieben : |
Eine Normale kannst du so setzen (jeweils vor glVertex):
Mit
Delphi-Quelltext 1:
| glEnable(GL_NORMALIZE); |
werden sie automatisch auf Länge 1 umgerechnet. (wichtig!)
Du musst mal sehen ob das was bringt. |
vielen Dank für den Hinweis auf die Normalen. Ich staune, was es alles gibt.
Ich habe es gleich eingebaut und es bringt etwas, einen lustigen Effekt: Jetzt werden die Körper kurzzeitig auch ganz weiß.
Irgendwie komisch. Aber ich werde weiter suchen.
Kennst Du ein gutes Buch über OpenGL? Das Angebot, allein bei amazon, ist ziemlich groß. Leider weiß man nie vorher, was gut ist?
Beste Grüße
Mathematiker
Bergmann89 - Mi 22.08.12 00:41
Hey:
Xion hat folgendes geschrieben : |
Wenn du Licht verwendest, werden Color-Befehle ignoriert! |
Da muss ich dir wiedersprechen. glEnable(GL_COLOR_MATERIAL) macht es möglich, das die normale Farbe (glColor) als Parameter des Lichts interpretiert wird. Welcher Parameter das ist, kann man mit
glColorMaterial [
http://wiki.delphigl.com/index.php/glColorMaterial] festlegen.
Xion hat folgendes geschrieben : |
Mit
Delphi-Quelltext 1:
| glEnable(GL_NORMALIZE); |
werden sie automatisch auf Länge 1 umgerechnet. (wichtig!) |
Für einen Anfänger ist das natürlich der einfachste Weg, aber GL_NORMALIZE ist sehr langsam, deshalb sollte man später, wenn es auf performance ankommt, dafür sorgen, dass die Normalen schon beim Laden des Objekts normalisiert werden und auf ein GL_NORMALIZE verzichten. Das nur mal so als kleine Randbemerkung :)
@Mathematiker: Ich würde dir für den Anfang empfehlen einen einfachen Würfel zu Zeichen. Bei dem kannst du die Normalen per Hand ganz einfach setzen und kannst so die Richtigkeit deiner Licht- bzw. MaterialParameter überprüfen. Anschließend kannst du dann deinen Ployeder einbauen. Bei
DelphiGL [
http://delphigl.com/] gibts gute
Tutorials [
http://wiki.delphigl.com/index.php/Tutorial] zu eigentlich allen Grundlagen. Dort hab ich mir alles angeeignet, was ich über OpenGL weiß. Ein passendes
Tutorial zum Licht [
http://wiki.delphigl.com/index.php/Tutorial_Lektion_8] gibt es natürlich auch. Ein Buch brauch man dafür nicht wirklich, es sei denn du bist eher der Typ, der beim Lernen was in der Hand halten will ;) Wenn dem so ist, kann ich dir das sogenannte
Red Book [
http://www.amazon.com/OpenGL-Programming-Guide-Official-Learning/dp/0321335732] empfehlen. Da steht auch so ziemlich alles drin (glaube auch mit Bsp. Code).
MfG Bergmann.
Xion - Mi 22.08.12 07:23
Mathematiker hat folgendes geschrieben : |
Ich habe es gleich eingebaut und es bringt etwas, einen lustigen Effekt: Jetzt werden die Körper kurzzeitig auch ganz weiß. |
Versuche mal die Lichtquelle vor glRotate zu definieren. Dann hast du eine statische Lichtquelle.
Mathematiker hat folgendes geschrieben : |
Kennst Du ein gutes Buch über OpenGL? Das Angebot, allein bei amazon, ist ziemlich groß. |
Neben DelphiGL ist noch
NeHe [
http://nehe.gamedev.net] (rechts die legacy tutorials) eine super Quelle für OpenGL. Ich hatte dann noch eine Vorlesung in der Uni dazu, wo es (nur theoretisch) um OpenGL ging und das mit dem Licht etwas klarer wurde. Bücher hab' ich aber keine dazu, da kann ich also keins empfehlen. ;)
Mathematiker - Mi 22.08.12 09:14
Hallo Xion, Hallo Bergmann89,
vielen Dank für die vielen Hinweise. Ich werde alle genannten Tutorials ansehen und sicher eine Lösung finden.
Mein Hauptproblem ist wohl, dass ich nicht schrittweise, beginnend bei den ersten Grundlagen, mich in OpenGL einarbeiten wollte. :oops:
Beste Grüße
Mathematiker
Bergmann89 - Mi 22.08.12 13:15
Hey,
ich denke die absoluten Basics hast du drauf. Immerhin hast du es geschaft den Context zu erstellen und die Geometrie zu zeichnen. Was anderes wird in den ersten 6 Tutorials nicht erklärt (mal abgesehen von den Texturen, aber die brauchst du in deinem Fall ja nicht). Der nächste Schritt wäre also so oder so das Licht gewesen. Was auch ganz wichtig ist, sind die Matrix Operationen. Viele Fehler entstehen, weil die einfach falsch genutzt wurden. Da gibts bei DGL auch ein
sehr ausführliches Tutorial [
http://wiki.delphigl.com/index.php/Tutorial_Lektion_3] dazu. Noch genauer wird es dann im
zweiten Teil [
http://wiki.delphigl.com/index.php/Tutorial_Matrix2] beschrieben.
MfG Bergmann.
Delphi-Laie - Mi 22.08.12 13:53
Hallo Mathematiker, danke!
Mein Ziel war gar nicht, daß Du meinen Lieblingskörper einbaust, aber daß er nun integriert ist, dafür danke ich Dir! Er ist ja auch keine auffällige, offenkundige Schönheit (z.B. ist seine Symmetrie nur mittelmäßig), sondern er fasziniert mich deshalb, weil er - scheinbare - Trivialität und tatsächliche Kompliziertheit vereint, und das auch noch versteckt.
Woher Du das hast bzw. wie Du das hinbekamst, ist mir jetzt auf Anhieb nicht klar, vermute aber, daß Du einfach Deine mathematische Routine anwandtest, um das zu vereinfachen. Ich bin beeindruckt, denn Wolframs Internetseite(n) macht nicht jeder so schnell etwas vor.
Mathematiker hat folgendes geschrieben : |
Da die Gleichung, nach Reduktion, eine irreduzible 3.Grades ist, wird es nichts mit einer Konstruktion allein mit Zirkel und Lineal. |
Auch dieser Körper hat ein Netz, wie jedes andere Polyeder auch. Wollte man ihn aus Papier zusammensetzen, geht es genausow wie bei den anderen auch - zusammenfalten (das sind im wesentlichen Rotationen der Flächen um die (Falt-)Kanten, bis diese sich in einer weiteren gemeinsamen Kante treffen). Grundsätzlich müßte dieser Körper so auch in CAD konstruierbar sein. Warum ich das damals nicht hinbekam, weiß ich just nicht, denn das ist schon einige wenige Jahre her.
Mathematiker hat folgendes geschrieben : |
Ich habe keine Ahnung von CAD, vermute aber dass es deshalb nicht geht. |
Nun, wenn man geometrisch ein wenig experimentieren möchte, ist CAD schon ganz nützlich. Ob die auf Mathematik ausgerichteten Programme (MathCad, Mathematica % Co.) ähnliche Funktionen auch für die Geometrie bieten, weiß ich nicht.
Vordergründig soll es in dieser Diskussion ja um Deine Anwendung der Delphi-Implementation des OpenGLs gehen.
Mathematiker - Mi 22.08.12 14:38
Delphi-Laie hat folgendes geschrieben : |
Woher Du das hast bzw. wie Du das hinbekamst, ist mir jetzt auf Anhieb nicht klar, vermute aber, daß Du einfach Deine mathematische Routine anwandtest, um das zu vereinfachen. |
Ich habe vor einiger Zeit per Hand alle platonischen, archimedischen und catalanschen Körper, die Johnson-Polyeder und alle uniformen Polyeder durchgerechnet. Die ersten für die Diplomarbeit, die anderen aus Spaß an der Sache. Aus diesem Grund habe ich von diesen Körpern auch die Punktkoordinaten vorliegen.
Delphi-Laie hat folgendes geschrieben : |
Auch dieser Körper hat ein Netz, wie jedes andere Polyeder auch. Wollte man ihn aus Papier zusammensetzen, geht es genausow wie bei den anderen auch - zusammenfalten (das sind im wesentlichen Rotationen der Flächen um die (Falt-)Kanten, bis diese sich in einer weiteren gemeinsamen Kante treffen). Grundsätzlich müßte dieser Körper so auch in CAD konstruierbar sein. |
Ist richtig, mein Fehler. Mit einem hinreichend guten Programm können die Seitenflächen, evtl. auch näherungsweise, gezeichnet werden. Es müsste also gehen.
Beste Grüße
Mathematiker
Delphi-Laie - Mi 22.08.12 19:56
Leider sind die Spinedits nicht beschriftet.
Der untere scheint für die Größe des Polyeders verantwortlich zu sein. Doch der obere? Ich fand es jedenfalls noch nicht heraus.
Edit: Soeben konnte ich damit - leider nicht rückgängigmachbar - die Rotationsgeschwindigkeit verringern.
Mathematiker - Mi 22.08.12 22:13
Hallo Delphi-Laie,
Delphi-Laie hat folgendes geschrieben : |
Leider sind die Spinedits nicht beschriftet. ...
Edit: Soeben konnte ich damit - leider nicht rückgängigmachbar - die Rotationsgeschwindigkeit verlangsamen. |
Danke für den Hinweis. In der Revision 2 der Exe mit Quelltext habe ich das geändert.
Zusätzlich habe ich auch noch ein paar neue Polyeder eingefügt.
Beste Grüße
Mathematiker
Delphi-Laie - Do 23.08.12 13:59
Wenn man das Fenster noch maximieren könnte oder gar in den Vollbildmodus umschalten könnte, wäre das ganz lässig. Sicher wird es jedoch einen Grund haben, daß Du das ausschlossest. Vielleicht kommt ja wenigstens ersteres noch. Oder gar eine bewegliche Rotationsachse: Entweder taumelnd (beschreibt einen Kegelmantel), zufällig drehwandernd oder gar mit der Maus verdrehbar? Das ist alles natürlich nicht trivial implementierbar, das ist mir bewußt.
Mathematiker - Do 23.08.12 15:27
Hallo Delphi-Laie,
Delphi-Laie hat folgendes geschrieben : |
Oder gar eine bewegliche Rotationsachse: |
Dein Wunsch ist mir Befehl, allerdings nicht vollständig wählbar. An den 3 Spinedits x-, y- und z-Achse kann die relative Drehung um diese Achsen eingestellt werden.
Delphi-Laie hat folgendes geschrieben : |
Wenn man das Fenster noch maximieren könnte oder gar in den Vollbildmodus umschalten könnte, wäre das ganz lässig. Sicher wird es jedoch einen Grund haben, daß Du das ausschlossest. |
Hat es, leider. Aus irgendeinem, mir noch unklaren, Grund stellt mein Rechner die Polyeder nur bis zu einer bestimmten Fenstergröße dar. Ich vermute, dass es an meinem alten Computer liegt.
Ich habe in der Revision 3 (testweise) die Fenstermaximierung und die Fenstergrößenänderung mit der Maus zugelassen.
Du kannst ja mal testen, ob bei verschiedenen Fenstergrößen immer ein Polyeder zu sehen ist, bei mir leider nicht.
Beste Grüße
Mathematiker
Delphi-Laie - Do 23.08.12 16:25
Hallo Mathematiker!
Erster Eindruck - bestens! Es gibt keine Darstellungsprobleme mit maximiertem Fenster.
Das einzige, was ich in diesem Maximalmodus noch ein klein wenig zu bemängeln hätte, ist, daß die Zentrierung (oder Positionierung) der Polyeder noch etwas präziser sein könnte: Manchmal stoßen sie oben während des Rotierens an die Fenster(titel)kante und werden entsprechend abgeschnitten, unten hingegen nicht. Klar, mit Zoomen ist das vermeidbar, aber die nicht ganz perfekten Zentrierung ändert sich damit nicht.
Weiterhin viel Spaß und Erfolg damit!
Gruß Delphi-Laie
Mathematiker - Do 23.08.12 17:54
Hallo Delphi-Laie,
Delphi-Laie hat folgendes geschrieben : |
Das einzige, was ich in diesem Maximalmodus noch ein klein wenig zu bemängeln hätte, ist, daß die Zentrierung (oder Positionierung) der Polyeder noch etwas präziser sein könnte: |
Hatte ich vollkommen übersehen. Danke für den Hinweis.
Mit etwas Probieren habe ich eine Lösung gefunden. Jetzt dürfte es (Revision 4) korrekt funktionieren; und für mich das Schönste: Jetzt sehe ich auch auf meinem Computer bei jeder Fenstergröße ein Bild. :D
Beste Grüße
Mathematiker
Nachtrag: Rev 4 hatte einen Fehler. Sorry. In Rev 5 geändert.
Xion - Sa 25.08.12 10:14
Hab mir eben das Programm nochmal angeguckt (aus dem andren Thread). Sehr coole Objekte sind da dabei :zustimm:
Bei MO12 (siehe Bild), U37 (die Flächen in den Sternen) und PT39 (oben/unten) hab ich
Z-Fighting [
http://wiki.delphigl.com/index.php/ZFighting] (flackern), da hast du wohl Flächen mehrfach an der selben Stelle gerendert.
Die Rotationseinstellungen find ich nicht so gelungen. ;) Ich setze sowas meist mit direkter Maussteuerung um (ist einfach intuitiver). Ist auch ganz leicht: Wenn der User auf das OpenGL-Panel klickt (mousedown) merkst du dir die Mausposition und setzt ein bool auf true. Bei OnMouseMove nimmst du (falls bool true ist) die Differenz aus den XPositionen für die y-Rotation und die YPositionen für die x-Rotation. Bei OnMouseUp setzt du den bool auf false. Es ist dabei sinnvoll, die x-Rotation auf 180° zu begrenzt ;)
Mathematiker - Sa 25.08.12 12:21
Hallo Xion,
vielen Dank für den Hinweis.
Xion hat folgendes geschrieben : |
Bei MO12, U37 (die Flächen in den Sternen) und PT39 (oben/unten) hab ich Z-Fighting. |
Beim 1.Polyeder habe ich mich wohl verrechnet, das muss ich prüfen. Vorerst habe ich MO12 entfernt.
Bei den anderen beiden treten die verflixten Sternpolygone auf, die mich schon bei der Körperberechnung geärgert haben.
Im Moment habe ich eine "Notlösung" (Programm im anderen thread
http://www.entwickler-ecke.de/viewtopic.php?t=110058) eingefügt, in dem ich diese Flächen nur mit einer Farbe fülle. Zur endgültigen Lösung werde ich wohl oder übel nochmals die Polygone nachrechnen müssen.
Beste Grüße
Mathematiker
Bergmann89 - Sa 25.08.12 14:58
Hey,
das mit OnMouseDown brauch man gar nicht, denn bei OnMouseMove werden die derzeit gedrücken Maustasten im Parameter Shift: TShiftState mitgeliefert ;)
MfG Bergmann.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!