Autor Beitrag
catweasel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: 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? :?:

ausblenden volle Höhe 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:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: 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 :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Mo 22.04.13 20:32 
Wo hast du denn Abitur gemacht :shock: 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
ausblenden Quelltext
1:
2:
d1 = A-B  und 
d2 = A-C


Jetzt musst du den Sehstrahl und die Ebene schneiden. Es muss also gelten:

ausblenden 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
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Mo 22.04.13 20:55 
user profile iconXion hat folgendes geschrieben Zum zitierten Posting springen:
Wo hast du denn Abitur gemacht :shock: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 600
Erhaltene Danke: 23


Delphi 7 PE
BeitragVerfasst: Mo 22.04.13 21:00 
user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:

Ich werd mir das aber mal anschauen ob ich verstehe was ihr mir sagen wollt. :)

ich machs mit nem Steigungsdreieck zwischen den punkten und danach setzte ich einen punkt ein... das will ich sagen^^

_________________
Sucht "neueres" Delphi :D
Wer nicht brauch was er hat, brauch auch nicht was er nicht hat!
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Di 23.04.13 09:56 
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
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 :wink:

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 :wink:
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Di 23.04.13 10:12 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
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 :wink:

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 :wink:


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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Di 23.04.13 12:49 
user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Di 23.04.13 14:17 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconcatweasel hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Fr 26.04.13 16:40 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
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 :D 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: 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 :P
Ich habe jetzt nicht herausgefunden, wie ich quadratische Matrizen eingeben kann.
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Fr 26.04.13 23:54 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
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 :P
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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: 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.
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Sa 27.04.13 11:57 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
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.
ausblenden 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:
ausblenden 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.