예제 #1
0
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
예제 #2
0
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()
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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()