Wie visualisiere ich das Design einer Physik-Engine?

17

Ich mache eine Physik-Engine und es wird ziemlich schwierig, den Überblick zu behalten. Wenn ich nach einer Pause zu meinem Code zurückkehre, kann ich mich oft nicht erinnern, warum das nicht funktioniert. Die meisten Probleme sind keine einfachen Programmierfehler, sondern Designfehler in meiner Physik-Engine. Deshalb sollte ich es erst fertig entwerfen, bevor ich es programmiere.

Ich brauche jedoch eine Möglichkeit, das gesamte Design meiner Physik-Engine auf Papier zu schreiben. Sonst werde ich es morgen einfach vergessen und wieder verloren gehen. Ein UML-Klassendiagramm ist für den Entwurf einer Physik-Engine überhaupt nicht geeignet. Ich interessiere mich nicht wirklich für den Unterricht, sondern für den Prozess. Ich sehe das Geschäftsprozessdiagramm nicht als wirklich nützlich an, da das Modellieren eines einzelnen Schritts (Rahmens) meines Prozesses mir nicht hilft, das endgültige Verhalten meiner Engine in vielen Schritten zu verstehen.

Welche Art von Diagramm sollte ich verwenden, um den Prozess im Auge zu behalten? Welche Art von Diagramm verwenden Profis, um eine Physik-Engine zu erstellen?

Winter
quelle
4
Zunächst würde ich ein allgemeines Flussdiagramm vorschlagen, um zu zeigen, wie der Motor verwendet wird und wie er die Dinge bewertet. Oder vielleicht etwas Ähnliches wie das OpenGL-Pipeline-Diagramm ( openglinsights.com/pipeline.html ). Dann würde ich eine Google Images-Suche nach "Physik-Engine-Diagramm" durchführen, um zu sehen, wie andere Leute es tun! ;)
FrustratedWithFormsDesigner
4
Mit "einem UML-Diagramm" meinen Sie wahrscheinlich ein Klassendiagramm? Das Klassendiagramm ist eines von 7 Strukturdiagrammen in UML. Es gibt auch 7 Arten von Verhaltensdiagrammen.
KOMMEN SIE VOM
Zunächst muss man die Physik-Engine sehr gut verstehen. jedes kleine Detail und wie die Dinge zusammenarbeiten. Mit Programmierung nichts zu tun. Anschließend versuchen Sie, es in Programmierentitäten (Klassen) und Interaktionen zu modellieren. Sie können beliebige Werkzeuge verwenden (sogar Skizzen und handgeschriebene Notizen). Dann erstellen Sie Ihre Klassen nacheinander. Beginnen Sie mit dem Schreiben einer Konsolenanwendung. Sie können Einheiten- / Klassentests verwenden, um sicherzustellen, dass Ihre kleinen Klassen funktionieren und das tun, was Sie erwarten
John Kouraklis
6
Nach meiner Erfahrung verwenden professionelle Programmierer keine Designdokumente oder -diagramme, um Dinge zu entwerfen. Vielleicht auf einem Whiteboard. Mit modernen Programmiersprachen sind Designs im Kopf und im Code. Designdokumente oder -diagramme werden am häufigsten für die Kommunikation verwendet. Meiner Einschätzung nach muss Ihr Design aufgrund Ihrer Beschreibung zerlegt werden.
JimmyJames
1
"Ein UML-Klassendiagramm ist für den Entwurf einer Physik-Engine überhaupt nicht geeignet." Warum nicht? Der Unterricht dreht sich alles um die Trennung von Anliegen. Jedes System kann in Komponenten mit unterschiedlichen Rollen unterteilt werden, und diese Komponenten können normalerweise in Klassen unterteilt werden.
Tanner Swett

Antworten:

29

TO DO-Listen sind wunderbare Dinge.

Ich spreche nicht von // #TODO: bla bla Kommentare. Ich meine, hol dir ein ehrliches Notizbuch zu Gott.

Sie wissen nie, wann Sie sich an etwas Wichtiges erinnern. Ein Notizbuch sitzt ruhig da und lässt Sie nachdenken, ohne sich darüber zu beschweren, wie Ihre Handschrift nicht kompiliert wird. Einige meiner besten Ideen entstehen im Badezimmer (ja, ich besitze ein wasserdichtes Notizbuch, aber so weit muss man nicht gehen).

Sie können Taschengrößen erhalten, die genäht (nicht geklebt) sind, damit sie nicht in Ihrer Tasche auseinanderfallen. Haben Sie es nicht geschafft, ein schickes mit einem eingebauten Lesezeichen zu bekommen? Klebeband, Schere, Schleife und niemand wird es jemals erfahren.

