Monday, 23 September 2019

draw vertical line to camera center in arcore

i have some horizontal plane, where i set the start point of line i want to draw.

Now i want to make a vertical line from start point to the center of camera, aka ArFragment. Current i make it as follow

// 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
....

and this works as expected as long as i can hold smartphone vertical. When i rotate the camera, the line is no more drawed to middle because the created anchor is no more in the middle of screen.

Is there a official or better way to make a vertical line as expected no matter how i hold a smartphone?

UPDATE

now i have reached to create a line by calculate a point of intersection.

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);

The only problem is that the line must be exactly in the middle (right, left) of smartphone

smartphone center on line

in other case the line is too big or too small

smartphone center right of line

sphere shows the middle of camera

UPDATE 2

Some more explanation

enter image description here

we set somewhere in xz-room a startpoint of vertical line.

Then we are some away from the line and look at the point where we want the end of line.

Now i look at the problem in 2D and imagine, that my camera start and end point are in same xy-room as line and calculate the endpoint of line.

The Problem

my start and end points of camera view has different z as the line i draw.

To find is the point (and his y-value) on camera view vector that is in same xy-room as line (z of line = z of point)



from draw vertical line to camera center in arcore

No comments:

Post a Comment