Autor |
Beitrag |
catweasel
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Mo 22.04.13 20:12
Moin
Ich habe mal eine Frage zur Berechnung von Schnittpunkten. Ich habe schon ein wenig hier im Forum und bei Google herumgesucht, aber nichts (für mich) brauchbares gefunden. Ich muss dazu sagen das ich Mathe nur als Grundkurs in der Oberstufe hatte und bei dem Thema Vektorrechnung auf sehr dünnem Eis gehe.
Es gilt: Alles spielt sich im R3 ab.
Problem: Schnittpunkt von (Halb)gerade und Dreieck
Gegeben ist ein Dreieck, welches durch drei Vektoren eindeutig definiert ist. Es ist garantiert ein echtes Dreieck und auch dessen Normalenvektor ist bekannt.
Auserdem gegeben ist ein Sehstrahl mit einem Ursprung und einer Richtung, ebenfalls (Orts)vektoren.
Wie errechne ich nun den Schnittpunkt von Sehstrahl und Dreieck.
ich denke man muss erst den Schnittpunkt mit der Ebene des Dreiecks feststellen und dann prüfen ob der Punkt von dem Dreieck eingeschlossen wird.
Wie erhalte ich die Halbgerade (aus den zwei Sehstrahlpunkten) und der Ebene (aus den Dreieckspunkten) in einer geeigneten Form; und wie rechne ich damit?
Hier ist auch mal meine Vektor Unit die ich mir zusammngebastelt habe. Wäre cool wenn jemand mal schauen könnte ob das alles so richtig ist. Die Sachen mit dem Kreuzprodukt und so weiter hab ich mir anhnd der Wikipedia zusammengereimt. Ist das so richtig?
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: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215:
| unit UVectorLib;
interface
uses UDataTypes, Math;
function AddScalar(V:T2DVector;S:extended):T2DVector;overload; function AddScalar(V:T3DVector;S:extended):T3DVector;overload; function AddVectors(A,B:T2DVector):T2DVector;overload; function AddVectors(A,B:T3DVector):T3DVector;overload; function AddVectors(A,B:T3DColor):T3DColor;overload; function SubtractVectors(A,B:T2DVector):T2DVector;overload; function SubtractVectors(A,B:T3DVector):T3DVector;overload; function SubtractVectors(A,B:T3DColor):T3DColor;overload; function ScaleVector(V:T2DVector;S:extended):T2DVector;overload; function ScaleVector(V:T3DVector;S:extended):T3DVector;overload; function ScaleVector(V:T3DColor;S:extended):T3DColor;overload; function VMultiply(A,B:T3DVector):T3DVector; function VScaleProduct(A,B:T2DVector):extended;overload; function VScaleProduct(A,B:T3DVector):extended;overload; function VScaleProduct(A,B:T3DColor):extended;overload; function VCrossProduct(A,B:T3DVector):T3DVector; function VLength(V:T2DVector):extended;overload; function VLength(V:T3DVector):extended;overload; function VAngle(A,B:T2DVector):extended;overload; function VAngle(A,B:T3DVector):extended;overload; function VectorMin(A,B:T2DVector):T2DVector;overload; function VectorMin(A,B:T3DVector):T3DVector;overload; function VectorMin(A,B:T3DColor):T3DColor;overload; function VectorMax(A,B:T2DVector):T2DVector;overload; function VectorMax(A,B:T3DVector):T3DVector;overload; function VectorMax(A,B:T3DColor):T3DColor;overload;
function VNormal(Data:TTriangleData):T3DVector;
const VZero : T3DVector = (X:0;Y:0;Z:0); AxisX : T3DVector = (X:1;Y:0;Z:0); AxisY : T3DVector = (X:0;Y:1;Z:0); AxisZ : T3DVector = (X:0;Y:0;Z:1);
implementation
function AddScalar(V:T2DVector;S:extended):T2DVector;overload; begin Result.X := V.X + S; Result.Y := V.Y + S; end;
function AddScalar(V:T3DVector;S:extended):T3DVector;overload; begin Result.X := V.X + S; Result.Y := V.Y + S; Result.Z := V.Z + S; end;
function AddVectors(A,B:T2DVector):T2DVector; begin Result.X := A.X + B.X; Result.Y := A.Y + B.Y; end;
function AddVectors(A,B:T3DVector):T3DVector; begin Result.X := A.X + B.X; Result.Y := A.Y + B.Y; Result.Z := A.Z + B.Z; end;
function AddVectors(A,B:T3DColor):T3DColor; begin Result.R := A.R + B.R; Result.G := A.G + B.G; Result.B := A.B + B.B; Result.A := A.A + B.A; end;
function SubtractVectors(A,B:T2DVector):T2DVector;overload; begin Result := AddVectors(A,ScaleVector(B,-1)); end;
function SubtractVectors(A,B:T3DVector):T3DVector;overload; begin Result := AddVectors(A,ScaleVector(B,-1)); end;
function SubtractVectors(A,B:T3DColor):T3DColor;overload; begin Result := AddVectors(A,ScaleVector(B,-1)); end;
function ScaleVector(V:T2DVector;S:extended):T2DVector;overload; begin Result.X := V.X * S; Result.Y := V.Y * S; end;
function ScaleVector(V:T3DVector;S:extended):T3DVector;overload; begin Result.X := V.X * S; Result.Y := V.Y * S; Result.Z := V.Z * S; end;
function ScaleVector(V:T3DColor;S:extended):T3DColor;overload; begin Result.R := V.R * S; Result.G := V.G * S; Result.B := V.B * S; Result.A := V.A * S; end;
function VMultiply(A,B:T3DVector):T3DVector; begin Result.X := A.X * B.X; Result.Y := A.Y * B.Y; Result.Z := A.Z * B.Z; end;
function VScaleProduct(A,B:T2DVector):extended; begin Result := A.X*B.X + A.Y*B.Y; end;
function VScaleProduct(A,B:T3DVector):extended; begin Result := A.X*B.X + A.Y*B.Y + A.Z*B.Z; end;
function VScaleProduct(A,B:T3DColor):extended; begin Result := A.R*B.R + A.G*B.G + A.B*B.B + A.A*B.A; end;
function VCrossProduct(A,B:T3DVector):T3DVector; begin Result.X := (A.Y*B.Z) - (A.Z*B.Y); Result.Y := (A.Z*B.X) - (A.X*B.Z); Result.Z := (A.X*B.Y) - (A.Y*B.X); end;
function VLength(V:T2DVector):extended; begin Result := sqrt(VScaleProduct(V,V)); end;
function VLength(V:T3DVector):extended; begin Result := sqrt(VScaleProduct(V,V)); end;
function VAngle(A,B:T2DVector):extended;overload; begin Result := RadToDeg(arccos(VScaleProduct(A,B)/(VLength(A)*VLength(B)))); end;
function VAngle(A,B:T3DVector):extended;overload; begin Result := RadToDeg(arccos(VScaleProduct(A,B)/(VLength(A)*VLength(B)))); end;
function VectorMin(A,B:T2DVector):T2DVector;overload; begin Result.X := Min(A.X,B.X); Result.Y := Min(A.Y,B.Y); end;
function VectorMin(A,B:T3DVector):T3DVector;overload; begin Result.X := Min(A.X,B.X); Result.Y := Min(A.Y,B.Y); Result.Z := Min(A.Z,B.Z); end;
function VectorMin(A,B:T3DColor):T3DColor;overload; begin Result.R := Min(A.R,B.R); Result.G := Min(A.G,B.G); Result.B := Min(A.B,B.B); Result.A := Min(A.A,B.A); end;
function VectorMax(A,B:T2DVector):T2DVector;overload; begin Result.X := Max(A.X,B.X); Result.Y := Max(A.Y,B.Y); end;
function VectorMax(A,B:T3DVector):T3DVector;overload; begin Result.X := Max(A.X,B.X); Result.Y := Max(A.Y,B.Y); Result.Z := Max(A.Z,B.Z); end;
function VectorMax(A,B:T3DColor):T3DColor;overload; begin Result.R := Max(A.R,B.R); Result.G := Max(A.G,B.G); Result.B := Max(A.B,B.B); Result.A := Max(A.A,B.A); end;
function VNormal(Data:TTriangleData):T3DVector; var P,Q : T3DVector; begin P := SubtractVectors(Data.B,Data.A); Q := SubtractVectors(Data.C,Data.A); Result := VCrossProduct(P,Q); end;
end. |
Vielen Dank für die Hilfe.
Cheers,
Catweasel
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mo 22.04.13 20:27
Zitat: |
Halbgerade (aus den zwei Sehstrahlpunkten)
|
du kennst die punkte und willst deren "Gleichung" aufstellen, dann
ist die Steigung = (p2.y-p1.y)-(p2.x-p1.x)
und da das ganze nicht immer durch den Urpsrung geht, musst du noch die "Hochsetzung" ausrechnen.. hierzu setzte einfach ein punkt ein zB.
p2.y = Steigung (s.O) *p2.x + Hochsetzung;
Dann hast du deine Formel
Allgemein also:
f(x) = ( (p2.y-p1.y)-(p2.x-p1.x) )*x + (p2.y - ( (p2.y-p1.y)-(p2.x-p1.x) )*p2.x)
das gilt allerdings nur im 2 Dimensionalen raum (und hat nichts mit der Vektorrechnung zu tun).. aber 3 D ist ja eigentlich nichts anderes als
3* 2D (X*Y*Z = X*Y + X*Z + Y*Z in der graphischen Darstellung)
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
Xion
Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mo 22.04.13 20:32
Wo hast du denn Abitur gemacht Vektorrechnung war bei uns ausführlich für alle Pflicht.
Zum Thema:
Du hast den Sehstrahl s als dreidimensionalen Richtungsvektor und den Augenpunkt (also dort, wo der Sehstral anfängt) als sp.
Du hast das Dreieck A, B, C durch diese 3 Punkte gegeben (also dreidimensionale Ortsvektoren).
Daraus berechnest du die Richtungsvektoren der Ebene, in dem das Dreieck liegt, durch
Quelltext 1: 2:
| d1 = A-B und d2 = A-C |
Jetzt musst du den Sehstrahl und die Ebene schneiden. Es muss also gelten:
Quelltext 1:
| sp + alpha*s = A + beta*d1 + gamma*d2 |
Da das alles dreidimensionale Vektoren sind, hast du 3 Gleichungen mit 3 Unbekannten (alpha, beta, gamma), also kein Problem.
Jetzt musst du nur noch gucken: Gilt
Quelltext 1: 2: 3:
| 0<=beta<=1 und 0<=gamma<=1 und 0<=beta+gamma<=1 |
so ist der (Schnitt-)Punkt im Dreieck. Sonst nicht.
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Zuletzt bearbeitet von Xion am Di 23.04.13 15:55, insgesamt 1-mal bearbeitet
|
|
catweasel
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Mo 22.04.13 20:55
Xion hat folgendes geschrieben : | Wo hast du denn Abitur gemacht Vektorrechnung war bei uns ausführlich für alle Pflicht. |
Also ich hab in Frankfurt am Main Abitur gemacht (Ziehenschule). Das war 1998. Ich hatte Mathematik als Grundkurs und die Inhalte waren wie folgt:
Grundkurs: Vektoren R2 Addieren und mit Skalaren multiplizieren.
Leistungskurs : Vektoren R2 und R3, Linearkombinationen, Matrizen, Vektorräume, Schnittpunte berechnen und vieles tolles mehr.
Bei uns wurde das schon ausgebreitet, aber eben nur im Leistungskurs. In anderen Fächern wie Physik die man gemeinsam mit LK Schülern hatte konnte man den Niveauunterschied deutlich sehen. Wir (GK Schüler kamen uns damals schion wie dumm gehalten vor). Der LK hatte Vektoren ein ganzes Jahr behandelt (12) und wir nur ein halbes Jahr (12/2) Wir hatten im 12/1 noch Analysis. In 13/1 kam dann Stochastik und 13/2 war ein bunter Mix von allen als Vorbereitung aufs Abi.
Ich werd mir das aber mal anschauen ob ich verstehe was ihr mir sagen wollt.
Cheers,
Catweasel
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
IhopeonlyReader
Beiträge: 600
Erhaltene Danke: 23
Delphi 7 PE
|
Verfasst: Mo 22.04.13 21:00
_________________ Sucht "neueres" Delphi
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
|
|
jfheins
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Di 23.04.13 09:56
IhopeonlyReader hat folgendes geschrieben : | ich machs mit nem Steigungsdreieck zwischen den punkten und danach setzte ich einen punkt ein... das will ich sagen^^ |
Ja, leider ist deine Formel falsch:
Zitat: | Steigung = (p2.y-p1.y)-(p2.x-p1.x) |
Da gehört eigentlich eine Division hin
Abgesehen davon ist die Lösung aus zwei Gründen von nachteil:
1. Du bekommt Probleme wenn eine Linie mal exakt senkrecht ist. Dann fliegt dir die Division durch Null um die Ohren. Klar, hier könnte man Sonderfälle einführen, aber das wird dann unnötig komplex.
2. Zitat: | aber 3 D ist ja eigentlich nichts anderes als 3* 2D |
Doch, schon. Selbst wenn sich eine Gerade und ein Dreieck in den drei Projektionen (XY, XZ und YZ) schneiden, heißt das noch lange nicht, dass die sich auch in 3D schneiden.
Vektorrechnung ist hier schon das richtige Werkzeug, Steigungsdreiecke nicht. Nichts für ungut
|
|
catweasel
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Di 23.04.13 10:12
jfheins hat folgendes geschrieben : | IhopeonlyReader hat folgendes geschrieben : | ich machs mit nem Steigungsdreieck zwischen den punkten und danach setzte ich einen punkt ein... das will ich sagen^^ |
Ja, leider ist deine Formel falsch:
Zitat: | Steigung = (p2.y-p1.y)-(p2.x-p1.x) |
Da gehört eigentlich eine Division hin
Abgesehen davon ist die Lösung aus zwei Gründen von nachteil:
1. Du bekommt Probleme wenn eine Linie mal exakt senkrecht ist. Dann fliegt dir die Division durch Null um die Ohren. Klar, hier könnte man Sonderfälle einführen, aber das wird dann unnötig komplex.
2. Zitat: | aber 3 D ist ja eigentlich nichts anderes als 3* 2D | Doch, schon. Selbst wenn sich eine Gerade und ein Dreieck in den drei Projektionen (XY, XZ und YZ) schneiden, heißt das noch lange nicht, dass die sich auch in 3D schneiden.
Vektorrechnung ist hier schon das richtige Werkzeug, Steigungsdreiecke nicht. Nichts für ungut |
Das Gefühl habe ich auch gehabt. Wenn zwei Geraden nicht parallel sind schneiden sie sich garantiert im R2, aber im R3 können sie auch Windschief sein. Auch bei der Rotation gibts da Unterschiede. Im R2 ist eine Rottion durch einen Winkel eindetig bestimmt. IM R3 brauche ich noch eine Achse um die rotiert werden soll.
Wobei es abera auch in der Vektorrechnung Undefiniertes gibt. Beispielsweise die Richtung des Nullvektors. Solche Sonderfälle muss man auch hier abfangen....
Ich habe mal ein bischen gegoogelt und festgestellt das Vektorrotation mit Matrizen zu bewerkstelligen ist. Ich werd mal schauen was ne Matrix ist und ob ich das verstehe.. falls nich, frag ich nochmal.
Cheers,
Catweasel
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
jfheins
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Di 23.04.13 12:49
catweasel hat folgendes geschrieben : | Wobei es aber auch in der Vektorrechnung Undefiniertes gibt. Beispielsweise die Richtung des Nullvektors. Solche Sonderfälle muss man auch hier abfangen.... |
Jein. Einerseits hast du recht, solche Fälle gibt es auch in der Vektorrechnung. Aber diese basieren eigentlich nur auf der Problemstellung, nicht dem Verfahren an sich.
Schau dein Problem an: Eine wichtige Sache hast du bereits ausgeschlossen:
Zitat: | Es ist garantiert ein echtes Dreieck |
So Sonderfälle, die mit noch einfallen:
1. Es gibt eine Lösung
2. Es gibt keine Lösung, weil der Schnittpunkt nicht im Dreieck liegt.
3. Es gibt keine Lösung, weil der Sichtstrahl parallel zur Ebene liegt.
4. Es gibt keine Lösung weil der Sichtstrahl zwar vollkommen in der Ebene liegt, aber das Dreieck nicht berührt.
5. Es gibt beliebig viele Lösungen, weil der Sichtstrahl in der Ebene liegt und das Dreieck schneidet.
Bei Fall 3, 4 und 5 wird dein LGS singulär, du brauchst also nichts weiter machen. (Es sei denn, du willst Speziallösungen wie für Fall 4 "Ein Punkt des Dreiecks der am nächsten liegt")
Die Spezialfälle, die hier auftreten, sind also weniger dem Werkzeug (Vektorrechnung) geschuldet als dem eigentlichen Problem. Das ist es ungefähr, was ich ausdrücken wollte.
Ach, und eine Sache wäre da auch noch: Du brauchst kein LGS lösen, das geht auch ohne. Eine andere Gleichung die das gleiche Ergebnis liefert, lässt sich direkt auflösen:
Betrachte die Ebene in Hesse-Normalform. Sie hat dann einen Normalenvektor und einen Abstand zum Ursprung. (Hier solltest du den Ursprung auf den Aufpunkt des Strahls legen) Dann ergibt sich:
t = (d-nP)/(nP)
mit der Ebenen(Dreiecks)normalen n, dem Ursprung des Strahls P und der Richtung des Strahls d.
t ist dann der Parameter des Strahls. Vorher musst du prüfen ob np gleich Null ist.
Siehe hier die ersten zwei Seiten: www.cs.washington.ed...gle_intersection.pdf
|
|
catweasel
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Di 23.04.13 14:17
jfheins hat folgendes geschrieben : | catweasel hat folgendes geschrieben : | Wobei es aber auch in der Vektorrechnung Undefiniertes gibt. Beispielsweise die Richtung des Nullvektors. Solche Sonderfälle muss man auch hier abfangen.... |
Jein. Einerseits hast du recht, solche Fälle gibt es auch in der Vektorrechnung. Aber diese basieren eigentlich nur auf der Problemstellung, nicht dem Verfahren an sich.
Schau dein Problem an: Eine wichtige Sache hast du bereits ausgeschlossen:
Zitat: | Es ist garantiert ein echtes Dreieck |
So Sonderfälle, die mit noch einfallen:
1. Es gibt eine Lösung
2. Es gibt keine Lösung, weil der Schnittpunkt nicht im Dreieck liegt.
3. Es gibt keine Lösung, weil der Sichtstrahl parallel zur Ebene liegt.
4. Es gibt keine Lösung weil der Sichtstrahl zwar vollkommen in der Ebene liegt, aber das Dreieck nicht berührt.
5. Es gibt beliebig viele Lösungen, weil der Sichtstrahl in der Ebene liegt und das Dreieck schneidet.
Bei Fall 3, 4 und 5 wird dein LGS singulär, du brauchst also nichts weiter machen. (Es sei denn, du willst Speziallösungen wie für Fall 4 "Ein Punkt des Dreiecks der am nächsten liegt")
Die Spezialfälle, die hier auftreten, sind also weniger dem Werkzeug (Vektorrechnung) geschuldet als dem eigentlichen Problem. Das ist es ungefähr, was ich ausdrücken wollte.
Ach, und eine Sache wäre da auch noch: Du brauchst kein LGS lösen, das geht auch ohne. Eine andere Gleichung die das gleiche Ergebnis liefert, lässt sich direkt auflösen:
Betrachte die Ebene in Hesse-Normalform. Sie hat dann einen Normalenvektor und einen Abstand zum Ursprung. (Hier solltest du den Ursprung auf den Aufpunkt des Strahls legen) Dann ergibt sich:
t = (d-nP)/(nP)
mit der Ebenen(Dreiecks)normalen n, dem Ursprung des Strahls P und der Richtung des Strahls d.
t ist dann der Parameter des Strahls. Vorher musst du prüfen ob np gleich Null ist.
Siehe hier die ersten zwei Seiten: www.cs.washington.ed...gle_intersection.pdf |
Danke für die Tips Ich werde mir den Link heute Abend auf jeden Fall ansehen.
Zu den Sonderfällen, ich hab das so vor:
Ist die Kamera innherhalb eines Objekts wird es aus der Liste entfernt
Aus der Liste der restlichen Objekte werden erst einmal alle herausgeschmissen bei welcher der Sehstrahl nicht die BoundingBox trifft.
Danach werden bei allen verbliebenen Objekten diejenigen herausgeschmissen die einen Winkel von mehr als 90° zum Kameravektor haben (backface culling).
Danach wird das getroffene Polygon ermittelt, oder falls zwar die BoundingBox, nicht aber das Objekt getroffen wird statt dem PolygonIndex nur 'void' gespeichert.
Wenn ich dann weiss welcher Sehstrahl welches Polygon trifft kann ich dann ein Bild entsprechend einfärben.. Ein Raytracer/Renderer eben
Damit sollten die Sonderfälle in der Pipeline eigentlich vorher ausgesiebt sein, oder?
Kein Sonderfälle 3 und 4, da backface culling.
Kein Sonderfall 5 weil keine Kamera im Objekt (Grenzfläche zähle ich als "innen")
Die Fälle 1 und 2 sind die zu erwartenden Ergebnisse. Wenn der Sehstrahl nunmal nichts trifft kann man nix machen. Ich färbe das dann eben mit dem Szenenhintergrund.
Oder hab ich was wesentliches übersehen?
Catweasel
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
jfheins
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Di 23.04.13 14:40
Okay, in dem Fall hilft dir wahscheinlich auch das hier noch ein bisschen: www15.in.tum.de/Teac...a/Florian_Ferstl.pdf
Oder ansonsten halt nach "Strahl dreieck schnittpunkt" googlen, da kommen eigentlich viele gute Ergebisse.
|
|
catweasel
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Fr 26.04.13 16:40
jfheins hat folgendes geschrieben : | Okay, in dem Fall hilft dir wahscheinlich auch das hier noch ein bisschen: www15.in.tum.de/Teac...a/Florian_Ferstl.pdf
Oder ansonsten halt nach "Strahl dreieck schnittpunkt" googlen, da kommen eigentlich viele gute Ergebisse. |
Wow Die links haben mir sehr weitergeholfen das Problem zu erkennen. Dank des ersten Links habe ich festgestellt das es bei der Schnittpunktberechnung von Halbgerade und Dreieck auf das Lösen eines LGS hinausläuft. Auch der zweite Link überzeugte mich von der Tatsache das man eine Ebene mit einem LGS darstellt. Du hattest zwar geschrieben das adas auch ohne geht, aber das habe ich noch nicht so richtig geblickt. ich werde mich auch noch mal mit der Hesseschen Normalenform beschäftigen.. Ist aber Ok. Ich will ja was lernen
Ein wenig Recherche brachte mich zu fokgendem Link
www.delphipraxis.net...oesen-eines-lgs.html
Daraus habe ich gelernt das man wohl nicht darum herum kommt sich mit Matritzen zu beschäftigen wenn man ein LGS lösen möchte. Und da ich von Matritzen absolut keine Ahnung habe, verstehe ich jetzt zumindest warum mir kein Lösungsansatz einfallen will/kann.
Also schnell mal informiert was so eine Matrix ist: de.wikipedia.org/wik...rix_%28Mathematik%29
der Anfang bis zur Matrixmultiplikation ist ja noch sehr eingängig, aber adnn wirds schon ein wenig seltsam.
Ich habe jetzt erstmal versucht eine Matrix als Klasse zu implementieren.
Dazu gibts auch ne kleine Testumgebung. Die Matrixelemente kann man direkt in dem Grid bearbeiten und bei Doppelklick auf den Maxtrixnamen kann man die Anzahl der Zeilen und Spalten ändern. Das "elements" hinter der einen Multiplikation und Division bedeutet das nicht (wie ich herausgefunden habe) die richtige Matrixmultiplikation gement ist, sondern zwei gleich grosse Matritzen werden Elementweise multipliziert. (Keine Ahnung wie man das nennt).
Das Transponieren kann man auf zwei Arten machen. Entweder die Klasse transponieren, dann verhält sie sich wie transponiert, ohne alle Daten ändern zu müssen. Oder man transponiert die Daten. Dann werden alle Elemente tatsächlich vertauscht.
Ist das so richtig, oder hat sich hier bereits ein (logischer) Fehler in den Code eingeschlichen?
Cheers,
Catweasel
Einloggen, um Attachments anzusehen!
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
jfheins
Beiträge: 918
Erhaltene Danke: 158
Win 10
VS 2013, VS2015
|
Verfasst: Fr 26.04.13 18:32
Naja, es sind da schon noch ein paar Fehlerchen drin ^^
A*B ergibt eigentlich
12 -6
39 -12
und nicht vier mal 42.
Die Determinante ist nur für quadratische Matrizen definiert. Es scheint als hättest du 42 so als Standardergebnis drin
Ich habe jetzt nicht herausgefunden, wie ich quadratische Matrizen eingeben kann.
|
|
catweasel
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Fr 26.04.13 23:54
jfheins hat folgendes geschrieben : | Naja, es sind da schon noch ein paar Fehlerchen drin ^^
A*B ergibt eigentlich
12 -6
39 -12
und nicht vier mal 42.
Die Determinante ist nur für quadratische Matrizen definiert. Es scheint als hättest du 42 so als Standardergebnis drin
Ich habe jetzt nicht herausgefunden, wie ich quadratische Matrizen eingeben kann. |
Ja, 42 ist bei mir noch die Dummy Antwort für das nicht-geblickte
Ich bin gerade noch am überlegen wie ich die Multiplikationen und Summenbildung machen soll (Schleifen). Der Strassen-Algorhytmus scheint mir ein wenig zu extrem für diesen Zweck.
Bei der Determinanten werde ich die Matritzen noch auf Quadratur pfüfen. Guter Tip
Wenn du auf den Matritzennamen klickst sollte eine InputBox aufgehen. Dann einfach Spalten,Zeile eingeben (also "2,2", oder "47,11").
Ich werde morgen nochmal dran arbeiten. dann gibts auch ne Version ohne 42
Cheers,
Catweasel.
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
Mathematiker
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Sa 27.04.13 10:50
Hallo,
ich habe gerade etwas mit Deinem Programm herumgespielt.
Da funktioniert aber einiges noch nicht. Möchte ich zwei Matrizen addieren oder subtrahieren, kommt sofort eine Fehlermeldung. Das ist auch kein Wunder, da man nur Matrizen mit gleichen Zeilen- und Spaltenzahlen addieren und subtrahieren kann.
Wie kann ich eigentlich eine andere Matrix und deren Rang eingeben?
Warum beim Multiplizieren/Dividieren der Matrixelemente ebenfalls die Fehlermeldung kommt, musst Du noch prüfen.
Nebenbei: Was verstehst Du unter der Division A / B zweier Matrizen?
Zur Matrizenmultplikation:
Das Element c(ij) des Matrizenproduktes C = A·B ergibt sich als skalares Produkt des i.ten Zeilenvektors von A mit dem j.ten Spaltenvektor von B; Voraussetzung: Spaltenzahl von A = Zeilenzahl von B
Irgendwelche komplizierten Algorithmen sind da nicht notwendig.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var i,j,k: byte; h: double; begin if Eingabe then for i:=1 to mAkt do for j:=1 to nAkt do begin h:=0; for k:=1 to lAkt do h:=h+A[i,k]*B[k,j]; C[i,j]:=h; end; end; |
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
catweasel
Beiträge: 487
Erhaltene Danke: 1
Win 7 64bit
Delphi 7 Second Sedition V7.2
|
Verfasst: Sa 27.04.13 11:57
Mathematiker hat folgendes geschrieben : | Hallo,
ich habe gerade etwas mit Deinem Programm herumgespielt.
Da funktioniert aber einiges noch nicht. Möchte ich zwei Matrizen addieren oder subtrahieren, kommt sofort eine Fehlermeldung. Das ist auch kein Wunder, da man nur Matrizen mit gleichen Zeilen- und Spaltenzahlen addieren und subtrahieren kann.
Wie kann ich eigentlich eine andere Matrix und deren Rang eingeben?
Warum beim Multiplizieren/Dividieren der Matrixelemente ebenfalls die Fehlermeldung kommt, musst Du noch prüfen.
Nebenbei: Was verstehst Du unter der Division A / B zweier Matrizen?
Zur Matrizenmultplikation:
Das Element c(ij) des Matrizenproduktes C = A·B ergibt sich als skalares Produkt des i.ten Zeilenvektors von A mit dem j.ten Spaltenvektor von B; Voraussetzung: Spaltenzahl von A = Zeilenzahl von B
Irgendwelche komplizierten Algorithmen sind da nicht notwendig.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var i,j,k: byte; h: double; begin if Eingabe then for i:=1 to mAkt do for j:=1 to nAkt do begin h:=0; for k:=1 to lAkt do h:=h+A[i,k]*B[k,j]; C[i,j]:=h; end; end; |
Beste Grüße
Mathematiker |
Ja, Addition/Subtraktion und die elementweise multiplikation/division funktioniert nur mit gleichgrossen Matritzen. Das muss ich noch abfangen, stimmt.
Was meinst du mit "Rang"? Wenn du auf den Matrixnamen Doppelklickst, kannst du die Dimensionen ändern. Meinst du das?
unter der Division von Matritzen verstehe ich z.b:
Delphi-Quelltext 1: 2:
| 5 3 dividiert durch 1 2 ergibt 5 1,5 8 10 4 5 2 2 |
Also elementweises Dividieren.
Ein wenig Suche hat mich drauf gebracht das ich die "andere" Divison streichen kann, gubts nich:
www.tm-mathe.de/Them...division__vorsi.html
Danke für den Tip zur Implementierung der Multiplikaton. Ich werd mich heute Abend nochmal dransetzen
Cheers,
Catweasel
_________________ Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
|
|
|