Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1920:tag_01_code

Erster Tag: Aktueller Code

18.03.2020

Home | Text | >>

[18:58 Uhr] Das Skript ist momentan in der Lage, die einzelnen Zellwände entsprechend der Generierung im Raum zu erstellen und diese durch den neuen Code sauber darzustellen. Wie im Bild zu sehen kann nun ohne Probleme auf Wireframe-Modus umgestellt werden, ohne dass der PC abstürzt (wir verbuchen das als plus).


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)
ws1920/tag_01_code.txt · Zuletzt geändert: 2020/03/19 15:16 von Zetraeder