在arcore中画一条垂直线到相机中心

时间:2019-09-18 14:10:42

标签: android arcore

我有一些水平面,在其中设置了我要绘制的线的起点。

现在,我想从起点到相机中心(也称为ArFragment)制作一条垂直线。 目前我做到了

// create an anchor 1 meter away of current camera position and rotation
Anchor anchor = arFragment.getArSceneView().getSession().createAnchor(
            arFragment.getArSceneView().getArFrame().getCamera().getPose()
                    .compose(Pose.makeTranslation(0, 0, -1f))
                    .extractTranslation());

// create AnchorNode with position data of Anchor
AnchorNode anchorNode = new AnchorNode(anchor);
// remove anchor to be free change position of AnchorNode
anchorNode.setAnchor(null);
// get local position of new anchor node
Vector3 newLocPos = anchorNode.getLocalPosition();

// get the local position of start node
Vector3 fromVector = fromNode.getLocalPosition();

// since we want to make vertical line, set x and z of new AnchorNode to same as start
newLocPos.x = fromVector.x;
newLocPos.z = fromVector.z;
// set updated position data to new AnchorNode
anchorNode.setLocalPosition(newLocPos);
// set scene as parent to have node in UI
anchorNode.setParent(arFragment.getArSceneView().getScene());

// draw line between Nodes
....

,只要我能垂直握住智能手机,它就会按预期工作。 当我旋转摄像机时,该线不再画到中间,因为创建的锚点不再在屏幕中间。

无论我如何握住智能手机,是否都有官方或更好的方法来制作垂直线?

更新

现在我已经可以通过计算相交点来创建一条线了。

private static MyPoint calculateIntersectionPoint(MyPoint A, MyPoint B, MyPoint C, MyPoint D) {
    // Line AB represented as a1x + b1y = c1
    double a1 = B.y - A.y;
    double b1 = A.x - B.x;
    double c1 = a1 * (A.x) + b1 * (A.y);

    // Line CD represented as a2x + b2y = c2
    double a2 = D.y - C.y;
    double b2 = C.x - D.x;
    double c2 = a2 * (C.x) + b2 * (C.y);

    double determinant = a1 * b2 - a2 * b1;

    if (determinant == 0) {
        // The lines are parallel. This is simplified
        // by returning a pair of FLT_MAX
        return new MyPoint(Double.MAX_VALUE, Double.MAX_VALUE);
    } else {
        double x = (b2 * c1 - b1 * c2) / determinant;
        double y = (a1 * c2 - a2 * c1) / determinant;
        return new MyPoint(x, y);
    }
}


MyPoint interceptionPoint = calculateIntersectionPoint(
    new MyPoint(line1From.getWorldPosition().x, line1From.getWorldPosition().y),
    new MyPoint(line1To.getWorldPosition().x, line1To.getWorldPosition().y),
    new MyPoint(line2From.getWorldPosition().x, line2From.getWorldPosition().y),
    new MyPoint(line2To.getWorldPosition().x, line2To.getWorldPosition().y));

// get local position of new anchor node
Vector3 newLocPos = anchorNode.getWorldPosition();
// since we want to make vertical line, set x and z of new AnchorNode to same as start
newLocPos.y = (float) interceptionPoint.y;
newLocPos.x = fromVector.x;
newLocPos.z = fromVector.z;

// set updated position data to new AnchorNode
anchorNode.setWorldPosition(newLocPos);

唯一的问题是该行必须恰好在智能手机的中间(右,左)

smartphone center on line

在其他情况下,行太大或太小

smartphone center right of line

球形显示摄像头的中央

更新2

更多说明

enter image description here

我们在xz房间的某个地方设置了垂直线的起点。

然后我们离线有些距离,然后看一下我们想要线末端的点。

现在,我查看2D问题并想象,我的摄像机起点和终点与线位于同一xy室中,并计算线的终点。

问题

我的相机视图的起点和终点与我画的线具有不同的z。

要找到摄影机视图矢量上与线(z线=点的z线)位于同一xy空间的点(及其y值)

有任何想法吗?

1 个答案:

答案 0 :(得分:0)

作为您的步骤之一,您似乎正在从anchorNode中移除锚点-我认为这是因为您想移动anchorNode,但是我怀疑这是问题的根源。

下面的代码将在任意两个anchorNode之间绘制一条线,并在旋转相机时保持在原处(允许设备发生任何小错误或移动)。这是从此答案(https://stackoverflow.com/a/52816504/334402)中获取的,并内置到下面链接的项目中,因此您可以进行检查:

PT20M28S

您可以在此处查看完整的代码:https://github.com/mickod/LineView