Wenn eine Idee zutrifft, schreiben Sie sie einfach auf. Zeichne kleine Kästchen neben jede Idee und du kannst sie leicht als erledigt markieren. Stellen Sie ein Kästchen oben auf die Seite und Sie wissen, wann die Seite fertig ist.

Welcher sequenzielle Zugriff ist für Sie nicht gut genug? Ja, sie stellen auch Taschenbücher her. Das alles scheint ein bisschen viel zu sein, aber es ist besser, als in Haftnotizen zu ertrinken oder zu versuchen, alles in Jira festzuhalten.

Lassen Sie die Dinge nicht halb implementiert

Halten Sie Ihre Verbesserungen klein und erreichbar. Fang nichts an, was nicht in einer Sitzung erledigt werden kann. Wenn es dafür zu groß ist, zerlegen Sie es in kleinere Schritte. Lassen Sie immer Code, der kompiliert und seine Tests besteht. Oh und lass keine bestandenen Tests scheitern, die du noch nie gesehen hast. Wenn Sie einen Test bestehen oder nicht bestehen, testen Sie den Test.

Hör auf zu denken, du brauchst das ganze Design auf Papier

Sie müssen lediglich Ihren Entwicklungsplan aufzeichnen. Du weißt nicht, wie die Dinge aussehen werden, wenn du fertig bist, also hör auf, so zu tun, als ob du es tust. Erfassen Sie so gut Sie können, was Sie herausgefunden haben. Verwenden Sie eine Serviette und einen Buntstift, wenn Sie müssen. Wenige Leute verstehen sowieso 90% von UML. Verwenden Sie, was auch immer Sie können, um zu zeigen, was Sie zeigen müssen. Ich konzentriere mich darauf, meine Benutzeroberflächen zu zeigen und was darüber weiß.

Schreiben Sie Notizen, wenn Sie mit dem Codieren aufhören

In dem Moment, in dem Sie Ihre Finger von den Tasten nehmen, werden Sie das letzte Mal verstehen, was Sie getan haben (und was Sie geplant haben) und was Sie jetzt tun. Halten Sie dieses Verständnis so gut wie möglich in einigen Notizen fest. Wenn Sie nur Kommentare haben, sind Sie immer noch an den Computer gebunden und hinterlassen wahrscheinlich eine Pfütze auf dem Stuhl. Auch hier ist ein Notebook eine großartige Sache.

Auf diese Weise können Sie Ihr Gehirn elegant landen lassen, Ihre Blase schonen und später wieder abheben, ohne auf Koffein und Zähneknirschen zurückgreifen zu müssen.

kandierte_orange
quelle
(Als ein ehrliches Notebook, das auch intelligent ist, funktioniert der Emacs Org-Modus gut. Ein ähnliches Tool, sogar ein Issue-Tracker, könnte je nach Prozess gut funktionieren Bilder, die beim Nachdenken groß ist .)
9000
6
+1 für Don't start anything that can't be finished in one sitting. If it's to big for that then break it down into smaller steps.. Es ist eines der wichtigsten Dinge, die ich in der Industrie gelernt habe.
Akshat Mahajan
8

"Bis auf das erste Mal sollte alles von oben nach unten gebaut werden", heißt es.

Ich beginne mit der niedrigsten Stufe (z. B. grundlegende Vektormathematik) und stelle sicher, dass ich sie gut verstehe und sie eine gute Testabdeckung hat. Dann würde ich eine weitere Ebene darüber aufbauen, um abstraktere Operationen zu ermöglichen (z. B. Gruppen / Entitäten, Kollisionserkennung, Kollisionsmechanik). Wieder würde ich es mit Tests abdecken; Es würde mir helfen, über die tatsächlichen Anwendungsfälle dieser Abstraktionen in der Engine nachzudenken.

Wenn Sie nicht über ein sehr gutes Verständnis der gesamten Engine verfügen (z. B. wenn Sie eine bekannte vorhandene Engine erneut implementieren), ist es in der Regel gut, diese Ebenen zu haben. Es ermöglicht Ihnen, auf einer bestimmten Ebene in Bezug auf die vorherige Ebene zu denken, und normalerweise nicht viel tiefer. Sie können mit neuen nützlichen Abstraktionen experimentieren und eine Ebene erstellen. Was sich in der Realität als praktisch erweist, weicht oft von den ursprünglichen Vorstellungen ab.

Hoffentlich ist jede Ebene so klein, dass Sie kein kompliziertes Diagramm dafür benötigen, oder es ist einfach, eine nützliche zu finden.

