如何使用 ARCore 测量距离?

How to measure distance using ARCore?

是否可以计算两个 HitResult 之间的距离?

或者我们如何使用 ARCore 计算实际距离(例如米)?

您可以使用 getHitPose() and then compare their translation component (getTranslation()) 提取两个 HitResult 姿势。 翻译定义为

...the position vector from the destination (usually world) coordinate frame to the local coordinate frame, expressed in destination (world) coordinates.

至于这个的物理单位我找不到任何备注。使用经过校准的相机,这在数学上应该是可行的,但我不知道他们是否真的为此提供了 API

在 Java ARCore 世界单位是米(我刚刚意识到我们可能不会记录这个...... aaa 看起来没有。糟糕,提交错误)。通过减去两个 Pose 的翻译分量,您可以获得它们之间的距离。您的代码看起来像这样:

首次命中时 hitResult:

startAnchor = session.addAnchor(hitResult.getHitPose());

第二次命中时 hitResult:

Pose startPose = startAnchor.getPose();
Pose endPose = hitResult.getHitPose();

// Clean up the anchor
session.removeAnchors(Collections.singleton(startAnchor));
startAnchor = null;

// Compute the difference vector between the two hit locations.
float dx = startPose.tx() - endPose.tx();
float dy = startPose.ty() - endPose.ty();
float dz = startPose.tz() - endPose.tz();

// Compute the straight-line distance.
float distanceMeters = (float) Math.sqrt(dx*dx + dy*dy + dz*dz);

假设这些命中结果不会发生在同一帧上,创建一个 Anchor 很重要,因为每次调用 Session.update() 时都可以重塑虚拟世界。通过使用锚点而不是姿势来保持该位置,其姿势将更新以跟踪这些重塑过程中的物理特征。

答案是:当然可以,你绝对可以计算出两个HitResult之间的距离。 ARCore 以及 ARKit 框架的网格大小为 meters。有时,使用 centimetres 更有用。 Java 和伟大的旧 Pythagorean theorem:

有几种方法

import com.google.ar.core.HitResult

MotionEvent tap = queuedSingleTaps.poll();
if (tap != null && camera.getTrackingState() == TrackingState.TRACKING) {
    for (HitResult hit : frame.hitTest(tap)) {
        // Blah-blah-blah...
    }
}

// Here's the principle how you can calculate the distance  
// between two anchors in 3D space using Java:

private double getDistanceMeters(Pose pose0, Pose pose1) {

    float distanceX = pose0.tx() - pose1.tx();
    float distanceY = pose0.ty() - pose1.ty();
    float distanceZ = pose0.tz() - pose1.tz();

    return Math.sqrt(distanceX * distanceX + 
                     distanceY * distanceY + 
                     distanceZ * distanceZ);
} 

// Convert Meters into Centimetres

double distanceCm = ((int)(getDistanceMeters(pose0, pose1) * 1000))/10.0f;

// pose0 is the location of first Anchor
// pose1 is the location of second Anchor

Or, alternatively, you can use the following math:

Pose pose0 = // first HitResult's Anchor
Pose pose1 = // second HitResult's Anchor

double distanceM = Math.sqrt(Math.pow((pose0.tx() - pose1.tx()), 2) + 
                             Math.pow((pose0.ty() - pose1.ty()), 2) +
                             Math.pow((pose0.tz() - pose1.tz()), 2));

double distanceCm = ((int)(distanceM * 1000))/10.0f;