[OpenSource] SharpMath 1.14.7 - Mathematikbibliothek

    • Release
    • Open Source

    Es gibt 43 Antworten in diesem Thema. Der letzte Beitrag () ist von Trade.

      [OpenSource] SharpMath 1.14.7 - Mathematikbibliothek

      Name:
      SharpMath

      Beschreibung:
      SharpMath ist eine Mathebibliothek, die ich geschrieben habe, um mich sehr ausführlich in Vektoren und Matrizen einzuarbeiten. Daraus wurde dann ein bisschen mehr, sodass die Library neben Vektoren und Matrizen noch einen ExpressionParser, einen Solver für lineare Gleichungssysteme und einen Canvas beinhaltet.
      Ich habe sehr auf Abstraktion und generische Extensions gesetzt, damit es leicht fällt, entsprechend selber Unterklassen zu implementieren, die auf den Interfaces aufbauen.

      Die Projektmappe enthält das Hauptprojekt, ein Komponententestprojekt sowie mehrere Beispielanwendungen, wo verschiedenste Komponenten mit einem User Interface getestet werden. Ich habe in SharpMath.3DTest die ganzen Projektionen mittels der Matrix4x4 und Vector4-Struktur implementiert. (Das läuft da über GDI+, also nicht wundern. Mir ist natürlich durchaus bewusst, dass man das so nie verwenden würde, da es ja DirectX etc. gibt, aber somit hatte ich ein praktisches Beispiel und etwas kleines für's Showcase.)
      Inspiriert wurde ich auch durch @Artentus ' MathUtils.

      Screenshot(s):







      Verwendete Programmiersprache(n) und IDE(s):
      C#, Visual Studio Enterprise und Visual Studio Express

      Systemanforderungen:
      .NET-Framework 4.0

      Download(s):
      github.com/ProgTrade/SharpMath/releases ... oder im Anhang ...

      Lizenz/Weitergabe:
      OpenSource, MIT License
      github.com/ProgTrade/SharpMath

      ToDo:
      - Konvexe Hülle bei den Polygonen (bin am QuickHull-Algorithmus gescheitert.^^)
      - ExpressionTree
      - Canvas verbessern
      - Canvas3D
      - Weitere Komponententests

      Es gibt noch ein paar Punkte, die fertiggemacht werden müssen. Dazu gehören noch ein paar fehlende UnitTests für die Matrizen. Quaternionen sind btw nicht implementiert, da ich mich damit noch gar nicht beschäftigt habe.
      Soweit ich die Bibliothek getestet habe, sollte aber alles funktionieren und zumindest grundlegend implementiert sein.
      Solltet Ihr Fehler finden, dann meldet diese oder sendet einen Issue bzw. PullRequest auf GitHub. ;)

      Ein Dankeschön geht an @~blaze~, der mit seinem riesigen Wissen zur Seite stand und an @Nikx für die Implementierung des Canvas.
      Viel Spaß, ich freue mich auf konstruktive Kritik.
      Dateien
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

      Dieser Beitrag wurde bereits 12 mal editiert, zuletzt von „Trade“ () aus folgendem Grund: Update auf Version 1.14.7

      Update auf Version 0.5.3
      • Implemented IEquatable<T> in Vector, Point and Matrix
      • Implemented custom, typified Clone-method instead of the one that ICloneable provides
      • Implemented all operators (+, -, *, ...) in the available base classes
      • Added methods Add and Subtract to Matrix and therefore abstracted the operators in the derived classes
      • Renamed Algorithm to Algorithms and made it static
      • Made FloatingNumber static
      • Added a class FloatingNumberExtensions that contains extensions for float and double to compare values
      • Small changes and improvements, especially to the documentation

      Viel Spaß mit dem neuen Update. Feedback ist weiterhin erwünscht.
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      Sehr "schöne" Library, scheint auch alles soweit ich das beurteilen kann zu funktionieren :D
      Was ich schön fände, wäre eine Differenzierung gegenüber anderen, ähnlichen Libraries - also Features, welche die meisten von denen nicht zur Verfügung stellen. Aber generell schon mal ein sehr guter Anfang mit guter Grundstruktur, solidem Codestil und ausführlicher Dokumentation :thumbup:
      Habe auch gleich mal nen Pull-Request mit ein paar Änderungen gemacht - schau mal rein ;)
      Ohohoh schick schick, find ich gut :) . Besonders Polygon & .Contains. Sehr praktisch. Was du noch machen könntest wäre eine Überladung mit .Contains(Point, Matix3x3). Und vielleicht die Klassen noch mit .TranslatePoints/Vectors(), .Skew(), .Mirror() (ggf. noch Zoom()) ausstatten.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Gonger96“ ()

      :?: wenn ich mal doof dazwischen-fragen darf: Wie kann man double Line2D.Offset verstehen?
      Nach meim Verständnis müsste ein Offset x- und y-Komponente aufweisen.

      ach, und das hier ist glaub suboptimal:

      C#-Quellcode

      1. public Line2D(Point2D a, Point2D b) {
      2. var line = FromPoints(a, b);
      3. Slope = line.Slope;
      4. Offset = line.Offset;
      5. }
      6. public static Line2D FromPoints(Point2D a, Point2D b) {
      7. var vectorA = a.PositionVector;
      8. var vectorB = b.PositionVector;
      9. var slope = (vectorB.Y - vectorA.Y) / (vectorB.X - vectorA.X);
      10. var offset = vectorA.Y - (slope * vectorA.X); // Insert a point
      11. return new Line2D(slope, offset);
      12. }
      bei Line2D(Point2D a, Point2D b) werden folglich 2 Objekte erstellt: Erstmal erstellt der Konstruktor natürlich sich selbst, aber in FromPoints noch eine Instanz, deren Werte werden übernommen, die zweit-Instanz verfällt dann aber.
      Macht praktisch nix aus, aber ich glaub es ginge auch mehr straight-forward.

      Ich habe das mal verschoben, hier passt das besser rein. ~Trade

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Trade“ ()

      Das ist einfach die Verschiebung der Geraden, also das ​t in ​mx + t.

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      @ErfinderDesRades Habe Deinen Edit gerade gesehen, stimmt, das ist suboptimal. Ich werde das entsprechend vertauschen, wenn ich die Methode nicht sogar ganz entferne.
      @nafets Danke. :) Das Refactoring hat anscheinend nicht ganz funktioniert, weil ein UnitTest nicht angepasst wurde, aber das macht nichts, kann man ja ändern. Ich werde den PullRequest mergen und dann die Tage ein Update raushauen, je nachdem, wie das mit dem Polygon.ContainsPoint noch ausgeht.
      @Gonger96 Dankeschön. Ich werde mal nachforschen und schauen, dass ich das implementiere.

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      ich trau mich kaum zu fragen, aber was bringt einen dazu, solche Kommentare zu verfassen?

      C#-Quellcode

      1. /// <summary>
      2. /// Gets or sets the slope of the <see cref="Line2D" />.
      3. /// </summary>
      4. public double Slope { get; set; }
      Angenommen, der Sinn von Kommentaren sei, etwas zu erklären - Was erklärt dieser Kommentar? ;(
      (Unter Erklärung verstehe ich, dass dass Erklärte nach Lektüre der Erklärung klarer ist als vorher)



      Das kann glaub auch weg:

      C#-Quellcode

      1. public Matrix Zero => new Matrix(RowCount, ColumnCount);
      Wenn man eine neue Matrix will, soll man halt mit new eine erstellen.
      Bei einer Objekt-Methode Zero() denkt man, sie würde irgendetwas mit dem Objekt machen, aber tut sie ja garnet.
      Oder vlt. GetZeroClone() nennen, falls man tatsächlich sowas häufig braucht.



      eine Bitte: Wärs evtl möglich, auf FW4.5 runterzugehen, und auf c#5?

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

      ErfinderDesRades schrieb:

      aber was bringt einen dazu, solche Kommentare zu verfassen?
      Guidelines von Microsoft? Was soll man da großartig erklären? Trotzdem gehört es dazu, das zu dokumentieren.

      ErfinderDesRades schrieb:

      Das kann glaub auch weg:
      [...]
      Wenn man eine neue Matrix will, soll man halt mit new eine erstellen.
      Stimmt, danke.

      ErfinderDesRades schrieb:

      eine Bitte: Wärs evtl möglich, auf FW4.5 runterzugehen, und auf c#5?
      Das Framework ist bereits .NET 4.0(?). Und nein, das bleibt C#6. ;) Wenn es da schon so geniale Features gibt, werde ich nicht auf die verzichten und extra was runterschrauben. Und ein Upgrade von VS tut doch echt nicht weh.

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      @Trade: Bitte, Bitte, Bitte, ändere deine ganzen Geometry-Klassen zu structs.
      Matrizen, Vektoren, Linien, sind alle immutable. Es gibt einen Grund, warum in Unity, XNA, MonoGame und Unreal diese Basis-Typen als Struct implementiert sind.
      docs.unity3d.com/ScriptReference/Vector3.html
      docs.unity3d.com/ScriptReference/Matrix4x4.html
      github.com/mono/MonoGame/blob/…Game.Framework/Vector3.cs
      github.com/mono/MonoGame/blob/…oGame.Framework/Matrix.cs
      docs.unrealengine.com/latest/I…e/Math/FVector/index.html
      docs.unrealengine.com/latest/I…e/Math/FMatrix/index.html

      Denn dann kannst du deine Zero-Matrix auch so aufbauen:

      C#-Quellcode

      1. public static Matrix Zero {get;} = new Matrix();

      Statt bei jedem Aufruf der Zero-Property ein neues Objekt zu erzeugen (die Garbage-Collection mag das garnicht).
      @AliveDevil Das Problem ist, dass ich die Architektur anders hochgezogen habe. Ich habe sehr auf Vererbung und damit einfache Erweiterung gesetzt und das geht mit Strukturen nicht, auch wenn ich wusste, dass diese besser geeignet sind.
      So müsste ich halt dann mit lauter Extensions ran.
      Aber gut, das scheint in der Tat so zu sein. Ich werde dann diese Architektur in dem betreffenden Klassen nochmal neu aufbauen. Eine Vorlage habe ich ja schon.

      @Gonger96 Und wie genau? Ich sah dafür nur den Gauss-Jordan-Algorithmus, um das zu lösen.
      Definiere 'Templates'.

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      Achso. So hatte ich auch die Determinante umgesetzt. Bis zu einer festen Größe mit Vorlagen, dann mit der LaplaceExpansion.
      Danke, ich werd's mir mal in GCL anschauen und übersetzen.

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      Was ich mir noch wünschen würde für Matrizen wäre:
      - Invertierung
      Also die Berechnung von A^-1, sodass gilt
      A*A^-1=I

      - Determinante für irgendeine nxn Matrize rekursiv mit dem Laplace'schen Entwicklungssatz
      de.wikipedia.org/wiki/Determin…acescher_Entwicklungssatz

      - Diagonalisierung von Matrizen (Eigenwert und Eigenvektorbestimmung) und damit verbunden Grenzwerte für A^n mit n->unendlich

      - Faktorisierung in A=L*U
      Kann auch zur Lösung von Ax=b dienen, manchmal performanter

      - Kern einer Matrix
      Wird benötigt um die vollständige Lösung anzugeben

      - Kofaktormatrix berechnen
      Alternativer Weg um eine Inverse zu berechnen

      8-) faxe1008 8-)

      faxe1008 schrieb:

      - Invertierung
      - Determinante für irgendeine nxn Matrize rekursiv mit dem Laplace'schen Entwicklungssatz
      - Kofaktormatrix berechnen
      Das ist doch schon implementiert.

      Das mit der Faktorisierung und dem Kern schaue ich mir mal an. ^^
      Edit: Der Kern scheint sich relativ gut berechnen zu lassen, denn lineare GLeichungssystem kann SharpMath ja lösen.
      Ich bin allerdings eh gerade dabei alles umzuschreiben und haue gerade die gesamte Architektur auf den Kopf, da ich alles als struct handhabe.

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      @Trade Ich fände noch eine QR-Zerlegung(bzw. die bereits angesprochenen Transformationen) von Matrizen gut - da muss man nicht "Gaussen". ^^
      Auch ganz geil wären Vorlagen für Ausgleichsprobleme.

      Trade schrieb:

      haue gerade die gesamte Architektur auf den Kopf, da ich alles als struct handhabe.
      Wobei ich infrage stelle, ob eine Matrix eine Struct sein sollte.
      Die WinForms-Matrix zumindest ist eine Class, während die Wpf-Matrix eine Struct ist.
      Und Immutable sind diese Dinge nicht, weder Matrix noch Points noch Vectors.

      AliveDevil sagt es gebe einen Grund dafür (und ausser bei Matrix widerspreche ich gar nicht), aber welcher ist es?