unity3d 将3D平面上的点转换为2D点的程序

qmelpv7a  于 2023-01-13  发布在  其他
关注(0)|答案(2)|浏览(236)

我有平面的法向量,我想把3D点转换到2D平面上,保持它们之间的距离不变,基本上我想做的是,使平面上所有点的z坐标相等,我怎么去实现这个,并为它写一个程序(最好是C#)?。有什么好的库我可以使用。这个库有用吗Point Cloud Library
我这样做的目的是在3D空间中有多条线(在同一平面上),我希望在2D中表示这些线沿着测量值
我的问题的一个示例平面。

我正在使用Google ARcore在Unity中开发一个应用程序

yyyllmsg

yyyllmsg1#

好的,我已经投入了相当多的时间来寻找这个问题的解决方案。我用ARcore找出了这个问题的简单解决方案,就像我用ARCore做这个一样(谷歌提供的增强现实SDK)。对于那些不想使用ARcore实现这一点的人,请参考这些问题Question 1Question 2,其中必须创建新的标准正交基或必须按顺序旋转平面以与默认平面对齐。
对于那些正在unity中使用ARcore的人来说,在这个由我创建的GitHub上的issue中给出了一个更简单的解决方案,基本上我们可以很容易地在3D平面上创建新的轴,并从这个新创建的坐标系中记录坐标。
如果你想把3d点投影到一个平面上,你需要有一个2d坐标系,一个自然的坐标系是由全局坐标轴定义的,但它只适用于一种平面(例如水平)而不是另一个坐标的另一个选择是由CenterPose定义的,但是它可以改变每一帧。所以如果你只需要一帧的2d点,这可以写成:

x_local_axis = DetectedPlane.CenterPose.rotation * Vector3.forward;
z_local_axis = DetectedPlane.CenterPose.rotation * Vector3.right;
// loop over your points
x = Vector3.Dot(your_3d_point, x_local_axis);
z = Vector3.Dot(your_3d_point, z_local_axis);

如果需要帧之间一致的2D坐标系,您可能希望将锚附加到任何感兴趣的平面(可能位于DetectedPlane.CenterPose),并执行与上面相同的数学运算,但使用锚点旋转而不是平面旋转。锚点的x轴和z轴将提供帧之间一致的2D坐标帧。
所以这里,在平面的中心创建新的局部轴,并且获得的点将只有2个坐标。

ckocjqey

ckocjqey2#

我需要在Unity C#中使用这个,所以这里有一些我使用的代码。
首先,将点投影到平面上,然后使用点值进行目标变换,得到局部的2D坐标。
所以如果你想要标准坐标,用(1,0)替换右边,用(0,1)替换右边

public static Vector3 GetClosestPointOnPlane(Vector3 point, Plane3D plane){
    Vector3 dir = point - plane.position;
    plane.normal = plane.normal.normalized;
    float dotVal = Vector3.Dot(dir.normalized, plane.normal);
    
    return point + plane.normal * dir.magnitude * (-dotVal);
}

    Intersection.Plane3D tempPlane = new Intersection.Plane3D(transform.position, transform.up);
    Vector3 closestPoint = Intersection.GetClosestPointOnPlane(testPoint.position, tempPlane);
    float xPos = Vector3.Dot((closestPoint - transform.position).normalized, transform.right);
    float yPos = Vector3.Dot((closestPoint - transform.position).normalized, transform.forward);

    float dist = (closestPoint - transform.position).magnitude;
    planePos = new Vector2(xPos * dist, yPos * dist);

    results.position = closestPoint;

相关问题