Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ws1920:cd_07 [2020/03/25 16:31] Zetraeder angelegt |
ws1920:cd_07 [2020/03/25 17:04] (aktuell) Zetraeder |
||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
----- | ----- | ||
- | ====== Aktueller Code ====== | + | ====== Code: Arbeitstermin 07 ====== |
- | **16.01.2020** | + | **23.01.2020** |
- | [[ws1920:cd_06|<<]] | [[ws1920:scutoids|Home]] | [[ws1920:arbeitstermin_07|Text]] | [[ws1920:cd_08|>>]] | + | [[ws1920:cd_u00|<<]] | [[ws1920:scutoids|Home]] | [[ws1920:arbeitstermin_07|Text]] | [[ws1920:cd_u01|>>]] |
Aktuelle Programmversion | Aktuelle Programmversion | ||
+ | |||
+ | <code python> | ||
+ | |||
+ | # -*- 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)] | ||
+ | |||
+ | </code> | ||
+ |