Koordinatentransformation

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
mechanicalStore
User
Beiträge: 119
Registriert: Dienstag 29. Dezember 2009, 00:09

Hallo Zusammen,

ich weiß nicht, ob jemand helfen kann oder will, es ist recht aufwändig. Wenn nicht, trotzdem danke fürs Ansehen. Mein Programm läuft ohne Fehler durch, jedoch kommen am Ende exorbitante Werte heraus, ich weiß aber nicht, woran es liegt, bzw. bin der Meinung, dass es so stimmen sollte (ok, was halt nicht so ist). Ich versuche mal, zu erklären, worum es geht:

Ich habe 2 CSV-Dateien k1 und k2 (zur Demonstration stark gekürzt). Diese enthalten Punktewolken X,Y,Z (wobei ich nur Y und Z benutze, X ist immer 0).

Der erste Punkt auf k2 ist der Startpunkt. Dann laufe ich kontinuierlich durch alle Punkte k2 hindurch und bilde aus der jeweiligen Differenz zum ersten Punkt einen Otrtsvektor.
Ebenso laufe ich in einer verschachtelten Schleife durch die Punktewolke k1.
Nun wird aus den jeweils ersten Punkten aus k1 und k2 ein Richtungsvektor gebildet, der sozusagen die Basisrichtung angibt. Im weiteren Verlauf das gleiche Spiel, es wird jewelis ein RIchtungsvektor relativ zum ersten Richtungsvektor gebildet (entsprechend passend zum jeweiligen Ortsvektor).
Man kann sich das Ganze als starre Linie vorstellen, deren Enden auf den beiden Punktewolken entlang kletttern, wobei k2 die Leitlinie ist.
Besonderheit: da eine starre Linie eine feste länge hat, die Auflösung der Punktewolken aber viel zu grob ist, hat k2 etwa die 10-Fache Menge an Punkten. Ich halte also den Punkt auf k2 fest und durchlaufe k2 (ich weiß, ineffizient) vollständig, solange der Vergleich der Vektorlänge mit ABSTAND immer kleiner wird (epsilon). Sobald epsilon wieder größer wird, ist der letzte Punkt davor der Richtige (ich weiß, was jetzt kommen mag, aber beide Punktewolken als Kurve gedacht, sind in dem Fall monoton steigend/fallend, sodass dieser Vergleich immer stimmt, es gibt nur ein kleinstes epsilon).

Soweit, sogut. Wenn man sich nun vorstellt, dass an dieser starren Linie eine weitere Linie starr verbunden ist (beliebig), so soll der Endpunkt (POINT) dieser Linie unter diesen Transformationen bewegt/erzeugt werden.
Daher normiere ich den Richtungsvektor, stelle einen senkrechten Vektor darauf und baue daraus zusammen mit dem Ortsvektor eine Transformationsmatrix. Diese invertiere ich und bilde dann jeweils das Punktprodukt mit POINT.

Leider stimmen die Ergebnisse ganz und gar nicht, die erzeugten Punkte liegen um die 8000mm entfernt, ich komme aber nicht dahinter.

Hier das Programm und die beiden gekürzten Punktewolken (falls bis hierhin noch jemand am lesen ist ....)

Code: Alles auswählen

import math
import numpy as np
from operator import itemgetter

ABSTAND = 153.8
POINT = np.array([(60.0,-100.0, 1.0)])

def load_trace(file_name,trace_array):
    # Format: Nr                X               Y       Z
    # Format: Point.5445	1000,981234	81,6	338,20483
    # Liest Y und Z Werte aus der Datei
    get_items = itemgetter(2, 3)

    with open(file_name, 'r') as fh:
        for line in fh:
            items = get_items(line.split(';'))
            a = items[0].replace(",",".")
            b = items[1].replace(",",".")
            xy = float(a), float(b)
            trace_array.append(xy)

def calculate_new_points(basic_point, normalized_inverted_matrices):
    new_points = []

    for matrix in normalized_inverted_matrices:

        # print(f'{matrix}    {basic_point}')
        
        transferred_point = np.dot(basic_point, matrix)
        new_points.append(transferred_point)

    return new_points

