Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1920:tag_02_code

Dies ist eine alte Version des Dokuments!



Zweiter Tag: Aktueller Code

19.03.2020

<< | Home | Text | >>

[17:37] 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 polySortList(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 = polySortList(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)
 
def inListeAnStelle(element, liste):
    #   durchsucht eine Liste nach einem Vector und gibt die Stelle aus, falls es enthalten ist
    if element in liste:
        for i in range(0, len(liste)):
            if (element == liste[i]): return i
    return None
 
def inListeAnStelleNP(element, liste):
    #   durchsucht eine Liste von np.arrays nach einem np.array und gibt die Stelle aus,
    #   falls dieser enthalten ist
    for i in range(0, len(liste)):
        if (np.array_equal(element, liste[i])): return i
    return None   
 
 
 
#   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
 
 
vertex = [[] for dummy in range(anzahlKerne)]     #   liste alle vertecies, index markiert die Zellnummer, zu der sie gehören
faces = [[] for dummy in range(anzahlKerne)]      #   liste alle faces, index markiert die Zellnummer, zu der sie gehören
 
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])
            geordnet = polySortList(z_verts, normal)
 
            temp_face1 = []
            temp_face2 = []
 
            for i in range(0, len(geordnet)):
 
                if (inListeAnStelleNP(geordnet[i], vertex[u]) != None):
                    temp_face1.append(inListeAnStelleNP(geordnet[i], vertex[u]))
                else:
                   vertex[u].append(geordnet[i])
                   temp_face1.append(inListeAnStelleNP(geordnet[i], vertex[u]))
 
                if (inListeAnStelleNP(geordnet[i], vertex[v]) != None):
                    temp_face2.append(inListeAnStelleNP(geordnet[i], vertex[v]))
                else:
                   vertex[v].append(geordnet[i])
                   temp_face2.append(inListeAnStelleNP(geordnet[i], vertex[v]))
            faces[u].append(temp_face1)
            faces[v].append(temp_face2)
 
for i in range(0, anzahlKerne):
    generateObj("Zelle", vertex[i], faces[i])
ws1920/tag_02_code.1584635865.txt.gz · Zuletzt geändert: 2020/03/19 17:37 von Zetraeder