def is_point_inside_cell(cell, point): """ Checks if a given triple-vector is inside the cell given by the basis matrix in cell """ p1 = FracVector((0, 0, 0)) p2 = cell[0] p3 = cell[1] p4 = cell[0] + cell[1] p5 = cell[2] p6 = cell[0] + cell[2] p7 = cell[1] + cell[2] p8 = cell[0] + cell[1] + cell[2] tetras = [None] * 6 tetras[0] = [p1, p2, p3, p6] tetras[1] = [p2, p3, p4, p6] tetras[2] = [p3, p4, p6, p8] tetras[3] = [p3, p6, p7, p8] tetras[4] = [p3, p5, p6, p7] tetras[5] = [p1, p3, p5, p6] for tetra in tetras: if is_point_inside_tetra(tetra, point): return True return False
def niggli_to_metric(niggli): niggli = FracVector.use(niggli) m = niggli.noms # Since the niggli matrix contains 2*the product of the off diagonal elements, we increase the denominator by cell.denom*2 return FracVector( ((2 * m[0][0], m[1][2], m[1][1]), (m[1][2], 2 * m[0][1], m[1][0]), (m[1][1], m[1][0], 2 * m[0][2])), niggli.denom * 2).simplify()
def is_point_inside_tetra(tetra, point): """ Checks if a point is inside the tretrahedra spanned by the coordinates in tetra """ D0 = FracVector(((tetra[0][0], tetra[0][1], tetra[0][2], 1), (tetra[1][0], tetra[1][1], tetra[1][2], 1), (tetra[2][0], tetra[2][1], tetra[2][2], 1), (tetra[3][0], tetra[3][1], tetra[3][2], 1))) D1 = FracVector(((point[0], point[1], point[2], 1), (tetra[1][0], tetra[1][1], tetra[1][2], 1), (tetra[2][0], tetra[2][1], tetra[2][2], 1), (tetra[3][0], tetra[3][1], tetra[3][2], 1))) D2 = FracVector(((tetra[0][0], tetra[0][1], tetra[0][2], 1), (point[0], point[1], point[2], 1), (tetra[2][0], tetra[2][1], tetra[2][2], 1), (tetra[3][0], tetra[3][1], tetra[3][2], 1))) D3 = FracVector(((tetra[0][0], tetra[0][1], tetra[0][2], 1), (tetra[1][0], tetra[1][1], tetra[1][2], 1), (point[0], point[1], point[2], 1), (tetra[3][0], tetra[3][1], tetra[3][2], 1))) D4 = FracVector(((tetra[0][0], tetra[0][1], tetra[0][2], 1), (tetra[1][0], tetra[1][1], tetra[1][2], 1), (tetra[2][0], tetra[2][1], tetra[2][2], 1), (point[0], point[1], point[2], 1))) d0 = D0.det() if d0 < 0: s0 = -1 else: s0 = 1 d1 = D1.det() d2 = D2.det() d3 = D3.det() d4 = D4.det() if abs(d0) == 0: return False if (d1.sign() == s0 or d1 == 0) and (d2.sign() == s0 or d2 == 0) and ( d3.sign() == s0 or d3 == 0) and (d4.sign() == s0 or d4 == 0): return True return False
def is_any_part_of_cube_inside_cell(cell, midpoint, side): """ Checks if any part of a cube is inside the cell spanned by the vectors in cell """ ps = [ midpoint + FracVector((x, y, z)) * side for x in [-1, 1] for y in [-1, 1] for z in [-1, 1] ] for p in ps: if is_point_inside_cell(cell, p): return True return False
def metric_to_niggli(cell): m = cell.noms return FracVector( ((m[0][0], m[1][1], m[2][2]), (2 * m[1][2], 2 * m[0][2], 2 * m[0][1])), cell.denom).simplify()