import math

n, h = map(int, input().split())
for _ in range(n):
    x, y, z = map(int, input().split())
    z_mirror = 2 * h - z
    g = math.gcd(math.gcd(abs(x), abs(y)), abs(z_mirror))
    i = x // g
    j = y // g
    k = z_mirror // g
    print(i, j, k)

几何分析

我们需要找到一个方向向量 (i, j, k),使得从原点 (0, 0, 0) 出发的激光经过水面 z = h 的反射后到达目标点 (x_i, y_i, z_i)。

反射的几何方法

在几何光学中,反射可以等效为“镜像法”。即,对于反射面 z = h,可以构造目标点关于水面的镜像点 (x_i, y_i, 2h - z_i)。然后,激光的方向就是从原点 (0, 0, 0) 指向镜像点 (x_i, y_i, h + h - z_i) 的方向。

这是因为:

  • 实际反射路径可以看作是激光直接穿过水面到达镜像点,但由于反射,实际路径是到达水面后反射到目标点。
  • 因此,方向向量可以是从原点到镜像点的方向。

方向向量的计算

镜像点的坐标为 (x_i, y_i, h + h - z_i)。因此,从原点 (0, 0, 0) 到镜像点 (x_i, y_i, h + h - z_i) 的方向向量为 x_i, y_i, h + h - z_i)。

但是,这个方向向量可能需要归一化或简化(即除以最大公约数 gcd(x_i, y_i, 2h - z_i))。

方向向量的简化

我们需要找到一个方向向量 (i, j, k) 使得:

  • (i, j, k) 与 (x_i, y_i, h + h - z_i) 成比例。
  • gcd(i, j, k) = 1。

因此,可以计算 (x_i, y_i, h + h - z_i) 的最大公约数 g = gcd(x_i, y_i, h + h - z_i),然后方向向量为 (x_i / g, y_i / g, (h + h - z_i) / g)。

注意事项

  1. gcd 的计算​:gcd 是三个数的最大公约数。可以先计算 gcd(x_i, y_i),然后计算 gcd(这个结果, z_mirror)。
  2. 负数的处理​:如果 z_i > h,那么 z_mirror = 2h - z_i 可能是负数。gcd 可以处理负数(因为 gcd(a, b) = gcd(|a|, |b|)),因此可以取绝对值或直接计算。
  3. 方向向量的方向​:题目没有要求方向向量的特定方向(正向或反向),因此比例后的方向向量是正确的。
  4. z_i = h 的情况​:如果 z_i = h,那么 z_mirror = h,方向向量是 (x_i, y_i, h)。这意味着激光直接射向水面上的点 (x_i, y_i, h),然后反射回自身。但根据题目描述,z_i 可以等于 h。