def printToCSG(self, f): o = Options() maxhFiller = o.getProperty('maxh_f') s = 'solid polygonalDisk{3} = plane({0}, {1}, {2}; ' f.write(s.format(self.values['topCenter'].x(), self.values['topCenter'].y(), self.values['topCenter'].z(), self.number())) s = '{0}, {1}, {2}) ' dx = self.values['topCenter'].x() - self.values['botCenter'].x() dy = self.values['topCenter'].y() - self.values['botCenter'].y() dz = self.values['topCenter'].z() - self.values['botCenter'].z() f.write(s.format(dx, dy, dz)) s = 'and plane({0}, {1}, {2}; ' f.write(s.format(self.values['botCenter'].x(), self.values['botCenter'].y(), self.values['botCenter'].z())) dx = -self.values['topCenter'].x() + self.values['botCenter'].x() dy = -self.values['topCenter'].y() + self.values['botCenter'].y() dz = -self.values['topCenter'].z() + self.values['botCenter'].z() f.write('{0}, {1}, {2})'.format(dx, dy, dz)) for facet in self.values['facets']: f.write(' and plane({0}, {1}, {2}; '.format(facet.x(), facet.y(), facet.z())) c = self.c() dfc = facet - c f.write('{0}, {1}, {2})'.format(dfc.x(), dfc.y(), dfc.z())) f.write(';\n')
def decompose(basis, vector): o = Options() epsilon = o.getProperty('epsilon') axeVector = basis[0] basisVector1 = basis[1] basisVector2 = basis[2] x1 = axeVector.x() x2 = basisVector1.x() x3 = basisVector2.x() y1 = axeVector.y() y2 = basisVector1.y() y3 = basisVector2.y() z1 = axeVector.z() z2 = basisVector1.z() z3 = basisVector2.z() a = vector.x() b = vector.y() c = vector.z() determinant = det([[x1, x2, x3], [y1, y2, y3], [z1, z2, z3]]) if abs(determinant) < epsilon: print('Determinant = ', determinant) pprint([[x1, x2, x3], [y1, y2, y3], [z1, z2, z3]]) alpha = det([[a, x2, x3], [b, y2, y3], [c, z2, z3]]) / determinant beta = det([[x1, a, x3], [y1, b, y3], [z1, c, z3]]) / determinant gamma = det([[x1, x2, a], [y1, y2, b], [z1, z2, c]]) / determinant return [alpha, beta, gamma]
def checkPercolation(pcs): """If there is a chain including a particle and its periodic image, there is percolation in the system""" o = Options() crossings = [[i] for i in range(len(pcs))] for i in range(len(pcs)): for j in range(i + 1, len(pcs)): pc1 = pcs[i] pc2 = pcs[j] if disksInTheShellCross(pc1, pc2): print(i, j) crossings[i].append(j) crossings[j].append(i) for j in range(len(crossings)): for k in range(len(crossings[j])): if k == 0: continue else: for element in crossings[j]: if element not in crossings[crossings[j][k]]: crossings[crossings[j][k]].append(element) toPop = [] for i in range(len(crossings)): if len(crossings[i]) == 1: if not i in toPop: toPop.append(i) for i in toPop[::-1]: crossings.pop(i) for i, crossing in enumerate(crossings): crossings[i] = set(crossing) toPop = [] for i in range(len(crossings)): for j in range(i + 1, len(crossings)): if crossings[i] - crossings[j] == set(): if not i in toPop: toPop.append(i) print(toPop) for i in toPop[::-1]: crossings.pop(i) pprint(crossings) names = [] for j, crossing in enumerate(crossings): names.append([]) for i in crossing: names[j].append(pcs[i].number()) for i in range(len(pcs)): for namesString in names: string1 = str(i) for j in range(27): string2 = '0' * j + string1 if string1 in namesString and string2 in namesString: print(percolation) # names = [] # for i in crossings: # for j in i: # print(int(pcs[j].number()), end=' ') # print() return None
def __init__(self, disks): o = Options() E_f = o.getProperty('E_f') nu_f = o.getProperty('nu_f') E_m = o.getProperty('E_m') nu_m = o.getProperty('nu_m') E_sh = o.getProperty('E_sh') nu_sh = o.getProperty('nu_sh') f = open('materials.txt', 'w') C = [[[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]], [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]], [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]] #for particle in range(len(disks)): if len(disks) > 0: la = E_f * nu_f / (1.0 - 2 * nu_f) / (1 + nu_f) mu = E_f / 2 / (1 + nu_f) for i in range(3): for j in range(3): for k in range(3): for l in range(3): C[i][j][k][l] = la * delta(i, j) * delta(k, l) C[i][j][k][l] += mu * delta(i, k) * delta(j, l) C[i][j][k][l] += mu * delta(i, l) * delta(j, k) f.write(str(C[i][j][k][l]) + ' ') f.write('\n') #for particle in range(len(disks)): if len(disks) > 0: la = E_sh * nu_sh / (1.0 - 2 * nu_sh) / (1 + nu_sh) mu = E_sh / 2 / (1 + nu_sh) for i in range(3): for j in range(3): for k in range(3): for l in range(3): C[i][j][k][l] = la * delta(i, j) * delta(k, l) C[i][j][k][l] += mu * delta(i, k) * delta(j, l) C[i][j][k][l] += mu * delta(i, l) * delta(j, k) f.write(str(C[i][j][k][l]) + ' ') f.write('\n') la = E_m * nu_m / (1.0 - 2 * nu_m) / (1 + nu_m) mu = E_m / 2 / (1 + nu_m) for i in range(3): for j in range(3): for k in range(3): for l in range(3): C[i][j][k][l] = la * delta(i, j) * delta(k, l) C[i][j][k][l] += mu * delta(i, k) * delta(j, l) C[i][j][k][l] += mu * delta(i, l) * delta(j, k) f.write(str(C[i][j][k][l]) + ' ')
def findBorders(self): o = Options() minx = miny = minz = 1000000 maxx = maxy = maxz = -1000000 s = o.getProperty('shellThickness') c = self.c() for facet in self.values['facets']: vToFacet = Vector(self.c(), facet) l = vToFacet.l() vToFacet = vToFacet * ((l + s) / l) realFacet = c + vToFacet if realFacet.x() < minx: minx = realFacet.x() if realFacet.x() > maxx: maxx = realFacet.x() if realFacet.y() < miny: miny = realFacet.y() if realFacet.y() > maxy: maxy = realFacet.y() if realFacet.z() < minz: minz = realFacet.z() if realFacet.z() > maxz: maxz = realFacet.z() return [minx, maxx, miny, maxy, minz, maxz]
def boxCross(disk): o = Options() additiionalEmptiness = max( o.getProperty('maxh_f'), # t oavoid errors o.getProperty('maxh_sh'), # in netgen nesh o.getProperty('maxh_m')) # generation length = o.getProperty('cubeEdgeLength') c = disk.c() tc = disk.tc() bc = disk.bc() r = disk.r() h = disk.h() v = len(disk.facets()) vtb = Vector(bc, tc) responce = '' for facet in disk.facets(): vToFacet = facet - c vInFacet = vtb.vectorMultiply(vToFacet) realLength = vInFacet.l() needLength = r * math.tan(math.pi / v) vInFacet = vInFacet * (needLength / realLength) x4 = facet + vInFacet + vtb / 2 x5 = facet - vInFacet + vtb / 2 x6 = facet + vInFacet - vtb / 2 x7 = facet - vInFacet - vtb / 2 if additiionalEmptiness > x4.x() or x5.x() < additiionalEmptiness: return True if additiionalEmptiness > x6.x() or x7.x() < additiionalEmptiness: return True if additiionalEmptiness > x4.y() or x5.y() < additiionalEmptiness: return True if additiionalEmptiness > x6.y() or x7.y() < additiionalEmptiness: return True if additiionalEmptiness > x4.z() or x5.z() < additiionalEmptiness: return True if additiionalEmptiness > x6.z() or x7.z() < additiionalEmptiness: return True if x4.x() > length - additiionalEmptiness or\ x5.x() > length - additiionalEmptiness: return True if x4.y() > length - additiionalEmptiness or\ x5.y() > length - additiionalEmptiness: return True if x4.z() > length - additiionalEmptiness or\ x5.z() > length - additiionalEmptiness: return True if x6.x() > length - additiionalEmptiness or\ x7.x() > length - additiionalEmptiness: return True if x6.y() > length - additiionalEmptiness or\ x7.y() > length - additiionalEmptiness: return True if x6.z() > length - additiionalEmptiness or\ x7.z() > length - additiionalEmptiness: return True return False
def mainExfoliation(): o = Options() maxhMatrix = o.getProperty('maxh_m') maxhFiller = o.getProperty('maxh_f') maxhShell = o.getProperty('maxh_sh') desiredDisksNumber = int(o.getProperty('numberOfDisks')) maxAttempts = o.getProperty('maxAttempts') pcs = [] l = o.getProperty('cubeEdgeLength') #cellString = 'solid cell = orthobrick(0, 0, 0;' #cellString += ' {0}, {0}, {0});\n'.format(l) cellString = 'solid cell = plane(0, 0, {0}; 0, 0, {0})'.format(l) cellString += ' and plane(0, {0}, 0; 0, {0}, 0)'.format(l) cellString += ' and plane({0}, 0, 0; {0}, 0, 0)'.format(l) cellString += ' and plane(0, 0, 0; 0, 0, -{0})'.format(l) cellString += ' and plane(0, 0, 0; 0, -{0}, 0)'.format(l) cellString += ' and plane(0, 0, 0; -{0}, 0, 0);\n'.format(l) matrixString = 'solid matrix = cell' attempt = 0 v = o.getProperty('verticesNumber') r = o.getProperty('polygonalDiskRadius') h = o.getProperty('polygonalDiskThickness') ready = 0 tmpPcs = [] while ready < desiredDisksNumber and attempt < maxAttempts: attempt += 1 if len(pcs) > 0: name = int(pcs[len(pcs) - 1].number()) + 1 pc = PolygonCylinderInTheShell(r, h, name, int(v)) else: pc = PolygonCylinderInTheShell(r, h, 0, int(v)) random.seed(datetime.now()) alpha = random.random() * 2 * math.pi beta = random.random() * 2 * math.pi gamma = random.random() * 2 * math.pi # rotate around 0x pc.changeByMatrix( np.array([[1, 0, 0, 0], [0, math.cos(alpha), -math.sin(alpha), 0], [0, math.sin(alpha), math.cos(alpha), 0], [0, 0, 0, 1]])) # rotate around 0y pc.changeByMatrix( np.array([[math.cos(beta), 0, math.sin(beta), 0], [0, 1, 0, 0], [-math.sin(beta), 0, math.cos(beta), 0], [0, 0, 0, 1]])) # rotate around 0z pc.changeByMatrix( np.array([[math.cos(gamma), -math.sin(gamma), 0, 0], [math.sin(gamma), math.cos(gamma), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])) # translate into random point of the box dx = l * random.random() dy = l * random.random() dz = l * random.random() pc.changeByMatrix( np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [dx, dy, dz, 1]])) tmpPcs = [] copiedCount = 0 pcToCheck = None for ix in [-1, 0, 1]: for iy in [-1, 0, 1]: for iz in [-1, 0, 1]: pc1 = copy.copy(pc) pc1.setCopied(copiedCount) copiedCount += 1 pc1.changeByMatrix( np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [ix * l, iy * l, iz * l, 1]])) tmpPcs.append(pc1) if (ix, iy, iz) == (0, 0, 0): pcToCheck = pc1 flag = 0 for oldPc in pcs: #for pc in tmpPcs: # if disksCross(oldPc, pc) or\ # disksCross(pc, oldPc) or\ # diskDiskInTheShellCross(oldPc, pc) or\ # diskDiskInTheShellCross(pc, oldPc): # flag = 1 # break if disksCross(oldPc, pc) or\ disksCross(pc, oldPc) or\ diskDiskInTheShellCross(oldPc, pc) or\ diskDiskInTheShellCross(pc, oldPc): flag = 1 break if flag != 1: ready += 1 for pc in tmpPcs: pcs.append(pc) toPop = [] for i, pc in enumerate(pcs): c = pc.c() if not 0 < c.x() < l or not 0 < c.y() < l or not 0 < c.z() < l: if not boxCrossByDiskInTheShell(pc): toPop.append(i) for i in toPop[::-1]: pcs.pop(i) s = 'End of attempt {0} ready {1} of {2}' print(s.format(attempt, ready, desiredDisksNumber)) print('Checking for percolation len is {}'.format(len(pcs))) for pc in pcs: print(pc) checkPercolation(pcs) s = ' and not filler and not shell;\ntlo matrix -transparent -maxh={0};\n' matrixString += s.format(maxhMatrix) f = open(o.getProperty('fname'), 'w') f.write('algebraic3d\n') f.write(cellString) if len(pcs) > 0: fillerString = 'solid filler = cell and (' shellString = 'solid shell = cell and (' for i, pc in enumerate(pcs): pc.printToCSG(f) if i != 0: fillerString += ' or polygonalDisk{0}'.format(pc.number()) shellString += ' or pdShell{0}'.format(pc.number()) else: fillerString += 'polygonalDisk{0}'.format(pc.number()) shellString += 'pdShell{0}'.format(pc.number()) fillerString += ');\ntlo filler -maxh={0};\n'.format(maxhFiller) s = ') and not filler;\ntlo shell -maxh={0};\n' shellString += s.format(maxhShell) f.write(fillerString) f.write(shellString) f.write(matrixString) print('Volume fraction is {}'.format(ready * math.pi * r**2 * h / l**3)) mp = MatricesPrinter(pcs) pp = PropertiesPrinter(pcs)
def disksCross(disk1, disk2): o = Options() epsilon = o.getProperty('roughEpsilon') c1 = disk1.c() tc1 = disk1.tc() bc1 = disk1.bc() c2 = disk2.c() dc12 = c1 - c2 l = dc12.l() r = disk1.r() h = disk1.h() v = len(disk1.facets()) if 2 * (r**2 + h**2 / 4)**0.5 < l**0.5: return False elif h > l: return True # http://mathworld.wolfram.com/Line-PlaneIntersection.html # facet of disk2 and top or bottom of disk1 vtb1 = Vector(bc1, tc1) tc2 = disk2.tc() bc2 = disk2.bc() vtb2 = Vector(bc2, tc2) for (x1, x2, x3) in [ ( c1 + vtb1 / 2, # top disk1.facets()[0] + vtb1 / 2, disk1.facets()[1] + vtb1 / 2), ( c1 - vtb1 / 2, # bottom disk1.facets()[0] - vtb1 / 2, disk1.facets()[1] - vtb1 / 2) ]: v12 = Vector(x2, x1) v32 = Vector(x2, x3) for facet in disk2.facets(): vToFacet = Vector(c2, facet) vInFacet = vtb2.vectorMultiply(vToFacet) realLength = vInFacet.l() needLength = r * math.tan(math.pi / v) vInFacet = vInFacet * (needLength / realLength) for (x4, x5) in [ ( facet + vInFacet + vtb2 / 2, # top edge facet - vInFacet + vtb2 / 2), ( facet + vInFacet - vtb2 / 2, # bottom edge facet - vInFacet - vtb2 / 2) ]: v42 = Vector(x2, x4) v52 = Vector(x2, x5) det1 = np.linalg.det( np.array([[v12.x(), v12.y(), v12.z()], [v32.x(), v32.y(), v32.z()], [v42.x(), v42.y(), v42.z()]])) det2 = np.linalg.det( np.array([[v12.x(), v12.y(), v12.z()], [v32.x(), v32.y(), v32.z()], [v52.x(), v52.y(), v52.z()]])) if -epsilon < det1 < epsilon or -epsilon < det2 < epsilon: l = ((r / math.cos(math.pi / v))**2 + h**2 / 4)**0.5 if Vector(x1, x4).l() < r / math.cos(math.pi / v): return True if Vector(x1, x5).l() < r / math.cos(math.pi / v): return True #return True elif det1 * det2 < -epsilon: v45 = Vector(x4, x5) pti = x4 + v45 * abs(det1) / (abs(det1) + abs(det2)) if Vector(x1, pti).l() < r: return True for facet1 in disk1.facets(): x1 = facet1 vToFacet1 = Vector(x1, c1) vInFacet1 = vtb1.vectorMultiply(vToFacet1) needLength = r * math.tan(math.pi / v) realLength = vInFacet1.l() vInFacet *= needLength / realLength x2 = x1 + vInFacet + vtb1 / 2 x3 = x1 - vInFacet + vtb1 / 2 v12 = Vector(x2, x1) v32 = Vector(x2, x3) for facet2 in disk2.facets(): vToFacet = Vector(c2, facet) vInFacet = vtb2.vectorMultiply(vToFacet) realLength = vInFacet.l() needLength = r * math.tan(math.pi / v) vInFacet = vInFacet * (needLength / realLength) for (x4, x5) in [ ( facet + vInFacet + vtb2 / 2, # top edge facet - vInFacet + vtb2 / 2), ( facet + vInFacet - vtb2 / 2, # bottom edge facet - vInFacet - vtb2 / 2) ]: v42 = Vector(x4, x2) v52 = Vector(x5, x2) det1 = np.linalg.det( np.array([[v12.x(), v12.y(), v12.z()], [v32.x(), v32.y(), v32.z()], [v42.x(), v42.y(), v42.z()]])) det2 = np.linalg.det( np.array([[v12.x(), v12.y(), v12.z()], [v32.x(), v32.y(), v32.z()], [v52.x(), v52.y(), v52.z()]])) if -epsilon < det1 < epsilon: xi = x4 vectori = Vector(x1, xi) cos = (abs(vectori.x() * vtb1.x() + vectori.y() * vtb1.y() + vectori / z() * vtb1 / z())) / vectori.l() / vtb1.l() sin = (1 - cos**2)**0.5 axelen = cos * vectori.l() norlen = sin * vectori.l() if axelen < (vtb1 / 2).l() and norlen < needLength: return True elif -epsilon < det2 < epsilon: xi = x5 vectori = Vector(x1, xi) cos = (abs(vectori.x() * vtb1.x() + vectori.y() * vtb1.y() + vectori / z() * vtb1 / z())) / vectori.l() / vtb1.l() sin = (1 - cos**2)**0.5 axelen = cos * vectori.l() norlen = sin * vectori.l() if axelen < (vtb1 / 2).l() and norlen < needLength: return True elif det1 * det2 < -epsilon: xi = x4 + Vector( x4, x5) * (abs(det1)) / (abs(det1) + abs(det2)) vectori = Vector(x1, xi) cos = (abs(vectori.x() * vtb1.x() + vectori.y() * vtb1.y() + vectori / z() * vtb1 / z())) / vectori.l() / vtb1.l() sin = (1 - cos**2)**0.5 axelen = cos * vectori.l() norlen = sin * vectori.l() if axelen < (vtb1 / 2).l() and norlen < needLength: return True return False
def mainExfoliation(): o = Options() maxhMatrix = o.getProperty('maxh_m') desiredDisksNumber = int(o.getProperty('numberOfDisks')) maxAttempts = o.getProperty('maxAttempts') maxhMatrix = o.getProperty('maxh_m') maxhFiller = o.getProperty('maxh_f') pcs = [] l = o.getProperty('cubeEdgeLength') attempt = 0 v = o.getProperty('verticesNumber') r = o.getProperty('polygonalDiskRadius') h = o.getProperty('polygonalDiskThickness') while len(pcs) < desiredDisksNumber and attempt < maxAttempts: attempt += 1 pc = PolygonCylinder(r, h, len(pcs), int(v)) random.seed(datetime.now()) alpha = random.random() * 2 * math.pi beta = random.random() * 2 * math.pi gamma = random.random() * 2 * math.pi # rotate around 0x pc.changeByMatrix( np.array([[1, 0, 0, 0], [0, math.cos(alpha), -math.sin(alpha), 0], [0, math.sin(alpha), math.cos(alpha), 0], [0, 0, 0, 1]])) # rotate around 0y pc.changeByMatrix( np.array([[math.cos(beta), 0, math.sin(beta), 0], [0, 1, 0, 0], [-math.sin(beta), 0, math.cos(beta), 0], [0, 0, 0, 1]])) # rotate around 0z pc.changeByMatrix( np.array([[math.cos(gamma), -math.sin(gamma), 0, 0], [math.sin(gamma), math.cos(gamma), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])) # translate into random point of the box dx = l * random.random() dy = l * random.random() dz = l * random.random() pc.changeByMatrix( np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [dx, dy, dz, 1]])) flag = 0 if boxCross(pc): continue for oldPc in pcs: if disksCross(oldPc, pc) or disksCross(pc, oldPc): flag = 1 if flag == 0: pcs.append(pc) print('End of attempt {0} ready {1} of {2}'.format( attempt, len(pcs), desiredDisksNumber)) f = open(o.getProperty('fname'), 'w') f.write('algebraic3d\n') cellString = 'solid cell = plane(0, 0, {0}; 0, 0, {0})'.format(l) cellString += ' and plane(0, {0}, 0; 0, {0}, 0)'.format(l) cellString += ' and plane({0}, 0, 0; {0}, 0, 0)'.format(l) cellString += ' and plane(0, 0, 0; 0, 0, -{0})'.format(l) cellString += ' and plane(0, 0, 0; 0, -{0}, 0)'.format(l) cellString += ' and plane(0, 0, 0; -{0}, 0, 0);\n'.format(l) matrixString = 'solid matrix = cell and not filler' f.write(cellString) if len(pcs) > 0: fillerString = 'solid filler = cell and (' for i, pc in enumerate(pcs): pc.printToCSG(f) if i != 0: fillerString += ' or polygonalDisk{0}'.format(pc.number()) else: fillerString += 'polygonalDisk{0}'.format(pc.number()) fillerString += ');\ntlo filler -maxh={0};\n'.format(maxhFiller) f.write(fillerString) matrixString += ';\ntlo matrix -transparent -maxh={0};'.format(maxhMatrix) f.write(matrixString) print('Volume fraction is {}'.format(len(pcs) * math.pi * r**2 * h / l**3)) mp = MatricesPrinter(pcs) pp = PropertiesPrinter(pcs)
def boxCrossByDiskInTheShell(disk): o = Options() length = o.getProperty('cubeEdgeLength') c = disk.c() s = o.getProperty('shellThickness') tc = disk.tc() bc = disk.bc() r = disk.r() h = disk.h() v = len(disk.facets()) vtb = Vector(bc, tc) vtb = vtb * (2 * s + h) / h responce = [0 for i in range(6)] for facet in disk.facets(): ifcrossx = False ifcrossy = False ifcrossz = False ptOnFacet = c + (facet - c) / r * (r + s) vToFacet = facet - c vInFacet = vtb.vectorMultiply(vToFacet) realLength = vInFacet.l() needLength = (r + s) * math.tan(math.pi / v) vInFacet = vInFacet * (needLength / realLength) x1 = ptOnFacet + vInFacet + vtb / 2 x2 = ptOnFacet + vInFacet - vtb / 2 x3 = ptOnFacet - vInFacet + vtb / 2 x4 = ptOnFacet - vInFacet - vtb / 2 if x1.x() * x2.x() < 0 or x1.x() * x3.x() < 0 or x1.x() * x4.x() < 0: ifcrossx = True if (x1.x() - length) * (x2.x() - length) < 0 or\ (x1.x() - length) * (x3.x() - length) < 0 or\ (x1.x() - length) * (x4.x() - length) < 0: ifcrossx = True if x1.y() * x2.y() < 0 or x1.y() * x3.y() < 0 or x1.y() * x4.y() < 0: ifcrossy = True if (x1.y() - length) * (x2.y() - length) < 0 or\ (x1.y() - length) * (x3.y() - length) < 0 or\ (x1.y() - length) * (x4.y() - length) < 0: ifcrossy = True if x1.z() * x2.z() < 0 or x1.z() * x3.z() < 0 or x1.z() * x4.z() < 0: ifcrossz = True if (x1.z() - length) * (x2.z() - length) < 0 or\ (x1.z() - length) * (x3.z() - length) < 0 or\ (x1.z() - length) * (x4.z() - length) < 0: ifcrossz = True if ifcrossx and not ifcrossy and not ifcrossz: if 0 < c.y() < length and 0 < c.z() < length: return True if ifcrossy and not ifcrossx and not ifcrossz: if 0 < c.x() < length and 0 < c.z() < length: return True if ifcrossz and not ifcrossy and not ifcrossx: if 0 < c.y() < length and 0 < c.x() < length: return True if ifcrossx and ifcrossy and not ifcrossz: if 0 < c.z() < length: return True if ifcrossx and ifcrossz and not ifcrossy: if 0 < c.y() < length: return True if ifcrossz and ifcrossy and not ifcrossx: if 0 < c.x() < length: return True if ifcrossx and ifcrossy and ifcrossz: return True return False
def printToCSG(self, f): o = Options() l = o.getProperty('cubeEdgeLength') h = 0.01 cellString = ' and plane(0, 0, {0}; 0, 0, {0})'.format(l - h) cellString += ' and plane(0, {0}, 0; 0, {0}, 0)'.format(l - h) cellString += ' and plane({0}, 0, 0; {0}, 0, 0)'.format(l - h) cellString += ' and plane({1}, {1}, {1}; 0, 0, -{0})'.format(l - h, h) cellString += ' and plane({1}, {1}, {1}; 0, -{0}, 0)'.format(l - h, h) cellString += ' and plane({1}, {1}, {1}; -{0}, 0, 0)'.format(l - h, h) h = o.getProperty('polygonalDiskThickness') maxhFiller = o.getProperty('maxh_f') st = 'solid polygonalDisk{3} = plane({0}, {1}, {2}; ' f.write( st.format(self.values['topCenter'].x(), self.values['topCenter'].y(), self.values['topCenter'].z(), self.number())) dx = self.values['topCenter'].x() - self.values['botCenter'].x() dy = self.values['topCenter'].y() - self.values['botCenter'].y() dz = self.values['topCenter'].z() - self.values['botCenter'].z() f.write('{0}, {1}, {2}) '.format(dx, dy, dz)) st = 'and plane({0}, {1}, {2}; ' f.write( st.format(self.values['botCenter'].x(), self.values['botCenter'].y(), self.values['botCenter'].z())) dx = -self.values['topCenter'].x() + self.values['botCenter'].x() dy = -self.values['topCenter'].y() + self.values['botCenter'].y() dz = -self.values['topCenter'].z() + self.values['botCenter'].z() f.write('{0}, {1}, {2})'.format(dx, dy, dz)) for facet in self.values['facets']: f.write(' and plane({0}, {1}, {2}; '.format( facet.x(), facet.y(), facet.z())) c = self.c() dfc = facet - c f.write('{0}, {1}, {2})'.format(dfc.x(), dfc.y(), dfc.z())) f.write(cellString) f.write(';\n') s = o.getProperty('shellThickness') v = Vector(self.bc(), self.tc()) v = v * (2 * s + h) / 2 / h pt = self.bc() / 2 + self.tc() / 2 + v st = 'solid pdShell{0} = plane({1}, {2}, {3}; ' f.write(st.format(self.number(), pt.x(), pt.y(), pt.z())) f.write('{0}, {1}, {2}) '.format(v.x(), v.y(), v.z())) pt = self.bc() / 2 + self.tc() / 2 - v f.write('and plane({1}, {2}, {3}; '.format(self.number(), pt.x(), pt.y(), pt.z())) f.write('{0}, {1}, {2}) '.format(-v.x(), -v.y(), -v.z())) for facet in self.values['facets']: vToFacet = Vector(self.c(), facet) l = vToFacet.l() vToFacet = vToFacet * ((l + s) / l) f.write(' and plane({0}, {1}, {2}; '.format( c.x() + vToFacet.x(), c.y() + vToFacet.y(), c.z() + vToFacet.z())) f.write('{0}, {1}, {2})'.format(vToFacet.x(), vToFacet.y(), vToFacet.z())) f.write(cellString) f.write(';\n')
def diskDiskInTheShellCross(disk1, disk2): o = Options() epsilon = o.getProperty('roughEpsilon') s = o.getProperty('shellThickness') c1 = disk1.c() tc1 = disk1.tc() bc1 = disk1.bc() c2 = disk2.c() dc12 = c1 - c2 l = dc12.l() r = disk1.r() h = disk1.h() v = len(disk1.facets()) if 2 * (r**2 + (h / 2 + 2 * s)**2)**0.5 < l: return False elif h + 2 * s > l: return True # facet of disk2 and top of disk1 vtb1 = Vector(bc1, tc1) vtb1 = vtb1 * (2 * s + h) / h tc2 = disk2.tc() bc2 = disk2.bc() vtb2 = Vector(bc2, tc2) for (x1, x2, x3) in [ ( c1 + vtb1 / 2, # top disk1.facets()[0] + vtb1 / 2, disk1.facets()[1] + vtb1 / 2), ( c1 - vtb1 / 2, # bottom disk1.facets()[0] - vtb1 / 2, disk1.facets()[1] - vtb1 / 2) ]: v12 = Vector(x2, x1) v32 = Vector(x2, x3) for facet in disk2.facets(): vToFacet = Vector(c2, facet) vInFacet = vtb2.vectorMultiply(vToFacet) realLength = vInFacet.l() needLength = r * math.tan(math.pi / v) vInFacet = vInFacet * (needLength / realLength) for (x4, x5) in [ ( facet + vInFacet + vtb2 / 2, # top edge facet - vInFacet + vtb2 / 2), ( facet + vInFacet - vtb2 / 2, # bottom edge facet - vInFacet - vtb2 / 2) ]: v42 = Vector(x2, x4) v52 = Vector(x2, x5) det1 = np.linalg.det( np.array([[v12.x(), v12.y(), v12.z()], [v32.x(), v32.y(), v32.z()], [v42.x(), v42.y(), v42.z()]])) det2 = np.linalg.det( np.array([[v12.x(), v12.y(), v12.z()], [v32.x(), v32.y(), v32.z()], [v52.x(), v52.y(), v52.z()]])) if -epsilon < det1 < epsilon or -epsilon < det2 < epsilon: l = ((r / math.cos(math.pi / v))**2 + h**2 / 4)**0.5 if Vector(x1, x4).l() < r / math.cos(math.pi / v): return True if Vector(x1, x5).l() < r / math.cos(math.pi / v): return True elif det1 < -epsilon: v45 = Vector(x4, x5) pti = x4 + v45 * abs(det1) / (abs(det1) + abs(det2)) if Vector(x1, pti).l() < r: return True return False
def disksInTheShellCross(disk1, disk2): o = Options() epsilon = o.getProperty('roughEpsilon') s = o.getProperty('shellThickness') length = o.getProperty('cubeEdgeLength') h = o.getProperty('polygonalDiskThickness') v = o.getProperty('verticesNumber') r = o.getProperty('polygonalDiskRadius') c1 = disk1.c() c2 = disk2.c() vtb1 = Vector(disk1.bc(), disk1.tc()) vtb1 *= (2 * s + h) / h vtb2 = Vector(disk2.bc(), disk2.tc()) vtb2 *= (2 * s + h) / h # facet of disk2 and top/bottom of disk1: for [x1, x2, x3] in [[ c1 + vtb1 / 2, disk1.facets()[0] + vtb1 / 2, disk1.facets()[1] + vtb1 / 2 ], [ c1 - vtb1 / 2, disk1.facets()[0] - vtb1 / 2, disk1.facets()[1] - vtb1 / 2 ]]: v12 = Vector(x2, x1) v32 = Vector(x2, x3) for facet2 in disk2.facets(): vToFacet = Vector(facet2, c2) vToFacet *= (s + r) / r vInFacet = vToFacet.vectorMultiply(vtb2) realLength = vInFacet.l() needLength = (r + s) * math.tan(math.pi / v) vInFacet *= needLength / realLength for [x4, x5] in [[ c2 + vToFacet + vtb2 / 2 + vInFacet, c2 + vToFacet + vtb2 / 2 - vInFacet ], [ c2 + vToFacet - vtb2 / 2 + vInFacet, c2 + vToFacet - vtb2 / 2 - vInFacet ], [ c2 + vToFacet + vtb2 / 2 + vInFacet, c2 + vToFacet - vtb2 / 2 + vInFacet ], [ c2 + vToFacet + vtb2 / 2 - vInFacet, c2 + vToFacet - vtb2 / 2 - vInFacet ]]: v42 = Vector(x2, x4) v52 = Vector(x2, x5) det1 = np.linalg.det( np.array([[v12.x(), v12.y(), v12.z()], [v32.x(), v32.y(), v32.z()], [v42.x(), v42.y(), v42.z()]])) det2 = np.linalg.det( np.array([[v12.x(), v12.y(), v12.z()], [v32.x(), v32.y(), v32.z()], [v52.x(), v52.y(), v52.z()]])) if abs(det1) < epsilon: if Vector(x4, x1).l() < r + s: return True elif abs(det2) < epsilon: if Vector(x5, x1).l() < r + s: return True elif det1 * det2 < 0: tmpVector = Vector( x4, x5) * abs(det1) / (abs(det1) + abs(det2)) if Vector(x1, x4 + tmpVector).l() < r + s: return True return False