Dies ist eine alte Version des Dokuments!
16.01.2020
Heute kamen nur wenige Änderungen hinzu, größtenteils haben wir unser weiteres Vorgehen besprochen und den Rest der Zeit damit verbracht, den Code ein bisschen aufzuräumen (Betonung auf „ein bisschen“) und kleinere Fehler auszubessern.
Aktueller Code:
# -*- coding: utf-8 -*- """ Created on Thu Dec 19 15:31:18 2019 @author: Lukas """ import numpy as np import math import turtle import random as rn import copy turtle.speed(0) turtle.ht() # VARIABLEN anzahlKerne = 20 max_x = 300 max_y = 300 # KLASSEN class Gerade(object): ov = (0,0) #Ortsvektor rv = (0,0) #Richtungsvektor l = 0; #Laenge kerne = (0,0) # gibt an, welche Kerne durch die Linie verbunden werden wink = 0 # gibt an, in welchem Winkel der Richtungsvektor steht start=0 ende=1 index=0 def toString(): print("OV : "+Gerade.ov+" RV : "+Gerade.rv+" Kerne "+Gerade.kerne) # METHODEN def generiereKernListe(n,maxx,maxy): # generiert eine Liste von Punkten im R^2 liste=[] for c in range(n): x = rn.randint(-maxx,maxx)#rn.uniform(0,maxx) y = rn.randint(-maxy,maxy)#rn.uniform(0,maxy) liste.append((x,y)) return liste def zeichneLinie(start,ende): # zeichnet eine Linie zwischen start und ende mithilfe einer turtle turtle.penup() turtle.goto(start) turtle.pendown() turtle.goto(ende) def richtungLinie(start,ende): # gibt den Richtungsvektor von start nach ende aus richtung = np.subtract(ende,start) return richtung def schnittTest(g1,g2): # testetm ob g1 und g2 sich schneiden return np.linalg.solve([[g2.rv[0],-g1.rv[0]],[g2.rv[1],-g1.rv[1]]],[[g1.ov[0]-g2.ov[0]],[g1.ov[1]-g2.ov[1]]]) def vektorLänge(v2): # errechnet die Laenge eines Vektors v1 = np.array([0,0]) return math.sqrt((abs(v1[0]-v2[0])**2)+(abs(v1[1]-v2[1])**2)) def vektorNorm(v): # normiert einen Vektor return(1/math.sqrt(v[0]**2+v[1]**2)*v) def punktAufLinie(p,o,r): # liegt punkt p auf der geraden g = o + m*r? if(np.array_equal(p,o)): return False elif(np.array_equal(r,[0,0])): return False elif(r[1] == 0): a = (p[0]-o[0])/r[0] if (o[1]+a*r[1] == p[1]): if(a<1 and a>0): return True else: return False else: return False else: a = (p[1]-o[1])/r[1] if (o[0]+a*r[0] == p[0]): if(a<1 and a >0): return True else: return False else: return False def rechtW(v): # findet einen Vektoren im rechten Winkel zu dem gegebenen Vektor v_neu = np.array((-v[1],v[0])) return v_neu def zwischenWinkel(a,b): # gibt den Winkel zwischen zwei Vektoren aus w = (a[0]*b[0]+a[1]*b[1])/(math.sqrt(a[0]**2+a[1]**2)*math.sqrt(b[0]**2+b[1]**2)) w = math.degrees(math.acos(w)) return w def xAchseWinkel(a): w = (a[0]*1+a[1]*0)/(math.sqrt(a[0]**2+a[1]**2)*math.sqrt(1**2+0**2)) w = math.degrees(math.acos(w)) if (a[1]<0): w = 360 -w return w # MAIN # genriert die Liste der Kerne ker = generiereKernListe(anzahlKerne,max_x,max_y) #anzahlKerne = 30 #ker = [(253, 63), (-202, 25), (117, -194), (271, 247), (-84, -96), (145, 215), (-81, -145), (157, -297), (-157, 80), (217, 164), (175, -253), (-190, -48), (-122, 193), (253, -268), (-211, -81), (-121, 64), (-249, -25), (244, 298), (-42, 98), (-144, 218), (42, -56), (-141, 118), (125, 63), (-119, -21), (-79, 238), (21, 272), (100, -107), (147, 25), (-170, -54), (260, 267)] print("Kerne : ",ker) listGer = [] # generiert alle Linien zwischen den Kernen for i in range(0,anzahlKerne): for k in range(i,anzahlKerne): if (i!=k): eineGerade = Gerade() eineGerade.ov = np.array(ker[i]) eineGerade.rv = np.subtract(ker[k],ker[i]) eineGerade.l = vektorLänge(eineGerade.rv) # welche Kerne verbindet die Linie? eineGerade.kerne = (i,k) listGer.append(eineGerade) # zeichnet alle Linien zwischen allen Punkten #turtle.color("cyan") #for i in range(0, len(listGer)): # zeichneLinie(listGer[i].ov,listGer[i].ov+listGer[i].rv) schnitt = 0 l = len(listGer) #testet, welche geraden gelöscht werden sollen i = 0 k = 0 epsilon = 0.0001 #*anzahlKerne while (i < l): k = i+1 while (k < l): z = [0,0] if(i!=k): #for k in range(i+1, l): try: # schneiden sich die Linien? z = schnittTest(listGer[i],listGer[k]) if (z[0][0]<1 and z[0][0]>0 and z[1][0]<1 and z[1][0]>0 and listGer[i].kerne[0] != listGer[k].kerne[0] and listGer[i].kerne[1] != listGer[k].kerne[1] and listGer[i].kerne[1] != listGer[k].kerne[0] and listGer[i].kerne[0] != listGer[k].kerne[1]): #print("\n\n ",i," OV ",listGer[i].ov," ",i," RV ",listGer[i].rv," ",k," OV ",listGer[k].ov," ",k," RV ",listGer[k].rv) #print("vergleiche ",i," und ", k) #print("Schnitt\n",z[0][0],z[1][0]) schnitt=schnitt+1 #del listGer[i] #ACHTUNG: EIGENTLICH SOLL DIE LÄNGERE GELÖSCHT WERDEN #print("laenge a : ",listGer[i].l," laenge b : ",listGer[k].l,"\n",10*" - ") if (listGer[i].l < listGer[k].l): del listGer[k] i=0 else: del listGer[i] k=0 except: #print("# end of this iteration") break k=k+1 i=i+1 for i in range(0, len(listGer)): listGer[i].index = i; # die Geraden in den Kernen müssen wissen, welchem echtem Index sie angehören # HIER NEU EINGEFÜGT!!! # listen, die die einzelnen Kerne abspeichert vK = [] # Geraden in listen so geordnet, dass sie ihrem kern zugeordnet werden for k in range(0, anzahlKerne): kernGeraden = [] vK.append(kernGeraden) for i in range(0, len(listGer)): if (listGer[i].kerne[0] == k): obj = copy.copy(listGer[i]) obj.wink = xAchseWinkel(obj.rv) vK[k].append(obj) vK[k].sort(key=lambda x: x.wink, reverse=False) if (listGer[i].kerne[1] == k): obj = copy.copy(listGer[i]) obj.wink = xAchseWinkel((-1)*obj.rv) vK[k].append(obj) vK[k].sort(key=lambda x: x.wink, reverse=False) for j in range(0, len(vK)): print("\nWinkel von Kern ",j," (",len(vK[j])," Stück) : ") for g in range(0, len(vK[j])): if (vK[j][g].kerne[0] != j): print(vK[j][g].index,vK[j][g].wink, "kern", vK[j][g].kerne[0]) else: print(vK[j][g].index,vK[j][g].wink, "kern", vK[j][g].kerne[1]) # Geraden in den Kernen werden sortiert listRGer = [] for i in range(0, len(listGer)): neueGerade = Gerade() neueGerade.ov = listGer[i].ov+(.5*listGer[i].rv) neueGerade.rv = rechtW(listGer[i].rv) listRGer.append(neueGerade) # funktioniert schonmal, jetzt müssen die aber auch richtig gezeichnet werden... for f in range(0, anzahlKerne): for i in range(0, len(vK[f])): if (i-1 < 0): oG = schnittTest(listRGer[vK[f][i].index], listRGer[vK[f][len(vK[f])-1].index]) listRGer[vK[f][i].index].start = oG[1] listRGer[vK[f][len(vK[f])-1].index].ende = oG[0] print("Kern ",f," Stelle",i,len(vK[f])-1,"\n Winkel",vK[f][i].wink, vK[f][len(vK[f])-1].wink," \n",oG) else: oG = schnittTest(listRGer[vK[f][i].index], listRGer[vK[f][i-1].index]) listRGer[vK[f][i].index].start = oG[1] listRGer[vK[f][i-1].index].ende = oG[0] print("Kern ",f," Stelle",i,i-1,"\n Winkel",vK[f][i].wink, vK[f][i-1].wink," \n",oG) print("Schnitte : ", schnitt) for i in range(0, len(listRGer)): print(listRGer[i].start, listRGer[i].ende) for i in range(0, len(listGer)): turtle.color("red") turtle.pensize(2) zeichneLinie(listGer[i].ov,listGer[i].ov+listGer[i].rv) turtle.color("black") turtle.pensize(2) #zeichneLinie(listRGer[i].ov,listRGer[i].ov+listRGer[i].rv) zeichneLinie(listRGer[i].ov+(listRGer[i].rv * listRGer[i].start),listRGer[i].ov+(listRGer[i].rv * listRGer[i].ende)) print(ker) turtle.Screen().exitonclick() #turtle.done() # Gute Kernlisten: # für die tests [(28, 151), (-79, 119), (18, 183), (-226, 148), (182, -18)] # beste : [(52, 199), (101, 243), (-227, -48), (5, 213), (26, -294), (197, 174), (57, -275), (-61, -63), (206, 6), (-112, 62), (26, 105), (247, 121), (287, 161), (152, 272), (209, -94)] # beste : [(-92, 125), (-172, -127), (282, 26), (43, 114), (52, -6), (-155, -212), (-187, 135), (125, -30), (-78, -80), (8, -165), (-292, -8), (140, -7), (-252, -254), (-47, -19), (292, -225)] # 15 : [(-214, -223), (65, 86), (113, -226), (227, -199), (8, -5), (94, 193), (-218, -280), (108, -30), (206, 217), (-21, -292), (215, 112), (-289, -86), (-127, 50), (-257, 298), (-194, 254)] # 15 : [(-158, 54), (181, -2), (-55, -230), (158, 192), (106, -216), (150, -88), (156, -245), (-22, 261), (67, 2), (-47, -27), (81, -28), (81, -252), (290, -54), (282, 286), (-32, -188)] # 15 : [(166, 27), (-152, 245), (-152, 79), (-64, 298), (259, -222), (98, 177), (38, 227), (-40, -201), (55, 68), (-291, 272), (60, -232), (143, -282), (-86, 49), (53, 270), (160, -177)] # 25 : [(-98, 152), (8, 295), (-153, -130), (-272, 86), (-92, 57), (157, 255), (-121, 134), (-42, -17), (-57, -238), (-290, -26), (-233, 8), (-271, 160), (27, 43), (-32, 292), (108, -297), (-41, 207), (67, -111), (-209, -224), (172, -288), (255, -136), (105, -229), (166, 42), (-145, -288), (33, 193), (77, 78)] # 7 : [(76, -55), (-297, -51), (162, -110), (-50, -9), (125, 18), (-21, 35), (-259, 175), (-194, 23), (-243, -147), (181, -288)] # 30 : [(-168, -165), (94, -217), (-10, 185), (-90, 224), (-140, 246), (189, 28), (297, -126), (-211, 290), (71, -6), (-298, -79), (-78, 51), (277, -97), (135, 56), (47, 107), (182, -138), (258, -241), (-292, 3), (257, -188), (227, -261), (90, -2), (-228, 19), (153, -44), (-169, -146), (225, 33), (78, 166), (142, 238), (0, -105), (217, 83), (211, -195), (-142, -79)] # 30 : [(253, 63), (-202, 25), (117, -194), (271, 247), (-84, -96), (145, 215), (-81, -145), (157, -297), (-157, 80), (217, 164), (175, -253), (-190, -48), (-122, 193), (253, -268), (-211, -81), (-121, 64), (-249, -25), (244, 298), (-42, 98), (-144, 218), (42, -56), (-141, 118), (125, 63), (-119, -21), (-79, 238), (21, 272), (100, -107), (147, 25), (-170, -54), (260, 267)]