Verfasst am: 12.10.2011, 20:54
Titel: Schnittpunkt einer interpolierten Fläche mit Gerade
Hallo zusammen,
hat einer von euch vielleicht schon einmal ein ähnliches Problem berechnen lassen müssen?
Problem:
Gegeben sind mehrere Punkte(x,y,z) von Sollmessdaten durch die ich mit kubischer splineinterpolation einen flächenfit gelegt habe.
Berechnet werden soll von einem Punkt (xp,yp,zp) ausgehend in einer bestimmten Richtung(xn,yn,zn) die Laenge bis zum Schneiden der Fläche durch die Sollmesspunkte.
Am liebsten wäre es mir das ganze analytisch umzusetzen, eine solche Möglichkeit habe ich aber nicht gefunden. Ich habe zwar eine Geradengleichung, aber von dem Flächenfit bekomme ich leider nichts, dort kann ich mir nur zu gegebenen (x,y)-Werten den auftretenden z-Wert ausrechnen lassen.
Ich bekomme zwar aus dem fit eine Funktion wenn ich beispielsweise auf Polynome umstelle, bin damit aber nicht mehr genau genug an meinen Messwerten.
Bis jetzt habe ich numerisch angesetzt - in definierten Schritten so lange die Gerade entlanglaufen und parallel dazu mit den entstehenden (x+länge*richtung x, y + länge'richtung y)-Paaren den z-Wert der Flächeninterpolation berechnen. Wenn die Differenz der beiden z-Werte unter meine geforderte Genauigkeit fällt, ist man am Ziel.
So dauert die Rechnung für 200 Punkte allerdings 27h, insgesamt müsste ich aber knapp 1000 Punkte ausrechnen lassen. Ist also keineswegs eine schöne Lösung
Falls jemand schon einen ähnlichen Fall hatte oder anderweitige Ideen beisteuern kann wäre ich sehr dankbar!
Den gesamten Code inklusive Einlesewerten hänge ich mal als Anhang an, in den ersten paar Zeilen müsste nur das Verzeichnis der Messwerte angepasst werden, damit er lauffähig ist.
Das relevante Codestück:
Code:
for z=1:200; %gewuenschte Punkte festlegen
%spaeter nur fuer interpolierte Punkte, Berechnung von bestehenden
%Istmessdaten erlaubt Feststellung der Abweichung!
% if (Ergebnis(z,10) == 1); disp('interpolierter Punkt erreicht')
clear vektorlaenge;
clear richtung;
vektorlaenge = 0.0001;
k=0;
%Ueberpruefen, welche der Flaechen weiter außen liegt!
if(((Ergebnis(z,3)^2+Ergebnis(z,4)^2+Ergebnis(z,5)^2)^0.5) > ((Ergebnis(z,3)^2+Ergebnis(z,4)^2+(feval(sollmesflaeche.fitresult, [ Ergebnis(z,3) , Ergebnis(z,4)]))^2)^0.5));
%Istmessflaeche hat groeßeren Abstand zum Ursprung , weiter
%außen --> Richtung der Normalenvektoren muss umgedreht
%werden
richtung = 1;
else
richtung = 0;
end while(k == 0);
clear testwert;
clear testwert2;
clear narf;
%wie berechnet man den z-wert des aktuellen punktes?
%startwert + vektorlänge mal einheitsrichtung
if(richtung == 1);
testwert = (Ergebnis(z,5) - (vektorlaenge*Ergebnis(z,8)));
testwert2 = feval(sollmesflaeche.fitresult, [(Ergebnis(z,3)-(vektorlaenge*Ergebnis(z,6))) , (Ergebnis(z,4)-(vektorlaenge*Ergebnis(z,7)))]); %bestimme wert z des flaechenfits der sollmessdaten bei vektorlaenge
else
testwert = (Ergebnis(z,5) + (vektorlaenge*Ergebnis(z,8)));
testwert2 = feval(sollmesflaeche.fitresult, [(Ergebnis(z,3)+(vektorlaenge*Ergebnis(z,6))) , (Ergebnis(z,4)+(vektorlaenge*Ergebnis(z,7)))]); %bestimme wert z des flaechenfits der sollmessdaten bei vektorlaenge
end
narf = (testwert2-testwert);
% pause(5) if(abs(narf) < 0.001); %abbruchkriterium : bis auf ein µm an der fläche
Ergebnis(z,9) = vektorlaenge;
k=1;
disp('Laenge gefunden!')
%pause(5) elseif(vektorlaenge > 0.200);
Ergebnis(z,9) = 99;
disp('Fehler!')
k=1;
else
vektorlaenge = (vektorlaenge+0.000001);
end end % end
Zur Lesbarkeit : In der Matrix Ergebnis ist je Zeile ein Messwert, die Spalten sind wie folgt belegt = ( J I xp yp zp xn yp zn L interpoliert?)
Die ersten beiden bestehen aus Indizes, dann folgen die Punktkoordinaten, anschließend der normalisierte Normalenvektor und Laenge bis zum Schnittpunkt.
Im gesamten Code ist der Anfang recht uninteressant, Einlesen, die Istmessdaten mit zusätzlichen Punkten die ausgewertet werden sollen versehen und das ganze mit neuen Indizes in Ergebnis abspeichern.
Wenn ich jetzt die Laenge bis zum Schneiden eines vorhandenen Istmesspunktes berechne, kann ich die Genauigkeit der Rechnung bestimmen, weil ich von diesen Punkten die gemessene Laenge der Abweichung zur Verfügung habe
Durch die Indexveschiebung entspricht die Zeile 35, Punkt 2,5 von Ergebnis dem Punkt 1,1 der originalen Daten.
Die Werte die ich so berechne sind aber um mehrere Faktoren größer als die vorhandene gemessene Länge.
Im gesamten Code ist auch eine Version2 dabei, die auskommentiert ist. Das Vorgehen dort ist ziemlich ähnlich, nur das ich die Differenz über fsolve lösen lasse, liefert aber auch keine schöneren Werte.
Gerade arbeit ich an einem anderen Ansatz, von dem ich hoffentlich heute nachmittag den Code posten kann. Die Idee dabei ist:
Berechne für einen Startwert (x,y,z) das Sollmes-z (x,y, z2), die Differenz von z sei a. Jetzt dasselbe bei verschiedenen Längen des Vektors l auswerten und eine Funktion von l und a finden, die dann an der Stelle a = 0 auswerten, was mir einen Wert für die Länge liefern sollte.
Finds immer schwierig über ein Problem zu reden, weil man selbst in dem Thema so drin ist, wenns weiterhin Unklarheiten gibt einfach bescheid geben!
Und danke
der angekündigte Ansatz ist mittlerweile auch fertig
Zitat:
Gerade arbeit ich an einem anderen Ansatz, von dem ich hoffentlich heute nachmittag den Code posten kann. Die Idee dabei ist:
Berechne für einen Startwert (x,y,z) das Sollmes-z (x,y, z2), die Differenz von z sei a. Jetzt dasselbe bei verschiedenen Längen des Vektors l auswerten und eine Funktion von l und a finden, die dann an der Stelle a = 0 auswerten, was mir einen Wert für die Länge liefern sollte.
, den Code hänge ich auch noch an. In der kompletten Daten einfach ab Zeile 340 auskommentieren und das Stück stattdessen verwenden.
Dier erstellte Funktion übernimmt 3 Rückgabewerte.
Für interpolierte Punkte soll die Länge des Vektors bestimmt werden und in Spalte 9 von Ergebnis abgelegt werden, dort sieht man auch schön den Unterschied der Größen zu den vorhandenen Daten.
In Spalte 11 wird die noch vorhandene Differenz bei der gefundenen Länge der z-Koordinaten ausgegeben, um festzustellen wie nah man dem tatsächlichen Durchstoßpunkt gekommen ist. Das schaut bis auf Ausnahmen auch gut aus.
Zum Vergleich habe ich für alle bestehenden Punkte die z-Abweichung der Punkte mit dem z-Wert des Sollmesflaechenfits in Spalte 12 ausgeben lassen, berechnet mit der von diesen Punkten vorhandenen Länge des Vektors. Diese Abweichungen sind allerdings noch viel zu groß, die interpolierte Fläche würde so ja um Größenordnungen zur vorhandenen Länge abweichen.
Alle Ideen, den Schnittpunkt zu berechnen liefern ähnliche Werte, weswegn ich mir langsam die Frage stelle, ob der Flaechenfit die Fehlerursache sein könnte?
Allerdings weiß ich nicht, wie ich den in Matlab sinnvoll anders umsetzen könnte
Code:
%% weiterer Ansatz: Funktion von vektorlaenge und Abstand der z-werte
%% aufstellen, damit bestimmen des 0-z-Abstandes
%%%%%%%%%%%%%%%
%% wie sieht denn die sollmesflaeche aus?
%% Ausgabe der Abweichung der z-Werte bei Verwendung von Fn zu den
%% entsprechenden z-Werten der Sollmesflaeche
%% damit Vergleich verschiedener Verfahren des Flaechenfits durchgefuehrt,
%% zeigen aber alle ein aehnliches Abweichungsverhalten clear tmp.testdiff;
for z=1:length(Ergebnis(:,1));
if(Ergebnis(z,10) == 0); %%nur fuer nicht interpolierte Punkte!
clear tmp.istmessstartz;
clear tmp.sollmesstartz;
clear startz;
tmp.istmessstartz = Ergebnis(z,5);
tmp.sollmesstartz = feval(sollmesflaeche.fitresult, [ Ergebnis(z,3) , Ergebnis(z,4)]);
startz = (tmp.sollmesstartz - tmp.istmessstartz);
Denn er löscht die Variable mit Namen "tmp.ismessstartz", aber eine solche Variable gibt es nicht, da das ein Struct ist. Entweder "clear tmp" oder das clearen gleich ganz lassen.
herzlichen Dank für den Tip. Sobald es sich also um ein struct handelt kann ich in matlab keine einzelnen Elemente löschen, sondern wenn dann nur die ganze Struktur?
Wusste ich nicht, aber den Code könnte ich in dem Fall ja problemlos anpassen,um das Problem zu umgehen.
Nur mit dem eigentlichen Problem komm ich nicht wirklich weiter ^^
Das Löschen eines einzelnen Felds eines Structs ist nicht einfach in MATLAB. RMFIELD macht das z.B. recht ineffizient. "fRMField" aus der FEX ist schneller.
Aber ich würde das CLEAR einfach ganz weglassen, weil es unnötig Zeit raubt.
Zu dem eigentlichen Problem kann ich nichts sagen, weil ich das Problem auch nach mehrmaligen Durchlesen nicht verstehe. Du beschreibst zwar viele Details, aber ich komme schon beim Anfang nicht mit: Du hast eine Spline-Fläche und eine Gerade. Wonach suchst Du dann?
Ok, wenn das an clearen an dieser Stelle nicht sinnvoll ist, fliegts einfach komplett raus.
Zum Problem:
Wie du schon sagtest, habe ich 2 Splineflächen und eine Gerade.
Es liegen 2 Datensätze vor, einmal die Originalfläche, später eine verschlissene Version davon.
Von der verschlissenen berechne ich in jedem Punkt des Messgitters den Normalenvektor, in dessen Richtung die Gerade läuft.
Gesucht ist jetzt die Länge der Gerade, ausgehend von dem Startpunkt der verschlissenen bis zum Schnittpunkt mit der Originalfläche.
Wie oben schon geschrieben, komm ich mit meinem Verfahren mittlerweile ziemlich genau an den tatsächlichen Schnittpunkt heran, die Länge die dabei herauskommt ist aber nicht plausibel, viel zu groß. Deswegen vermute ich, das der Flächenfit keine ausreichende Genauigkeit hat, bzw. zwischen den Datenpunkten das oszillieren anfängt, das versuch ich mir gerade anzusehen.
(Danke übrigens auch fürs mehrmalige Lesen und nicht aufgeben )
Einstellungen und Berechtigungen
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.