These functions provide the following functionality:
quadray_to_xyz: Converts a quadray (a, b, c, d) to Cartesian coordinates (x, y, z).
xyz_to_quadray: Converts Cartesian coordinates (x, y, z) to a quadray (a, b, c, d).
quadray_midpoint: Finds the midpoint between two quadrays.
quadray_distance: Calculates the Euclidean distance between two quadrays.
generate_fcc_quadrays: Generates the first n layers of the face-centered cubic (FCC) lattice using quadrays.
from math import sqrt
def quadray_to_xyz(quadray):
"""
Convert a quadray (a, b, c, d) to Cartesian coordinates (x, y, z).
"""
a, b, c, d = quadray
x = (a + b) / 2
y = (b + c) / 2
z = (c + d) / 2
return x, y, z
def xyz_to_quadray(x, y, z):
"""
Convert Cartesian coordinates (x, y, z) to a quadray (a, b, c, d).
"""
a = x - y + z
b = x + y - z
c = -x + y + z
d = -x - y - z
return a, b, c, d
def quadray_midpoint(q1, q2):
"""
Find the midpoint between two quadrays.
"""
return tuple((a + b) / 2 for a, b in zip(q1, q2))
def quadray_distance(q1, q2):
"""
Calculate the Euclidean distance between two quadrays.
"""
return sqrt(sum((a - b)**2 for a, b in zip(q1, q2)))
def generate_fcc_quadrays(n):
"""
Generate the first n layers of the face-centered cubic (FCC) lattice using quadrays.
"""
fcc_quadrays = [(0, 0, 0, 0)]
for layer in range(1, n + 1):
for a in range(layer + 1):
for b in range(layer + 1 - a):
c = layer - a - b
d = -layer
fcc_quadrays.append((a, b, c, d))
fcc_quadrays.append((a, b, d, c))
fcc_quadrays.append((a, c, b, d))
fcc_quadrays.append((a, c, d, b))
fcc_quadrays.append((a, d, b, c))
fcc_quadrays.append((a, d, c, b))
return fcc_quadrays
KU: Here’s my test drive of the above code. In canonical form, a Qvector should have only non-negative elements, and that rule is broken right away. However a non-normalized (a, b, c, d) might be the correct quadray once normalized, so I check that. I’d say none of these are usable, except the midpoint algorithm is actually correct if we ignore normalizing.