我有一个晶格三维晶格,大小为 lx * ly * lz,三边都有周期性边界条件。我的平面对称切割是垂直于 xy 平面、yz 平面和 xz 平面的两个水平和垂直平面(斜率 0 和 inf)加上两个对角线切割(斜率 -1 和 +1)。所以我总共有 9 种类型的平面,它们都穿过晶格点而不是它们之间。
这些切口中的每一个都可以在垂直于它们的平面上的任何位置通过。例如,垂直于 xy 平面的坡度 0 切口可以在任何 ly 点处通过。垂直于 xy 平面的斜率 inf 切割可以在任何 lx 点处通过。垂直于 xy 平面的坡度 +1 切口可以通过任何 lx 相交。垂直于 xy 平面的斜率 -1 切口可以穿过任何 ly 相交点。
现在给定一个位于 0 和 (lx * ly * lz)-1 之间的格子上的站点 i,我想反映一下 1 到 9 之间的任何一个随机切割 c。最好在"C"中计算反射晶格位点的最快算法是什么。
该算法应采用三个输入,即站点 i、切割 c 的类型以及切割通过的相交点,介于 0 和 lx-1 或 0 和 ly-1 或 ly-1 或 0 和 lz-1 之间,具体取决于切割和输出反射的站点。
平面写为方程
与其说"斜率",我宁愿谈论这些平面的法线。所以我理解你的问题的方式,你有
xy plane, slope 0 ⇒ normal (0, 1, 0)
xy plane, slope ∞ ⇒ normal (1, 0, 0)
xy plane, slope 1 ⇒ normal (1, -1, 0)
xy plane, slope -1 ⇒ normal (1, 1, 0)
xz plane, slope 0 ⇒ normal (0, 0, 1)
xz plane, slope ∞ ⇒ normal (1, 0, 0)
xz plane, slope 1 ⇒ normal (1, 0, -1)
xz plane, slope -1 ⇒ normal (1, 0, 1)
yz plane, slope 0 ⇒ normal (0, 0, 1)
yz plane, slope ∞ ⇒ normal (0, 1, 0)
yz plane, slope 1 ⇒ normal (0, 1, -1)
yz plane, slope -1 ⇒ normal (0, 1, 1)
所以9种平面将对应于法线方向
(1, 0, 0), (0, 1, 0), (0, 0, 1),
(1, 1, 0), (1, 0, 1), (0, 1, 1),
(1, -1, 0), (1, 0, -1), (0, 1, -1)
对于这些方向中的每一个,您都可以将法向量(a, b, c)
转换为平面方程:
a*x + b*y + c*z = d
但是d
的哪些值是可以允许的呢?对于上面的第一行,平行于其中一个坐标平面的平面,事情很简单:对于(a, b, c) = (1, 0, 0)
,你有0 ≤ d < lx
,而其他两个则类似。对于对角线平面,您的(在我看来很奇怪)拦截规则成立。如果我理解正确,(1, -1, 0)
平面可以穿过x
轴上的任何一点,再次导致0 ≤ d < lx
。(1, 1, 0)
平面可以穿过y
轴上的任何点,因此您必须0 ≤ d < ly
.对于其他对角线,请自己制定d
界限。
在这样的平面上反射
所以现在你有一个平面的方程,并希望在该平面中反射。Woodface提供的链接基本上是正确的,但你可能更喜欢这个想法的更简单的表述。首先将平面的方程重写为
a*x + b*y + c*z - d = 0
如果左侧不为零,则给定点不在平面上。在这种情况下,您获得的值与该点与平面的距离成正比。暂时假设a²+b²+c²=1
.在这种情况下,左侧的值确实是与平面的距离。将该数字乘以法向量(a, b, c)
得到一个从平面指向相关点的向量。将数量乘以-(a, b, c)
,你会得到一个从点指向平面的向量,乘以-2*(a, b, c)
得到一个从点指向其镜像的向量。
但如果a²+b²+c²≠1
呢?在这种情况下,等式左侧的值将是实际距离的 sqrt(a²+b²+c²)
倍。您将该距离乘以一个没有单位长度而是sqrt(a²+b²+c²)
长度的向量,因此您的最终结果向量将太大,总共a²+b²+c²
倍。所以你所做的就是按这个因素进行缩放。
总结一下:反映您计算a*x + b*y + c*z = d
平面中的点(x, y, z)
(x, y, z) - 2/(a² + b² + c²)*(a*x + b*y + c*z - d)*(a, b, c)
或用 C 代码编写:
int f = 2/(a*a + b*b + c*c)*(a*x + b*y + c*z - d);
x = x - f*a;
y = y - f*b;
z = y - f*z;
您可以在此处使用int
,因为对于普通向量,a²+b²+c²
要么是 1
要么是 2
,因此2/(a*a + b*b + c*c)
将始终是整数。