Eine Ebene liegt in Normalform vor, wenn man den Vektor
(1) | |
wobei |
Der Punktoperator ist das Skalarprodukt der Vektoren links und rechts des Operators. Eine Vektorvariable hat in diesem Beitrag einen Pfeil über dem Symbol, oder eine Dächlein wenn der Vektor die Länge 1 hat, also ein Einheitsvektor ist.
Die Gleichung (1) sagt aus, dass das Skalarprodukt des Normalenvektors
Die Berechnungen werden einfacher, wenn man Einheitsvektoren verwenden kann. Ein beliebiger Vektor kann in einen Einheitsvektor transformiert werden, indem man die Komponenten des Vektors durch die Länge des Vektors dividiert:
(2) | ||||||||||
wobei' |
|
Eine Ebene kann in Parameterform notiert werden, wenn man zwei Vektoren
(3) |
Die Variablen a und b sind die Parameter. Jeder beliebige Punkt
Wenn die Ebene in Parameterform vorliegt, wir aber die Normalform benötigen, kann man einfach den Normalenvektor über das Vektorprodukt berechnen:
(4) |
Wenn die beiden Vektoren
Für die Berechnung der Schnittlinie zweier Ebenen gehe ich davon aus, dass die beiden Ebenen in Normalform vorliegen:
(5) | ||
mit |
Die Richtung der Schnittlinie
(6) |
Einen Punkt auf der Schnittgeraden finden wir, indem wir eine dritte Ebene A3 in Parameterform definieren, die senkrecht auf den beiden Ebenen A1 und A2 steht und den Ursprung als Punkt der Ebene enthält. Als Vektoren in der Ebene A3, die wir für die Parameterform benötigen, können wir die Normalenvektoren der Ebenen A1 und A2 verwenden. Daraus erhalten wir folgene Parameterform der Ebene A3:
(7) |
Wenn die beiden Ebenen A1 und A2 parallel sind, also keine Schnittlinie definiert werden kann, haben sie denselben Normalenvektor und die Ebene A3 ist nicht definiert.
Wir müssen nun die beiden Paraemeter s1 und s2 finden. Damit können wir dann den Punkt der Schnittlinie
(8) | |
und |
Damit haben wir zwei Gleichungen für die beiden Unbekannten s1 und s2, die wir leicht lösen können. Ich verwende die Eigenschaft, dass die Normalenvektor Einheitsvektoren sind, sodass ich folgende Vereinfachungen machen kann:
(9) |
Damit erhalte ich für die beiden Parameter:
(10) | |
und |
Nun können wir den Punkt der Schnittgeraden berechnen:
(11) |
Gegeben:
(12) | ||
mit |
Schnittgerade in Parameterform:
(13) |
|
(14) |
| |
(15) |
| |
mit |
Die Schnittgerade kann nur berechnet werden, wenn die beiden Normalenvektoren
Der Linienpunkt
Mit der folgenden interaktiven Animation kann man überprüfen, ob die Intersect-Funktion korrekt funktioniert.
var V3 = { Length: function( v ) { return Math.sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ); }, Scale: function( v, s ) { return [ v[0]*s, v[1]*s, v[2]*s ]; }, Add: function( a, b ) { return [ a[0]+b[0], a[1]+b[1], a[2]+b[2] ]; }, ScalarProd: function( a, b ) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; }, Mult: function( a, b ) { return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; }, }; function InterctionLineOf2Areas( P1, n1, P2, n2 ) { // Computes the parameter form of the intersection line // between the areas given in normal form P1, n1 and P2, n2. // If the areas are parallel, null is returned. // If an intersection line can be computed, it is returned as // ret = { V3 Q, V3 q }, where the parameterform of the intersection line is // x = ret.Q + lambda * ret.q // // require V3.Length(n1) == 1 and V3.Length(n2) == 1 var q = V3.Mult( n2, n1 ); var ql = V3.Length(q); if (ql == 0) { // areas are parallel -> no solution return null; } // normalize q q = V3.Scale( q, 1/ql ); var r = V3.ScalarProd( n1, n2 ); // assert r < 1 var d1 = V3.ScalarProd( P1, n1 ); var d2 = V3.ScalarProd( P2, n2 ); var s1 = (d1 - r * d2) / (1 - r*r ); var s2 = (d2 - r * d1) / (1 - r*r ); var Q = V3.Add( V3.Scale( n1, s1 ), V3.Scale( n2, s2 ) ); return { Q: Q, q: q }; }