So berechnen Sie das VektorkreuzproduktAus der Dokumentation geht hervor, dass der *-Operator ein Kreuzprodukt und ;* ein Skalarprodukt ausführt. Ich möchte ein Kreuzprodukt verwenden, um die Vektornormale zu einem Paar bekannter Vektoren wie folgt zu bestimmen:
p1 = [1, 2, 4];
p2 = [2, 1, 4];
p3 = [2, 2, 4];
v1 = p3 - p1;
v2 = p2 - p1;
xProd = v1*v2;
3 Punkte definieren eine Ebene, zwei Vektoren aus diesen Punkten bewirken dasselbe, das Kreuzprodukt sollte den Normalenvektor dieser Ebene ergeben. Das Problem scheint darin zu liegen, dass die Dimensionen der beiden zu multiplizierenden Matrizen (v1 und v2) nicht übereinstimmen – nRows(v1) sollte gleich nCols(v2) sein. Ich kann dies manuell mit einer vereinfachten Formel für Vektorkreuzprodukte implementieren, aber weiß jemand, wie man dies anders formatiert, um mit der Matrixmultiplikation zu arbeiten?
Betreff: So berechnen Sie das VektorkreuzproduktDie schlechtere Leistung überrascht nicht ... Danke, dass Sie die Vorzeichenanpassung vorgenommen haben. Ich habe versehentlich das „Zeichen-Schachbrett“ weggelassen.
Meiner Meinung nach ist dies einer dieser Fälle, in denen gilt: „Nur weil man es kann, heißt das nicht, dass man es sollte“ ... {cool, lustig, kurz} überwiegt nicht {verständlich, wartbar, schnell}.
Betreff: So berechnen Sie das Vektorkreuzprodukt@brady_brady Cool! Es bedarf einer Optimierung, wenn Sie es verwenden möchten:
i = 1;
j = -1;
J( 3, 1, (j *= -1) * Det( (v1 || v2)[Remove( [1, 2, 3], i++ ), 0] ) );
</CODE><A href="https://mathinsight.org/cross_product_formula" target="_blank" rel="nofollow noopener noreferrer">https://mathinsight.org/cross_product_formula</A> zeigt, wie das mittlere Element negativ sein muss.Oben wechselt j das Vorzeichen (1, -1, 1) und i erhöht (1, 2, 3). Die Funktion J(...) verfügt über eine implizite Schleife, die das dritte Argument für jedes Element auswertet.</P>
<P> </P>
<P>Die einfach korrigierte Formel von<A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/11962" target="_blank"> @klk</A> ist etwa dreimal schneller und etwa N-mal einfacher zu verstehen.</P>
<P> </P>
<P>Testcode.</P>
<DIV class="lia-spoiler-container"><A class="lia-spoiler-link" href="#" rel="nofollow noopener noreferrer" target="_blank">Mehr sehen...</A><NOSCRIPT><DIV class="lia-spoiler-content"><BR /><PRE><CODE class=" language-jsl">v1 = [0, 0, 1];
v2 = [0, 1, 0];
start = HP Time();
For( t = 1, t < 1e6, t += 1,
i = 1;
j = -1;
J( 3, 1, (j *= -1) * Det( (v1 || v2)[Remove( [1, 2, 3], i++ ), 0] ) );
);
stop = HP Time();
Show( (stop - start) / 1e6 );//9.3s
start = HP Time();
For( t = 1, t < 1e6, t += 1,
Matrix( {v1[2] * v2[3] - v1[3] * v2[2], v1[3] * v2[1] - v1[1] * v2[3], v1[1] * v2[2] - v1[2] * v2[1]} )
);
stop = HP Time();
Show( (stop - start) / 1e6 );//3.2s
For( q = 1, q < 10000, q += 1,
v1 = J( 3, 1, Random Uniform( -1, 1 ) );
v2 = J( 3, 1, Random Uniform( -1, 1 ) );
If(
All(
Round( Matrix( {v1[2] * v2[3] - v1[3] * v2[2], v1[3] * v2[1] - v1[1] * v2[3], v1[1] * v2[2] - v1[2] * v2[1]} ), 10 ) //
== //
(i = 1; j = -1 ; Round( J( 3, 1, (j *= -1) * Det( (v1 || v2)[Remove( [1, 2, 3], i++ ), 0] ) ), 10 ) ; ) //
) == 0//
, //
Throw( Char( q ) )
);
);Seltsamerweise führt das Runden auf 11 Stellen gelegentlich nicht zu den Ergebnissen. Wahrscheinlich nahezu kollineare Vektoren.
Betreff: So berechnen Sie das VektorkreuzproduktNun, der wiederbelebte Zombie hat mich erwischt. Hier ist eine Möglichkeit, dies über Determinanten als zu tun @Craige_Hales erwähnt. Es ist kurz, aber ich weiß es nicht... es ist nicht sehr einfach.
crossP = Function( {x, y, i = 1},
Return( J( 3, 1, Det( (x || y)[Remove( [1, 2, 3], i++ ), 0] ) ) )
);
d. h. unter Verwendung der ursprünglich bereitgestellten Daten:

Betreff: So berechnen Sie das VektorkreuzproduktTut mir leid, dass ich diesen Zombie-Thread wiederbeleben muss, aber im zweiten Element ist hier ein Vorzeichenfehler.Ich glaube, das sollte so sein
Matrix(
{v1[2] * v2[3] - v1[3] * v2[2], v1[3] * v2[1] - v1[1] * v2[3], v1[1] * v2[2] - v1[2] * v2[1]}<BR />)Ich möchte dies hier einfach für alle anderen belassen, die zum schnellen Kopieren und Einfügen vorbeikommen.
Betreff: So berechnen Sie das VektorkreuzproduktDanke Cwillden, das ist im Wesentlichen das, was ich implementiert habe. Bei mir funktioniert es zwar, da ich mich nur mit 3D-Vektoren beschäftige, aber ich bin davon überzeugt, dass dies keine eingebaute Funktion ist. Ich werde das eine Weile offen lassen, um zu sehen, ob jemand anderes einen solchen Weg kennt.
Betreff: So berechnen Sie das VektorkreuzproduktIch hoffe, dass jemand einen cleveren Weg findet, dies zu tun. Die Funktion det() ist eng verwandt, aber ich verstehe nicht, wie man mit det(3x3-Matrix) mehr als einen Skalarwert zurückerhält. Ich denke, Sie könnten det(2x2 sub-matrix) dreimal verwenden, aber ich denke, das ist einfach xyzzy Der Ansatz ist einfacher und genauso schnell.
Ich verwende es für die Oberflächennormalen in 3D-Szenen, es ist etwas JSL enthalten https://community.jmp.com/t5/Uncharted/Custom-Visualization/ba-p/191559 .
Betreff: So berechnen Sie das VektorkreuzproduktWenn Sie immer nur mit 3x1- (oder 1x3-)Vektoren arbeiten, sind Recheneffizienz oder Eleganz meiner Meinung nach nicht allzu wichtig.Wäre das ausreichend?
cross_prod = function({v1, v2},
matrix({v1[2]*v2[3] - v1[3]*v2[2], v1[1]*v2[3] - v1[3]*v2[1], v1[1]*v2[2] - v1[2]*v2[1]});
);
cross_prod(v1, v2);