Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ws1920:cd_u03 [2020/03/25 16:46] Zetraeder angelegt |
ws1920:cd_u03 [2020/03/25 16:50] (aktuell) Zetraeder |
||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
----- | ----- | ||
- | ====== Aktueller Code ====== | + | ====== Code: Update 03 ====== |
- | **06.02.2020** | + | **09.02.2020** |
[[ws1920:cd_09|<<]] | [[ws1920:scutoids|Home]] | [[ws1920:update_03|Text]] | [[ws1920:cd_10|>>]] | [[ws1920:cd_09|<<]] | [[ws1920:scutoids|Home]] | [[ws1920:update_03|Text]] | [[ws1920:cd_10|>>]] | ||
+ | |||
+ | Hier ist der aktuelle Code für Blender 3D: | ||
+ | |||
+ | <code python> | ||
+ | |||
+ | 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) | ||
+ | | ||
+ | def __init__(self,ov,rv): | ||
+ | self.ov = ov | ||
+ | self.rv = rv | ||
+ | | ||
+ | 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,4,5),(1,2,4,5),(2,3,6,7),(3,0,7,4)] | ||
+ | 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 | ||
+ | |||
+ | def generateObj(name, verts, faces, loc = np.array([0,0,0]), col = ( 1.0, 1.0, 1.0, 1.0 )): | ||
+ | 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) | ||
+ | |||
+ | def genMesh(pointList): | ||
+ | | ||
+ | vertex = [] | ||
+ | l = len(pointList) | ||
+ | | ||
+ | for i in range(0, l): | ||
+ | for j in range (0, l): | ||
+ | for k in range (0, l): | ||
+ | vertex.append([i,j,k]) | ||
+ | | ||
+ | generateObj("whatever", pointList , vertex) | ||
+ | |||
+ | 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) > 0): | ||
+ | genMesh(z_verts) | ||
+ | |||
+ | </code> |