Ich bin noch nie auf ein komplexes Codediagramm gestoßen, das nützlich war. Interaktions- und Lebenszyklusdiagramme sind jedoch hilfreich. Sehr oft ist ein solches Diagramm auf 1-2 Ebenen beschränkt und daher einfach.

Was ich normalerweise am wertvollsten finde, sind Schnittstellenbeschreibungen und Garantien, die von jedem Level bereitgestellt werden. ZB das Format der Vektormathematik und was bei numerischen Fehlern passiert; Das Format der Beschreibungen größerer Objekte (immer konvex, immer im Uhrzeigersinn, wie schneidet man sich? usw.), die mechanischen Parameter der Wechselwirkung (wie die Zeit vergeht, wie die Masse gehandhabt wird, der Impuls immer erhalten bleibt, wie die Kräfte berechnet werden) richtige Wechselwirkungen (wie man mit Reibung, Verformung, Fragmentierung umgeht, ist die Umwandlung von mechanischer Energie in Wärmeverluste eine Sache?).

Jede Schicht sollte klein genug sein, um eine beobachtbare Menge von Dingen zu haben, die sie einführt und die sie garantiert. Diese Beschreibung kann sogar verfasst werden, ohne dass (noch) Implementierungscode geschrieben wurde. Dies verringert die Wahrscheinlichkeit festzustellen, dass Sie drei Schichten tief etwas schrecklich Falsches getan haben. Wenn Sie dies tun, ist es bereits in höchstens zwei Ebenen sichtbar.

9000
quelle
Ich mag es, den Code von unten nach oben aufzubauen und Schichten zu erstellen, die Ihre Problematik immer deutlicher zum Ausdruck bringen. Aber denken Sie nicht, dass Sie sie beim ersten Mal richtig machen. Sobald Sie anfangen, eine Ebene zu verwenden, um etwas höheres zu implementieren, werden Sie Probleme mit Ihrer API finden und müssen zurückgehen und es ändern. Es ist in Ordnung.
Justsalt
4

Machen Sie Diagramme der Architektur! Die OpenGL - Pipeline - Diagramme FrustratedWithFormsDesigner geschrieben in den Kommentaren ein großartiges Beispiel für Programm fließen , aber das ist nur eine Art von Diagramm , das nützlich sein kann.

Beim Entwerfen von Diagrammen möchten Sie das Verständnis des Codes einfach und intuitiv gestalten. Dies kann sowohl übergeordnete Konzepte (wie die oberste Zeile der Knoten in diesem OpenGL-Pipeline-Diagramm, die etwas sagen) als auch sehr detaillierte technische Details (wie ein Diagramm mit vollständigen Funktionsaufrufen) umfassen.

Im Idealfall sollte Ihre Dokumentation den Code auch für andere leicht verständlich machen. Dies kann Dinge wie Codeüberprüfungen oder Open-Source-Zusammenarbeit vereinfachen. Schauen Sie sich große Projekte an, um zu sehen, wie sie dies erreichen. Wenn Sie mit Hunderttausenden oder Millionen von Codezeilen arbeiten, ist es äußerst wichtig, die Funktionsweise des Programms zu verstehen, ohne es lesen zu müssen, um den Überblick über die Codebasis zu behalten oder es anderen vorzustellen . Das Vim-Repository verfügt mit 1,3 Millionen LOC über eine großartige Dokumentation (IMO) in der Datei /src/README.txt . Es führt ein:

  • Welchen Code in jeder Datei tut
  • Wichtige globale Variablen und ihre Werte
  • Was passiert in der Hauptschleife und welche Funktionen werden aufgerufen?
  • Was passiert in den einzelnen Modi und welche Hauptfunktionen sind damit verbunden?
  • Was sind native Debugging-Funktionen?

Wenn ich einen Patch beisteuern möchte, weiß ich im Allgemeinen, welche Datei ich ändern muss, um meine Ziele zu erreichen, ohne viel zu graben.

Eine der besten Eigenschaften von Vim /src/README.txtist, wie einfach es zu finden ist und wie umfassend es ist; Es ist in keiner Weise granular, aber wenn Sie auf den srcOrdner in Github klicken, wird er automatisch geladen und gibt Anweisungen zum Auffinden von anderem Code oder anderer Dokumentation. Vergleichen Sie das mit dem Powershell-Repo, nach dem ich ein Beispiel gesucht habe, das aber keine zu Vim äquivalenten Dateien gefunden hat /src/README.txt. (Ein schlechtes Zeichen für ein Projekt mit 988 Tausend LOC!)

