Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ws1920:update_02 [2020/02/09 21:30] Zetraeder |
ws1920:update_02 [2020/03/25 16:36] (aktuell) Zetraeder |
||
---|---|---|---|
Zeile 4: | Zeile 4: | ||
**05.02.2020** | **05.02.2020** | ||
- | [[ws1920:arbeitstermin_08|<<]] | [[ws1920:scutoids|Home]] | [[ws1920:arbeitstermin_09|>>]] | + | [[ws1920:arbeitstermin_08|<<]] | [[ws1920:scutoids|Home]] | [[ws1920:cd_u02|Code]] | [[ws1920:arbeitstermin_09|>>]] |
[ Lukas ] | [ Lukas ] | ||
Zeile 10: | Zeile 10: | ||
Die Delaunay - Tetraedisierung wurde nun implementiert und funktioniert mehr oder weniger zuverlässig. Das Programm wählt nach dem Kugelkriterium die richtigen Tetraeder aus und fügt diese dem Viewport hinzu. | Die Delaunay - Tetraedisierung wurde nun implementiert und funktioniert mehr oder weniger zuverlässig. Das Programm wählt nach dem Kugelkriterium die richtigen Tetraeder aus und fügt diese dem Viewport hinzu. | ||
- | {{:ws1920:solid.jpg?200|}} | + | {{:ws1920:solid.jpg?320|}} |
- | {{:ws1920:wireframe.jpg?200|}} | + | {{:ws1920:wireframe.jpg?320|}} |
**Kugelkriterium** Es wird über eine zufällige Punktmenge iteriert und jede mögliche Kombination für vier verschiedene Kerne überprüft. Vier Punkte bestimmen (mathematisch bewiesen!) eine Kugel eindeutig, somit testen wir für alle Kombinationen (äquivalent zum zweidimensionalen Fall), ob sich weitere Kerne innerhalb der aufgespannten Kugel befinden. Ist dies der Fall, handelt es sich bei der zu überprüfenden Kombination NICHT um ein Tetraeder der Delaunay - Tetraedisierung (Begriff von uns eingeführt) - andernfalls handelt es sich um eines der gesuchten Volumina. | **Kugelkriterium** Es wird über eine zufällige Punktmenge iteriert und jede mögliche Kombination für vier verschiedene Kerne überprüft. Vier Punkte bestimmen (mathematisch bewiesen!) eine Kugel eindeutig, somit testen wir für alle Kombinationen (äquivalent zum zweidimensionalen Fall), ob sich weitere Kerne innerhalb der aufgespannten Kugel befinden. Ist dies der Fall, handelt es sich bei der zu überprüfenden Kombination NICHT um ein Tetraeder der Delaunay - Tetraedisierung (Begriff von uns eingeführt) - andernfalls handelt es sich um eines der gesuchten Volumina. | ||
Außerdem wurde der lästige Fehler "LinalgError Singular Matrix" durch Ausschluss der Determinante = 0 ausgemerzt. | Außerdem wurde der lästige Fehler "LinalgError Singular Matrix" durch Ausschluss der Determinante = 0 ausgemerzt. | ||
- | |||
- | <code python> | ||
- | |||
- | import bpy | ||
- | from random import random, randint | ||
- | from math import * | ||
- | import numpy as np | ||
- | |||
- | |||
- | |||
- | # 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): | ||
- | print(abstandPunkte(self.pos, p), self.radius) | ||
- | 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): | ||
- | frei = True | ||
- | for m in range(0, len(ker)): | ||
- | if (self.umkugel.punktInKugel(ker[m]) == True): | ||
- | frei = False | ||
- | print("shit", ker[m]) | ||
- | if (frei == True): | ||
- | generateObj("Tetraeder", t.verts, t.faces, (0,0,0)) | ||
- | #zeichnePunkt(t.sp, "Schwerpunkt") | ||
- | | ||
- | 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]]] | ||
- | | ||
- | print("Det :",np.linalg.det(a)) | ||
- | if (np.linalg.det(a) != 0): | ||
- | return np.linalg.solve(a,b)[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): | ||
- | print("DreieckSchwerpunkt") | ||
- | | ||
- | 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) | ||
- | #eichnePunkt(schnitt, "Dreieckschwerpunkt") | ||
- | 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): | ||
- | mymesh = bpy.data.meshes.new(name) | ||
- | myobject = bpy.data.objects.new(name,mymesh) | ||
- | |||
- | myobject.location = loc #(0,0,0) #bpy.context.scene.cursor.location | ||
- | bpy.context.collection.objects.link(myobject) | ||
- | |||
- | mymesh.from_pydata(verts,[],faces) | ||
- | mymesh.update(calc_edges=True) | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | # CODE | ||
- | |||
- | x_max = 10 | ||
- | y_max = 10 | ||
- | z_max = 10 | ||
- | ker = genKerne(20, x_max, y_max, z_max) | ||
- | |||
- | 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)): | ||
- | print(str(i),str(j),str(k),str(l)) | ||
- | | ||
- | t = Tetraeder([ker[i], ker[j], ker[k], ker[l]],"Tetraeder") | ||
- | t.selfRender(ker) | ||
- | |||
- | </code> | ||
---- | ---- | ||