def vector_length(vector):
    return math.sqrt(sum(pow(element, 2) for element in vector))

def calculate_normalized_matrices(k1_trace_array, k2_trace_array):

    normalized_inverted_matrices = []

    basis_ortsvektor = np.array(k2_trace_array[0])
    hilfspunkt = np.array(k1_trace_array[0])
    basis_richtungsvektor = np.subtract(hilfspunkt, basis_ortsvektor)
    basis_richtungsvektor_normiert = basis_richtungsvektor / np.linalg.norm(basis_richtungsvektor)

    # print(f"{basis_richtungsvektor}   {basis_richtungsvektor_normiert}")
    # print(basis_ortsvektor)

    k2_first_pass = False
    for k2_index in range(len(k2_trace_array)):
        
        if (k2_first_pass):

            p2 = np.array(k2_trace_array[k2_index])
            # print(p2)
            
            k1_first_pass = False
            last_epsilon = 0
            
            for k1_index in range(len(k1_trace_array)):
                
                p1 = np.array(k1_trace_array[k1_index])
                v = np.subtract(p1,p2)
                # print(f"{p1} --- {p2} --- {v}")
                
                epsilon = abs(ABSTAND - vector_length(v))
                # print(epsilon)

                if (k1_first_pass):
                    if (epsilon > last_epsilon):

                        new_ortsvektor = np.subtract(p2, basis_ortsvektor)
                        p1 = np.array(k1_trace_array[k1_index-1])
                        hilfs_richtungsvektor = np.subtract(p1, p2)
                        hilfs_richtungsvektor_normiert = hilfs_richtungsvektor / np.linalg.norm(hilfs_richtungsvektor)
                        new_richtungsvektor = np.subtract(hilfs_richtungsvektor_normiert, basis_richtungsvektor_normiert)

                        M = np.array( [ (new_richtungsvektor[0], -new_richtungsvektor[1], new_ortsvektor[0]),
                                        (new_richtungsvektor[1], new_richtungsvektor[0], new_ortsvektor[1]) , (0, 0, 1) ] )
                        M_inverted = np.linalg.inv(M)
                        
                        normalized_inverted_matrices.append(M_inverted)

                        # print(f'{M}')
                        
                        break
                    else:
                        last_epsilon = epsilon
                else:
                    last_epsilon = epsilon
                    k1_first_pass = True
        else:
            k2_first_pass = True

    # print(normalized_inverted_matrices)
    return normalized_inverted_matrices          
            
        

def main():

    k1_trace_array = []
    k1_file_name = 'k1_0,1mm.csv'
    
    k2_trace_array = []
    k2_file_name = 'k2_1,0mm.csv'
    
    load_trace(k1_file_name, k1_trace_array)
    load_trace(k2_file_name, k2_trace_array)

    normalized_inverted_matrices = calculate_normalized_matrices(k1_trace_array, k2_trace_array)
    
    new_points = calculate_new_points(POINT, normalized_inverted_matrices)

    print(new_points)

if __name__ == "__main__":
    main()
    
k2

Code: Alles auswählen

K2_Start;0;73,79999999;-50
K2_Start;0;73,8174524;-50,9998477
K2_Start;0;73,8349048;-51,99969539
K2_Start;0;73,85235721;-52,99954309
K2_Start;0;73,86980961;-53,99939078
K2_Start;0;73,88726202;-54,99923848
k1

Code: Alles auswählen

