Verfasst am: 05.12.2011, 13:09
Titel: Ebene aus drei Punkten
Hallo zusammen,
ich müsste aus drei Punkten eine Ebene bilden und die Koordinatengleichung der Ebene erhalten. Daraus brauche ich dann den Normalenvektor.
Die Ebene benötige ich für später auch noch, den Normalenvektor kann ich ja mit dem Kreuzprodukt bestimmen.
Das ganze benötige ich, um die Winkel von drei senkrecht aufeinander stehenden Achsen zu drei anderen zu bestimmen, damit ich die ersten drei mit den zweiten drei in Deckung bringen kann.
ich benötige die ebene aus diesen drei punkten, um zwei vektoren, die icht in dieser Ebene liegen darauf zu projezieren, damit ich berechnen kann, wie gross der Winkel in dieser Ebene sein muss, dass ich die beiden achesen deckungsgleich rotieren kann.
% Rotationswinkel/-matrix um Y-Achse (rot) % Knie- Ankle - Verbindungsvektor; (Z-Achse muss deckungsgleich zu dieser Achse gedreht werden!)
KNAK = NaN(size(LKJC,1),size(LKJC,2));
for i=1:1:size(LKJC,1)
KNAK(i,:) = LKJC(i,:)-LAJC(i,:);
end
% Normalenvektor der Ebene in die gedreht werden soll, hier KJC AJC Y-Achse
gamma = NaN(size(Markers.LANK,1),1);
for i=1:1:size(LTIB2k,1)
n = cross(KNAK(i,:),LTIB2k(i,:)); % LTIB2k liegt in der Ebene zu der der Winkel gesucht wird.
nn = norm(n);
gamma(i) = asin(norm(LTIB3k*n'/(norm(LTIB3k)*nn)));
end
% Rotation um Y-Achse (rot); Mfl ist Rotations matrix um LTIB2-Achse
LTIB3ran = NaN(size(LTIB3n,1),size(LTIB3n,2)); % neue Achse nach Drehung um die Achse
LTIB1ran = NaN(size(LTIB1n,1),size(LTIB1n,2));
LTIB3r = NaN(size(LTIB3n,1),size(LTIB3n,2)); % Um Achse gedrehter Punkt LTIB3
LTIB1r = NaN(size(LTIB1n,1),size(LTIB1n,2));
for i=1:1:size(LTIB3n,1)
Mfl = makehgtform('axisrotate',LTIB2(i,:),gamma(i));
Mfl(4,:) = [];
Mfl(:,4) = [];
LTIB3r(i,:) = Mfl*LTIB3n(i,:)';
LTIB1r(i,:) = Mfl*LTIB1n(i,:)';
% neue Achsen bestimmen (X' grün und Z' blau)
LTIB1ran(i,:) = LTIB1r(i,:)-LAJC(i,:);
LTIB3ran(i,:) = LTIB3r(i,:)-LAJC(i,:);
end % Rotationswinkel/- matrix um neue X-Achse bestimmen beta = NaN(size(Markers.LANK,1),1);
for i=1:1:size(LAJC,1)
n = cross(KNAK(i,:),LTIB1ran(i,:));
nn = norm(n);
beta(i) = asin(norm(LTIB3ran(i,:)*n'/(norm(LTIB3ran(i,:))*nn)));
end
% Rotation um neue X-Achse
LTIB3rr = NaN(size(LTIB3n,1),size(LTIB3n,2));
LTIB2r = NaN(size(LTIB2n,1),size(LTIB2n,2));
LTIB3rran = NaN(size(LTIB3n,1),size(LTIB3n,2));
LTIB2ran = NaN(size(LTIB2r,1),size(LTIB2r,2));
for i=1:1:size(LTIB3n,1)
Ma = makehgtform('axisrotate',LTIB1ran(i,:),beta(i));
Ma(4,:) = [];
Ma(:,4) = [];
LTIB3rr(i,:) = Ma*LTIB3r(i,:)';
LTIB2r(i,:) = Ma*LTIB2n(i,:)';
% Neue Achsen bestimmen (z''-Achse und y'achse)
LTIB3rran(i,:) = LTIB3rr(i,:)-LAJC(i,:);
LTIB2ran(i,:) = LTIB2r(i,:)-LAJC(i,:);
end
% Rotationswinkel/-matrix um neue Z-Achse bestimmen
alpha = NaN(size(Markers.LANK,1),1);
for i=1:1:size(LAJC,1)
n = cross(KNAK(i,:),LTIB3rran(i,:));
nn = norm(n);
alpha(i) = asin(norm(LTIB3rran(i,:)*n'/(norm(LTIB3rran(i,:))*nn)));
end
% Rotation um neue Z-Achse (blaue)
LTIB1rr = NaN(size(LTIB3n,1),size(LTIB3n,2));
LTIB2rr = NaN(size(LTIB2n,1),size(LTIB2n,2));
for i=1:1:size(LTIB3n,1)
Mab = makehgtform('axisrotate',LTIB3rran(i,:),alpha(i));
Mab(4,:) = [];
Mab(:,4) = [];
LTIB1rr(i,:) = Mab*LTIB1r(i,:)';
LTIB2rr(i,:) = Mab*LTIB2r(i,:)';
end
Dieser Code ergibt mir eine Annäherung an die gewünschte Achse. Leider ist das Resultat nicht ganz perfekt. es entsteht ein Fehler von ca. 3.5 Grad. Wenn du noch ne Idee hast, warum es nicht 100% übereinstimmt, teil sie mir doch mit.
Danke für die Vorschläge.
LKJC und LAJC sind zeitlich abhängig, sie verschieben sich also mit der Zeit. ist dein Vorschlag auch in diesem Fall möglich?
Ich weiß nicht, was innerhalb einer Matrix "zeitlich" abhängig bedeutet. Matlab sieht ja nur eine Matrix ohne etwas über die physikalischen Grundlagen zu wissen. Ich habe lediglich statt die Subtraktion auf einzelne Vektoren anzuwenden, sie gleich auf die gesamte Matrix angewendet.
Ich finde bisher Deinen Code noch nicht übersichtlich genug, um den Fehler finden zu können. Eine Abweichung von 3.5 Grad ist wahrscheinlich kein Rundungsproblem, sondern ein Zeichen dafür, dass die Berechnung falsch ist. Ich kann mir aber auf Anhieb nichts unter dem Folgenden vorstellen:
Code:
n = cross(KNAK(i,:),LTIB3rran(i,:));
nn = norm(n);
alpha(i) = asin(norm(LTIB3rran(i,:)*n'/(norm(LTIB3rran(i,:))*nn)));
Danke für den Hinweis. ich habe es mit deinem Ansatz probiert. Aber leider hat er Winkel ergeben, die rein durch anschauen der Graphik nicht sein können. Ich habe meinen Ansathz noch ein wenig angepasst und mittlerweile nur noch einen Fehler von ca. 0.9 Grad. Was ist denn nicht optimal an der Art wie ich die Winkel berechne? Habe diese Formeln aus der Vektorgeometrie, sollte ja auch funktionieren. Folgendes steht nun im Code:
Code:
n1 = cross(LKNAK(i,:),LTIB1k(i,:)); % Normalenvektor der Ebene in der die Achse (LTIB3k) gedreht werden soll
n1 = n1./norm(n1);
Z = LTIB3k(i,:) + LAJC(i,:); % Punkt an der Spitze des Vektors, der gedreht werden soll
g = [Z(1),Z(2),Z(3),n1(1),n1(2),n1(3)]; % Gerade die durch den Punkt Z geht und rechtwinklig die Ebene Schneidet.
b = sge3p(g,LAJC(i,:),LTIB1(i,:),LKJC(i,:)); % Punkt in dem die Gerade die Ebene schneidet
vb = b-Markers.LAJC(i,:); % LTIB3k projeziert in die Ebene in der die Achse gedreht werden soll
gammab(i) = acos(LKNAK(i,:)*vb'/(norm(vb)*norm(LKNAK(i,:)))); % Winkel um den LTIB3k rotiert werden soll
Die Formel zur Berechnung zwischen zwei Vektoren ist korrekt und stabiler als Methoden mit ASIN und ACOS. Diese beiden haben nämlich numerische Instabilitäten in der Nähe bestimmter Winkel.
Die ATAN2 Methode wird deshalb in professionellen Modellierungs-Programmen verwendet. Wenn sie bei Dir ein falsches Ergebnis geliefert hat, liegt irgendwo ein Feghler, aber nicht in der Gleichung.
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.