Dies ist eine alte Version des Dokuments!
18.03.2020
[18:58 Uhr] Aktuelle Programmversion
import bpy from random import random, randint from math import * import numpy as np import time from bpy_extras.mesh_utils import ngon_tessellate # KLASSEN class Sphere(object): pos = np.array([0,0,0]) radius = 0 epsilon = 0.001 def __init__(self, pos, radius): self.pos = pos self.radius = radius def punktInKugel(self, p): if (abstandPunkte(self.pos, p) < self.radius - self.epsilon): return True else: return False class Tetraeder(object): verts = [] faces = [] sp = np.array([0,0,0]) name = "tetraeder" umkugel = Sphere(np.array([0,0,0]), 0) def __init__(self, verts, name): self.name = name self.verts = verts self.faces = [(0,1,2),(1,2,3),(2,3,0),(3,0,1)] if (self.schwerpunkt()[0] != None): self.sp = self.schwerpunkt() self.umkugel = Sphere(self.sp,abstandPunkte(self.sp,self.verts[0])) else: self.sp = np.array([None,None,None]) def schwerpunkt(self): v1 = np.subtract(self.verts[1],self.verts[0]) v2 = np.subtract(self.verts[2],self.verts[0]) v3 = np.subtract(self.verts[3],self.verts[0]) sp = tetraSchwerpunkt(self.verts[0],v1,v2,v3) return sp def selfRender(self, ker, col, tetra): frei = True for m in range(0, len(ker)): if (self.umkugel.punktInKugel(ker[m]) == True): frei = False if (frei == True): generateObj("Tetraeder", t.verts, t.faces, (0,0,0), col) tetra.append(self) class Gerade(object): ov = (0,0,0) rv = (0,0,0) kreuzt = False kerne = [0,0] def __init__(self,ov,rv,kerne = [0,0]): self.ov = ov self.rv = rv self.kerne = kerne def punktAn(self,k): punkt = np.add(self.ov,(self.rv[0]*k,self.rv[1]*k,self.rv[2]*k)) return punkt # FUNKTIONEN def schnittTest(g1,g2): a = [[g2.rv[0],-g1.rv[0]],[g2.rv[1],-g1.rv[1]]] b = [[g1.ov[0]-g2.ov[0]],[g1.ov[1]-g2.ov[1]]] c = [[g2.rv[2],-g1.rv[2]],[g2.rv[1],-g1.rv[1]]] d = [[g1.ov[2]-g2.ov[2]],[g1.ov[1]-g2.ov[1]]] e = [[g2.rv[2],-g1.rv[2]],[g2.rv[0],-g1.rv[0]]] f = [[g1.ov[2]-g2.ov[2]],[g1.ov[0]-g2.ov[0]]] #print("Det :",np.linalg.det(a)) if (np.linalg.det(a) != 0): return np.linalg.solve(a,b)[0][0] elif (np.linalg.det(c) != 0): print(">> ERGEBNIS") return np.linalg.solve(c,d)[0][0] elif (np.linalg.det(e) != 0): print(">> SINBEGRE") return np.linalg.solve(e,f)[0][0] else: return None def schnittPunkt(g1,g2): z = schnittTest(g1,g2) if (z != None): return g2.punktAn(z) else: return np.array([None,None,None]) def dreieckSchwerpunkt(pos,a,b): g1 = Gerade(pos,a) g2 = Gerade(pos,b) c = kreuzProdukt(a,b) d = kreuzProdukt(a,c) e = kreuzProdukt(b,c) g3 = Gerade(g1.punktAn(.5), np.divide(d, 40)) g4 = Gerade(g2.punktAn(.5), np.divide(e, 40)) schnitt = schnittPunkt(g3,g4) return schnitt def tetraSchwerpunkt(pos, v1, v2, v3): #print("tetraSchwerpunkt") sp1 = dreieckSchwerpunkt(pos, v1, v2) sp2 = dreieckSchwerpunkt(pos, v1, v3) #print(pos, v1, v2, v3, sp1, sp2) if (sp1[0] != None and sp2[0] != None): g1 = Gerade(sp1, kreuzProdukt(v1, v2)) g2 = Gerade(sp2, kreuzProdukt(v1, v3)) schnitt = schnittPunkt(g1, g2) #print("Tetraschwerpunkt :",schnitt) return schnitt else: return np.array([None,None,None]) def abstandPunkte(p1, p2): a = sqrt(((p1[0]-p2[0])**2) + ((p1[1]-p2[1])**2) + ((p1[2]-p2[2])**2)) return a def zeichnePunkt(pos, name = "Punkt"): verts = [(0.1,0.1,0.1),(-0.1,0.1,0.1),(-0.1,-0.1,0.1),(0.1,-0.1,0.1) ,(0.1,0.1,-0.1),(-0.1,0.1,-0.1),(-0.1,-0.1,-0.1),(0.1,-0.1,-0.1)] faces = [(0,1,2,3),(4,5,6,7),(0,1,5,4),(1,2,6,5),(2,3,7,6),(3,0,4,7)] generateObj(name,verts,faces,pos) def kreuzProdukt(a,b): c = (a[1]*b[2]-a[2]*b[1] , a[2]*b[0]-a[0]*b[2] , a[0]*b[1]-a[1]*b[0]) return c def genKerne(anzahl, x_max, y_max, z_max): ker = [] for n in range(0, anzahl): x = randint(-x_max, x_max)*((random()/(1+random()))) y = randint(-y_max, y_max)*((random()/(1+random()))) z = randint(-z_max, z_max)*((random()/(1+random()))) if (len(ker) != 0): neu = True for m in range(0, len(ker)): if (x == ker[m][0] and y == ker[m][1] and z == ker[m][2]): neu = False if (neu == True): ker.append([x,y,z]) #zeichnePunkt(ker[n]) else: n = n-1 else: ker.append([x,y,z]) #zeichnePunkt(ker[n]) return ker # AB HIER ERSTELLUNG DER ZELLWÄNDE def radianBetweenVectors(v1, v2, n): # berechnet den Zwischenwinkel zweier Vektoren unter Beachtung eines Normalenwinkels # (später wird für n die Flächennormale der Zellwand eingesetzt, welche die Verbindung der # beiden Knotenpunkte ist, zwischen denen sich die Zellwand befindet). a = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] b = v1[0]*v2[1]*n[2] + v2[0]*n[1]*v1[2] + n[0]*v1[1]*v2[2] - v1[2]*v2[1]*n[0] - v2[2]*n[1]*v1[0] - n[2]*v1[1]*v2[0] rad = np.arctan2(b, a) if (rad < 0): rad = (2*np.pi) +rad deg = rad*180/np.pi #print(">> v02", rad, deg, "\n") return deg def polySortListNEW(v_list, normal): # soll eine Liste von Punkten im Kreis herum links herum anordnen # falls es ein Dreieck ist, ist die Reihenfolge egal if (len(v_list) == 3): return v_list # Startvariablen werden gesetzt geordnet = [] start = v_list[0] aktu = start vv = np.subtract(v_list[0], v_list[1]) # Vergleichswinkel, der zufällig gewählt wird (zeigt immer aus dem Kreis raus) geordnet.append(start) while True: print(">>", aktu) # loop start values min_angle = 360 min_stelle = 0 # suche nach nächstem Punkt for v in range(0, len(v_list)): if (aktu[0] != v_list[v][0] or aktu[1] != v_list[v][1] or aktu[2] != v_list[v][2]): dir = np.subtract(v_list[v], aktu) deg = radianBetweenVectors(vv, dir, normal) #np.array([0,0,1])) if (deg < min_angle): min_angle = deg min_stelle = v geordnet.append(v_list[min_stelle]) vv = np.subtract(v_list[min_stelle], aktu) aktu = v_list[min_stelle] print(" >", aktu) if (aktu[0] == start[0] and aktu[1] == start[1] and aktu[2] == start[2]): break return geordnet def genPoly(liste, normal): # sortiert die gegebene Vertecie- Liste im Kreis herum und erstellt dann daraus eine saubere Fläche. geordnet = polySortListNEW(liste, normal) f = [] for i in range(0, len(geordnet)): f.append(i) facelist = [] facelist.append(f) generateObj("Zellwand", geordnet, facelist) def generateObj(name, verts, faces, loc = np.array([0,0,0]), col = ( 1.0, 1.0, 1.0, 1.0 )): # generiert ein Objekt mit den Übergebenen Parametern (Name, Eckpunkte, Seiten) mymesh = bpy.data.meshes.new(name) myobject = bpy.data.objects.new(name,mymesh) mymat = bpy.data.materials.new("Mesh_mat") mymat.diffuse_color = col mymesh.materials.append(mymat) myobject.location = loc bpy.context.collection.objects.link(myobject) mymesh.from_pydata(verts,[],faces) mymesh.update(calc_edges=True) # ZUORDNUNG DER WÄNDE ZU KOLLEKTIONEN def createCollection(name): col = bpy.data.collections.new(name) bpy.context.scene.collection.children.link(col) return col def linkToCollection(obj, col): col.objects.link(obj) # CODE col = createCollection('Delaunay') col = createCollection('Voronoi') x_max = 100 y_max = 100 z_max = 100 anzahlKerne = 25 del_col = (1.0, 0.0, 0.0, 1) tetra = [] ker = genKerne(anzahlKerne, x_max, y_max, z_max) #ker = [[0.5993280181021913, -0.4902980267777478, -0.49501317000167505], [-0.5435355585699094, -0.5797131146501373, 5.358814201657665], [0.3314129669573313, 0.06170948842793362, -0.7049448015853017], [3.1586485852091704, -3.5930246037937623, 0.4050221351432125], [2.3720126622528435, -0.1444049711022323, -0.8239078280684086], [2.737558129947007, 3.263776842262023, -4.292689464037283], [-2.3210411603088885, -3.869616290303755, 0.9243976566069152], [0.2993804076152454, -0.5199510038865012, 0.28987243247419864], [8.201747317589948, 0.6535831987234019, 3.6830815010667664], [-0.42647813347859526, -1.5289270142358882, -0.08034527427391898], [3.9377606048318166, -4.865271969576239, 1.2243584468694046], [0.806041393229286, 0.0, 0.07921029485036851], [0.6137190460585324, 1.535243528493868, -1.600612893884901], [1.1540597542694828, 3.1304758799406356, 2.411227237265708], [1.5083371322537722, 0.059994185768576916, -1.96459150755497], [0.00978110076824692, 0.5153349359712261, 7.447412675253049], [-2.162426719288622, -0.18758603781988797, 1.874187393501292], [-1.2861520576937593, 2.255844853091784, -1.9755975108667347], [4.448892338753108, -2.247797498228902, -2.316136846836149], [0.0, 0.0, 0.2953965724182989]] print("\n\n",ker,"\n\n") for i in range(0, len(ker)): for j in range(i+1, len(ker)): for k in range(j+1, len(ker)): for l in range(k+1, len(ker)): t = Tetraeder([ker[i], ker[j], ker[k], ker[l]],"Tetraeder") t.selfRender(ker, del_col, tetra) print(tetra, len(tetra)) count = 0 for u in range(0, len(ker)): for v in range(u+1, len(ker)): z_verts = [] count = 0 for w in range(0, len(tetra)): if ((ker[u] in tetra[w].verts) and (ker[v] in tetra[w].verts)): z_verts.append(tetra[w].sp) if (len(z_verts) > 2): normal = np.subtract(ker[u], ker[v]) genPoly(z_verts, normal)