Zu den Dingen, die Sie möglicherweise grafisch darstellen oder dokumentieren möchten, gehören:

  • Konzeptionelle Programmablauf (Was ist das Programm vollenden , und in welcher Reihenfolge?)
  • Implementierter Programmablauf / Funktionsaufrufgraph (Wie erreicht das Programm seine Ziele? Welche Funktionen werden aufgerufen oder Klassen erstellt?)
  • Welcher Code befindet sich in welchen Dateien? Wie sieht das Organisationsschema aus und nach welchen Regeln bestimmen Sie, wohin eine neue Funktion führt? Wenn Sie ein starkes Organisationsschema haben, ist es auch ohne eine IDE oder ein IDE-ähnliches Feature zum "projektweiten Finden" einfach zu wissen, in welcher Datei nach einer bestimmten Funktion oder Klasse gesucht werden soll.
  • Verwandte, welche Dateien enthalten welche anderen Dateien (bezogen auf einen Funktionsaufrufgraphen)?
  • Welche Klassen erben von welchen anderen Klassen? Was ist der Zweck jeder Klasse?

Wie können Sie diese Diagramme erstellen? Auf Ihrer Ebene und für erste Entwürfe ist Bleistift und Papier wahrscheinlich die beste / schnellste Methode. Wenn Diagramme und Dokumentationen verfeinert werden, können Sie Folgendes untersuchen:

  • Dot / Graphviz, eine Reihe von Programmen zum Generieren von Grafiken aus .dotDateien.
  • LaTeX / TikZ, ein sehr komplexes und ausführliches Tool zum Generieren von Grafiken oder Bildern jeglicher Art - es ist möglicherweise zu umfangreich für Ihre Anforderungen, insbesondere, da alle Knotenpositionierungen manuell vorgenommen werden, sollte jedoch beachtet werden, insbesondere, wenn Sie vorhaben, eine zu schreiben Papier oder ähnliches später.
  • Für C, Gson der egyptHaken in gccund gibt einen .dotAufrufgraphen. Kann automatisiert oder in einen makeBefehl eingebettet werden , was sehr schön ist!
  • In Verbindung damit kann GNU cflownur Textaufrufdiagramme für C generieren. Gleichwertige Tools können für andere Sprachen vorhanden sein, obwohl Sie sich im Allgemeinen möglicherweise von automatisierten Tools entfernen möchten. Wenn Sie das Diagramm nicht manuell erstellen, kann dies Ihr Verständnis des Codes beeinträchtigen oder ein unangemessenes bereitstellen Komplexer Detaillierungsgrad (zu wissen, welche Funktionen aufgerufen werden, printf()ist normalerweise wenig hilfreich).
9999 Jahre
quelle
Ich mache mir große Sorgen um eine gute Dokumentation, aber im Moment habe ich die Dokumentation eingestellt, weil sich mein Code ständig ändert, um neue Algorithmen und Versuche einzuführen, etwas zu tun. Zum Beispiel habe ich bei der kontinuierlichen Erkennung von Codekollisionen mehrmals von der Speicherung vorheriger Positionen in den Body-Klassen auf die Berechnung der vorherigen Position aus der Bewegung des Body umgestellt. Dieser Mangel an Professionalität ist darauf zurückzuführen, dass ich das Ding während des Programmierens entwerfe, weil ich, wenn ich etwas in meiner Physik-Engine entwerfe, überprüfen möchte, ob es tatsächlich möglich ist.
Winter
Ich denke, ich sollte dieses Projekt als experimentell betrachten und es dann mit dem von mir erstellten Prototyp von Grund auf neu schreiben, aber ich habe viel Mühe darauf verwendet, es sauber genug zu halten, ohne alles neu schreiben zu müssen.
Winter
0

Versuchen Sie es mit einem Diagramm, das auf Petri-Netzen basiert. Es ist möglich, das Diagramm auf systematische Weise in Computerprogramme zu übersetzen, und es ist möglich, Diagramme auf hoher Ebene mit Diagrammen auf niedriger Ebene zu integrieren.

Verweise

Netzelemente und Anmerkungen: Eine visuelle Programmiersprache für allgemeine Zwecke (2016). Verfügbar unter https://www.academia.edu/31341292/Net_Elements_and_Annotations_A_General-Purpose_Visual_Programming_Language .

Netzelemente und Anmerkungen für die Computerprogrammierung: Berechnungen und Interaktionen in PDF (2014). Verfügbar unter https://www.academia.edu/26906314/Net_Elements_and_Annotations_for_Computer_Programming_Computations_and_Interactions_in_PDF .

John Frederick Chionglo
quelle