我有两个一模一样的东西和两个摄像头。我想要达到的目标如下:
1)捕捉立方体A相对于相机A的位置和旋转。
2)将其转移到立方体B,以便在照相机B(我不能移动)中,Cube B看起来与A相机中的Cube A完全一样
我成功地使用以下代码进行了定位:
positionDifference = CubeA.InverseTransformPoint(CameraA.transform.position);为了把它转移到立方体B,我需要:
cubeBpos = transform.InverseTransformPoint(CubeB.transform.localPosition);
while ( Mathf.Abs (cubeBpos.x + positionDifference.x) > 0.01f ) {
if (cubeBpos.x + positionDifference.x > 0) {
CubeB.transform.position += new Vector3(-0.01f, 0, 0);
}
else if (cubeBpos.x + positionDifference.x < 0) {
CubeB.transform.position += new Vector3(+0.01f, 0, 0);
}
cubeBpos = transform.InverseTransformPoint(CubeB.transform.position);
}很笨重,但很管用。然而,当我试图转移旋转,立方B开始枢轴围绕着原点。有趣的是,当我在世界坐标中移动立方体A时,立方体B在局部移动,反之亦然。我怀疑本地到世界的坐标转换是一个问题,但我也认为我的旋转代码是天真的。我试着用两种方式来捕捉旋转,首先是这样的:
rotationDifference = Quaternion.Inverse(CubeA.transform.rotation) * CameraA.transform.rotation;
CubeB.transform.rotation = Quaternion.Inverse(rotationDifference);第二次尝试:
rotationDifference = new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, transform.eulerAngles.z);
CubeB.transform.eulerAngles = rotationDifference;这两种方法都产生了奇怪的旋转偏移。我试着使用localPosition和localEulerAngles,但没有帮助。
我希望有一个更聪明的方法来做到这一点:)
编辑:下面是这个项目的一个Dropbox 链接
发布于 2017-10-03 20:23:13
问题是,虽然位置和旋转相互影响,但它们是分开处理的。让我们将两者结合起来,假设我们有两个摄像机和两个立方体的模型转换(用齐次矩阵表示;假设列向量)。然后,我们要找到多维数据集B TCubeB的转换,这样:
TCameraA^-1 * TCubeA = TCameraB^-1 * TCubeB请注意,TCamera是相机的模型转换,而不是视图矩阵。如果您有视图矩阵,只需忽略逆。
我们可以立即解决TCubeB
TCameraB * TCameraA^-1 * TCubeA = TCubeB我不太熟悉Unity,但似乎不能直接使用转换矩阵。让我们把变换矩阵T除以转动部分R和平移部分Tr
TrCameraB * RCameraB * (TrCameraA * RCameraA)^-1 * TrCubeA * RCubeA = TrCubeB * RCubeB
TrCameraB * RCameraB * RCameraA^-1 * TrCameraA^-1 * TrCubeA * RCubeA = TrCubeB * RCubeB如果我们只关心旋转,那么只需做以下操作就可以计算出相应的四元数:
QCameraB * QCameraA^-1 * QCubeA = QCubeB翻译变得有点困难。我们需要找到翻译转换,这样
TrCameraB * RCameraB * RCameraA^-1 * TrCameraA^-1 * TrCubeA * RCubeA * RCubeB^-1 = TrCubeB要找到翻译向量,只需将原点乘到左侧:
TrCameraB * RCameraB * RCameraA^-1 * TrCameraA^-1 * TrCubeA * RCubeA * RCubeB^-1 * (0, 0, 0, 1)在伪码中,这归结为(所显示的矩阵代表各自的翻译向量):
Vector4 translation = (0, 0, 0, 1)
translation += TrCubeA
translation -= TrCameraA
translation = RCameraA.Inverse().Transform(translation)
translation = RCameraB.Transform(translation)
translation += TrCameraB再说一遍,我几乎不知道Unity,它可能会使用一些与我不同的约定(转换数学中的约定特别棘手)。但我相信,如果有什么不正确的地方,你可以修改上面的推导。
发布于 2017-10-04 10:11:07
Nico的出色答案解决了我的问题,但是由于注释部分中的代码格式并不是为此而构建的,下面是我根据Nico的答案为Unity编写的代码:
Vector3 translation = new Vector3(0,0,0);
translation += cubeA.transform.position;
translation -= cameraA.transform.position;
translation = cameraA.transform.InverseTransformPoint(translation);
translation = cameraB.transform.TransformPoint(translation/2);
cubeB.transform.position = translation;
Quaternion rotation = Quaternion.identity;
rotation = cameraB.transform.rotation * Quaternion.Inverse(cameraA.transform.rotation) * cubeA.transform.rotation;
cubeB.transform.rotation = rotation;这不是一对一,但它实现了我所希望的:如果立方体A是静止的,相机A在它周围移动,那么立方体B相对于相机B移动的方式是,立方体A和立方体B对各自的相机总是有完全相同的位置和旋转。
https://stackoverflow.com/questions/46552263
复制相似问题