K1_End;0;-80;-50,30776517
Start_K1;0;-79,84841931;-50,31244912
Start_K1;0;-79,74846759;-50,31555708
Start_K1;0;-79,64851635;-50,31868043
Start_K1;0;-79,54856559;-50,32181917
Start_K1;0;-79,44861532;-50,32497331
Start_K1;0;-79,34866553;-50,32814283
Start_K1;0;-79,24871623;-50,33132775
Start_K1;0;-79,14876742;-50,33452805
Start_K1;0;-79,04881911;-50,33774375
Start_K1;0;-78,9488713;-50,34097483
Start_K1;0;-78,84892398;-50,34422131
Start_K1;0;-78,74897717;-50,34748317
Start_K1;0;-78,64903086;-50,35076043
Start_K1;0;-78,54908505;-50,35405307
Start_K1;0;-78,44913975;-50,3573611
Start_K1;0;-78,34919497;-50,36068452
Start_K1;0;-78,2492507;-50,36402333
Start_K1;0;-78,14930694;-50,36737753
Start_K1;0;-78,0493637;-50,37074711
Start_K1;0;-77,94942098;-50,37413208
Start_K1;0;-77,84947878;-50,37753244
Start_K1;0;-77,74953711;-50,38094819
Start_K1;0;-77,64959597;-50,38437933
Start_K1;0;-77,54965535;-50,38782585
Start_K1;0;-77,44971527;-50,39128776
Start_K1;0;-77,34977572;-50,39476505
Start_K1;0;-77,24983671;-50,39825774
Start_K1;0;-77,14989823;-50,4017658
Start_K1;0;-77,0499603;-50,40528926
Start_K1;0;-76,95002291;-50,4088281
Start_K1;0;-76,85008607;-50,41238232
Start_K1;0;-76,75014978;-50,41595193
Start_K1;0;-76,65021403;-50,41953693
Start_K1;0;-76,55027884;-50,42313731
Start_K1;0;-76,45034421;-50,42675308
Start_K1;0;-76,35041013;-50,43038423
Start_K1;0;-76,25047662;-50,43403076
Start_K1;0;-76,15054367;-50,43769268
Start_K1;0;-76,05061128;-50,44136999
Start_K1;0;-75,95067946;-50,44506268
Start_K1;0;-75,85074821;-50,44877075
Start_K1;0;-75,75081753;-50,4524942
Start_K1;0;-75,65088742;-50,45623304
Start_K1;0;-75,55095789;-50,45998726
Start_K1;0;-75,45102895;-50,46375686
Start_K1;0;-75,35110058;-50,46754185
Start_K1;0;-75,25117279;-50,47134222
Start_K1;0;-75,1512456;-50,47515797
Start_K1;0;-75,05131899;-50,47898911
Start_K1;0;-74,95139297;-50,48283562
Start_K1;0;-74,85146755;-50,48669752
Start_K1;0;-74,75154272;-50,4905748
Start_K1;0;-74,65161849;-50,49446746
Start_K1;0;-74,55169486;-50,4983755
Start_K1;0;-74,45177183;-50,50229892
Start_K1;0;-74,35184941;-50,50623772
Start_K1;0;-74,25192759;-50,5101919
Start_K1;0;-74,15200639;-50,51416147
Start_K1;0;-74,0520858;-50,51814641
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mir fehlt hier die Information, was das eigentlich erreichen soll. Du steigst da auf einem viel zu tiefen Level ein. Geht es darum, die beiden Punktewolken aneinander auszurichten? Oder um eine Erkennung, welche von verschiedenen Mustern es ist?
mechanicalStore
User
Beiträge: 119
Registriert: Dienstag 29. Dezember 2009, 00:09

Sorry, es fällt mir echt schwer, das anders zu beschreiben .
Grundsätzlich will ich eine 3. Punktewolke erzeugen. Der erste Punkt dieser 3. Punktewolke ist POINT. Dann wird POINT immer wieder verschoben, eben anhand der Orts- und Richtungsvektoren, die sich aus den beiden anderen Punktewolke ergeben hatten.
Man könnte das mit einem Pantographen vergleichen. Der ist quasi auch an zwei Punkten beweglich und hinterlässt am dritten Punkt irgendeine andere Form, in Relation.

Sorry, dass mir keine bessere Beschreibung einfällt. Kann verstehen, wenn das unverständlich rüber kommt. Trotzdem danke fürs drauf schauen.
Antworten