Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ws1617:dreieckologie_23.02.17

23.02.2017

In den letzten drei Wochen haben wir an dem Problem sich berührender Flächen gearbeitet; denn für die Triangulierung müssen die Schnittpunkte erkannt und die übrigen Flächen richtig trianguliert werden. Nach langwierigen Versuchen haben wir mit Stefans Hilfe eine funktionierende Funktion geschrieben, die man hier sehen kann:

# -*- coding: utf-8 -*-
from __future__ import division
from __future__ import print_function
import numpy as np
import union_example as ue
import fensterwand as fw
import raw_list_to_stl as rlts
from stl import mesh
 
 
fenster = fw.Fensterwand(10, (0, 0, 0), (1, 0, 0), (1, 1, 1))
ecken = fenster.getPoints()
ecken_2 = rlts.raw_list_to_cooked_list(ecken)
 
boxen = []
for box in ecken_2:
	boxen.append(ue.make_box(box[0], box[6]))
 
i = 0
while i<len(boxen) - 1:
	boxen[i+1]=boxen[i].union(boxen[i+1])
	i+=1
 
 
vertices, polygons, count = boxen[len(boxen)-1].toVerticesAndPolygons()
 
triangles = ue.create_triangles(vertices, polygons)
 
mesh =  mesh.Mesh(np.zeros(len(triangles), dtype=mesh.Mesh.dtype))
 
for i, f in enumerate(triangles):
    for j in range(3):
        mesh.vectors[i][j] = vertices[int(f[j])]
 
 
mesh.save("cool.stl")

In diesem Programm wird die Funktion „union_example“ importiert. Diese erstellt zuerst Vierecke mit den Eck- und Schnittpunkten sich berührender Flächen, die dann in Dreiecke umgewandelt werden.

 
import numpy as np
from csg.core import CSG
from stl import mesh
 
 
def make_box(corner1,  corner2):
    '''erzeugt einen Quader, durch zwei gegenüberliegende Ecken definiert.'''
    box = CSG.cube(center = list(0.5*(np.array(corner1)+np.array(corner2))), 
        radius = list(0.5*np.abs((np.array(corner2)-np.array(corner1)))))
    return box
 
def between(a,b,x, epsilon=1e-10):
    '''checks whether x lies between a and b in 3-d space'''
    a = np.array(a)
    b = np.array(b)
    x = np.array(x)
    if np.linalg.norm(np.cross(b-a, x-a))<epsilon*np.linalg.norm(b-a):
        if 0<=np.dot(x-a,b-a)<=np.dot(b-a,b-a):
            return True
    return False
 
 
def create_triangles(vertices, polygons):
    '''given are lists of vertices (3-tuples) and polygons (n-gons
    with n>3, only tested for n=4) as a list of lists of indices. 
 
    The polygons cover a surface, but vertices  may appear 
    only on on side of an edge, not on the other. The function
    collects all vertices that -- geometrically -- lie between
    the endpoints of an edge.  
 
    The polygons thus obtained are triangulated by a rather 
    stupid algorithm. 
 
    returns: the list of triangles, each triangle being a list
            of three indices.
 
    '''
 
 
    vertices = [np.array(v) for v in vertices]
    triangles = []
    for poly in polygons:
        edges =[]
        for i in range(len(poly)):
            begin = poly[i]
            end = poly[(i+1)%len(poly)]
            edge=[]
            for i,v in enumerate(vertices):
                if between(vertices[begin],vertices[end],v):
                    edge.append(i)
 
 
            edge.sort(key=lambda ind: np.dot(vertices[ind]-vertices[begin], vertices[end]-vertices[begin]))
            edges.append(edge)
 
 
 
        print poly, edges
 
        # total is the sequence of vertices around the polygon,
        # which in our application is a rectangle. edges is a list
        # list of corners, where each sublist is collinear (i.e. lies
        # on one of the edges of the rectangle).
 
 
        # choose a corner point a
 
        a = edges[0][0]
        right_edge = edges[0]
        left_edge = edges[-1]
 
        # points b and c are the first and last point 
        # connected to a
 
        b = edges[1][1]
        c = edges[-2][-2]
 
        # connect this point by triangles to all "opposite" point pairs
        # exlude the incident edges
 
        for i in range(1, len(edges)-1):
            edge = edges[i]
            if i == 1:
                for j in range(1,len(edge)-1):
                    triangles.append ( [a, edge[j], edge[j+1]])
            elif i == len(edges)-2:
                for j in range(len(edge)-2):
                    triangles.append ( [a, edge[j], edge[j+1]])
            else:
                for j in range(len(edge)-1):
                    triangles.append ( [a, edge[j], edge[j+1]])
 
        #  now triangulate the area adjacent to the two incident edges
 
        for i in range(len(right_edge)-1):
            triangles.append( [right_edge[i], right_edge[i+1], b])
        for i in range(len(left_edge)-1):
            triangles.append( [left_edge[i], left_edge[i+1], c])
 
    return triangles
ws1617/dreieckologie_23.02.17.txt · Zuletzt geändert: 2017/02/23 14:00 von SoenkeRoos96