20

Is it possible to calculate distance between two HitResult `s ?

Or how we can calculate real distance (e.g. meters) using ARCore?

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
Alexey Podolian
  • 303
  • 1
  • 3
  • 10

3 Answers3

35

In Java ARCore world units are meters (I just realized we might not document this... aaaand looks like nope. Oops, bug filed). By subtracting the translation component of two Poses you can get the distance between them. Your code would look something like this:

On first hit as hitResult:

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

On second hit as 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);

Assuming that these hit results don't happen on the same frame, creating an Anchor is important because the virtual world can be reshaped every time you call Session.update(). By holding that location with an anchor instead of just a Pose, its Pose will update to track the physical feature across those reshapings.

Ian M
  • 672
  • 4
  • 11
5

You can extract the two HitResult poses using getHitPose() and then compare their translation component (getTranslation()). The translation is defined as

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

As for the physical unit of this I could not find any remark. With a calibrated camera this should be mathematically possible but I don't know if they actually provide an API for this

PhilLab
  • 4,777
  • 1
  • 25
  • 77
5

The answer is: Yes, you definitely can calculate distance between two HitResult's. The working units of ARCore, as well as ARKit, are meters. Sometimes, it's more useful to use centimetres. Here are a few ways how you do it with Java and great old Pythagorean theorem.

enter image description here

import com.google.ar.core.HitResult

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

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

Alternatively, you can use the following math:

Pose pose0 = firstAnchor.getPose()     // first pose
Pose pose1 = secondAnchor.getPose()    // second pose

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;
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • Can you please share your full code? It would help me a lot – Shubham Agrawal Oct 15 '18 at 08:52
  • Can you please help me with getting the `height` of the object. Suppose I have placed a cube at some point and scaling that cube. Now the final value which is coming is in vectors. I don'y have any reference to convert that into meters. – Shubham Agrawal Oct 15 '18 at 13:05
  • Why are you multiplying by 100 (1000/10=100) to convert meters to centimeters? Why not just do distanceInMeters*100? – kenyee Nov 01 '18 at 18:43
  • Because distanceM typecasted to `int` but result is divided by `float`. Although, you can calculate it the way you like))) It's a precision issue... – Andy Jazz Nov 01 '18 at 20:48