Android ARCore 测量距离

标签 android distance measure arcore

我正在开发 AR 应用程序,我正在使用 ViroCore SDK。问题是如何借助 ViroCore SDK 测量距离?我应该通过将 2 个对象放在表面上然后使用它们的坐标来做到这一点,还是有另一种方法可以做到这一点?现在我正在尝试做一些类似这篇文章中描述的事情 https://stackoverflow.com/a/45987189/3071070

最佳答案

这是我的类,用于测量放置在 AR 中的两个对象之间的距离:

public class ARRuler {

public static final String TAG = ARRuler.class.getSimpleName();

private static final long PROCESS_POINT_DELAY = 1500L;

private static final int BOX_COLOR = Color.parseColor("#FF0000");
private static final float BOX_WIDTH = 0.05f;
private static final float BOX_HEIGHT = 0.05f;
private static final float BOX_LENGTH = 0.05f;

private static final int DISTANCE_LABEL_HEIGHT = 100;
private static final int DISTANCE_LABEL_WIDTH = 100;
private static final int DISTANCE_LABEL_TEXT_COLOR = Color.parseColor("#FF0000");
private static final int DISTANCE_LABEL_TEXT_SIZE = 10;

private static final float POLYLINE_THICKNESS = 0.05f;
private static final int POLYLINE_COLOR = Color.parseColor("#FFFFFF");


private ViroViewARCore mViroViewARCore;
private ARScene mARScene;
private List<Node> mSelectedNodes;
private List<Float> mDistances;

public ARRuler(ViroViewARCore viroViewARCore, ARScene arScene) {
    this.mViroViewARCore = viroViewARCore;
    this.mARScene = arScene;
    this.mSelectedNodes = new ArrayList<>();
    this.mDistances = new ArrayList<>();
}

public void pointSelected(Vector position) {
    Log.d(TAG, "pointSelected: " + position);

    Box box = new Box(BOX_WIDTH, BOX_HEIGHT, BOX_LENGTH);

    Material material = new Material();
    material.setDiffuseColor(BOX_COLOR);
    box.setMaterials(Collections.singletonList(material));

    Node boxNode = new Node();
    boxNode.setGeometry(box);
    boxNode.setPosition(position);

    if (mSelectedNodes.size() == 0) {
        boxNode.setClickListener(new ClickListener() {
            @Override
            public void onClick(int i, Node node, Vector vector) {
                Log.d(TAG, "onClick: First point clicked");

               mSelectedNodes.add(node);
               startDelayedProcessing();
            }

            @Override
            public void onClickState(int i, Node node, ClickState clickState, Vector vector) {

            }
        });
    }

    mARScene.getRootNode().addChildNode(boxNode);
    mSelectedNodes.add(boxNode);

    startDelayedProcessing();
}

private void startDelayedProcessing() {
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            processSelectedPoints();
        }
    }, PROCESS_POINT_DELAY);
}

private void processSelectedPoints() {
    Log.d(TAG, "processSelectedPoints: ");

    if (mSelectedNodes.size() < 2) {
        Log.d(TAG, "processSelectedPoints: Only one point, return");
        return;
    }

    for (int i = 0; i < mSelectedNodes.size(); i++) {
        Log.d(TAG, "processSelectedPoints: Start looping...");

        if (i + 1 == mSelectedNodes.size()) {
            Log.d(TAG, "processSelectedPoints: Last pair reached, return");
            return;
        }

        Node start = mSelectedNodes.get(i);
        Node end = mSelectedNodes.get(i + 1);

        drawDistanceLabel(start, end);
        drawPolylines();
    }
}

private void drawDistanceLabel(Node start, Node end) {
    Vector startVector = start.getPositionRealtime();
    Vector endVector = end.getPositionRealtime();

    Log.d(TAG, "drawDistanceLabel: Vectors created!");
    Log.d(TAG, "drawDistanceLabel: startVector=" + startVector);
    Log.d(TAG, "drawDistanceLabel: endVector=" + endVector);

    float distance = startVector.distance(endVector);
    Log.d(TAG, "drawDistanceLabel: distance=" + distance);
    mDistances.add(distance);

    String distanceString = new DecimalFormat("#.###").format(distance);
    Log.d(TAG, "drawDistanceLabel: distanceString=" + distanceString);

    Text text = new Text(mViroViewARCore.getViroContext(), distanceString,
            DISTANCE_LABEL_WIDTH, DISTANCE_LABEL_HEIGHT);
    text.setColor(DISTANCE_LABEL_TEXT_COLOR);
    text.setFontSize(DISTANCE_LABEL_TEXT_SIZE);

    Node node = new Node();
    node.setGeometry(text);

    Vector labelPosition = startVector.midpoint(endVector);
    node.setPosition(labelPosition);

    mARScene.getRootNode().addChildNode(node);
}

private void drawPolylines() {
    Log.d(TAG, "drawPolylines: ");

    Polyline polyline = new Polyline(POLYLINE_THICKNESS);
    polyline.setPoints(getVectors());

    Material material = new Material();
    material.setDiffuseColor(POLYLINE_COLOR);
    polyline.setMaterials(Collections.singletonList(material));

    Node node = new Node();
    node.setGeometry(polyline);

    mARScene.getRootNode().addChildNode(node);
}

private List<Vector> getVectors() {
    Log.d(TAG, "getVectors: ");

    List<Vector> vectors = new ArrayList<>();

    for (Node node : mSelectedNodes) {
        vectors.add(node.getPositionRealtime());
    }

    return vectors;
}

它在点击位置绘制红色框,在添加 2 个框后,它绘制折线和文本标签,这些框之间有距离。要开始使用它,您只需将它复制到您的项目并传递 ViroViewARCoreARScene 对象。之后,只需在 Node.ClickListener() 回调中调用 ARRuler.pointSelected(selectedPosition)

如有任何问题,请随时提出。

关于Android ARCore 测量距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48260107/

相关文章:

android - 在android中打开另一个带有横向屏幕的应用程序

android - 动态注册时未调用 BroadcastReceiver onReceive()

C++ 精确测量时间(以十进制毫秒为单位)

python - 使用Python测量音频输出电平?

android - 即使软键盘打开,按下 Android 后退按钮也能完成 Activity

java - 三元运算符中的多个语句

Java:方法总是返回相同的结果

google-maps - 用于地理编码(街道位置!)和下一次距离计算的包

r - 如何根据 R 中循环的距离测量值制作距离矩阵?

android - 显示尺寸最大时parentWidth返回错误值?