android - 一条线是否包含一个点

标签 android path android-canvas point

我希望用户能够在 Canvas 周围拖动正方形的边缘。使用我当前的解决方案它可以工作但有故障,有时无法选择边缘。是否有一种干净的方法来判断一条线是否已被单击(例如,通过坐标)?这就是我目前正在测试的方式:

// check edge pressed, edge is the line between to
// coords e.g. (i) & (i = 1)
for (int i = 0; i < coords.size(); i++) {
    p1 = coords.get(i);
    if ((i + 1) > (coords.size() - 1)) p2 = coords.get(0);
    else p2 = coords.get(i + 1);

    // is this the line pressed
    if (p1.x <= event.getX() + 5 && event.getX() - 5 <= p2.x && p1.y <= event.getY() + 5 && event.getY() - 5 <= p2.y) {
        // points found, set to non temp
        // variable for use in ACTION_MOVE
        point1 = p1;
        point2 = p2;
        break;
    } else if (p1.x >= event.getX() + 5 && event.getX() - 5 >= p2.x && p1.y >= event.getY() + 5 && event.getY() - 5 >= p2.y) {
        // points found, set to non temp
        // variable for use in ACTION_MOVE
        point1 = p1;
        point2 = p2;
        break;
    }
}

下面的代码//这是按下的行是最重要的,也是最有可能的问题。 +5 和 -5 用于为用户提供更大的点击区域。

这里是整个点击事件:

public void EditEdge() {

    //TODO this works like shit             
    // Detect the two coordinates along the edge pressed and drag
    // them
    scene.setOnTouchListener(new View.OnTouchListener() {
        private int startX;
        private int startY;
        private Point point1 = new Point(0, 0);
        private Point point2 = new Point(0, 0);

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startX = (int) event.getX();
                    startY = (int) event.getY();

                    Point p1;
                    Point p2;

                    // check edge pressed, edge is the line between to
                    // coords e.g. (i) & (i = 1)
                    for (int i = 0; i < coords.size(); i++) {
                        p1 = coords.get(i);
                        if ((i + 1) > (coords.size() - 1)) p2 = coords.get(0);
                        else p2 = coords.get(i + 1);

                        // is this the line pressed
                        if (p1.x <= event.getX() + 5 && event.getX() - 5 <= p2.x && p1.y <= event.getY() + 5 && event.getY() - 5 <= p2.y) {
                            // points found, set to non temp
                            // variable for use in ACTION_MOVE
                            point1 = p1;
                            point2 = p2;
                            break;
                        } else if (p1.x >= event.getX() + 5 && event.getX() - 5 >= p2.x && p1.y >= event.getY() + 5 && event.getY() - 5 >= p2.y) {
                            // points found, set to non temp
                            // variable for use in ACTION_MOVE
                            point1 = p1;
                            point2 = p2;
                            break;
                        }
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    point1 = new Point(0, 0);
                    point2 = new Point(0, 0);
                    // scene.setOnTouchListener(scene.editModeOnTouchListener);
                    break;
                case MotionEvent.ACTION_MOVE:

                    for (Point p: new Point[] {
                        point1, point2
                    }) {
                        int modX = (int)(p.x + (event.getX() - startX));
                        int modY = (int)(p.y + (event.getY() - startY));
                        p.set(modX, modY);
                    }

                    SetCoords(coords);
                    startX = (int) event.getX();
                    startY = (int) event.getY();

                    break;
                default:
                    return false;
            }
            return true;
        }
    });
}

那么有没有更简单的方法来判断一条线是否被点击/穿过一个点或者这不是问题?

谢谢

最佳答案

使用线方程 y = mx + b 找出点是否在一条线上

float EPSILON = 0.001f;

public boolean isPointOnLine(Point linePointA, Point linePointB, Point point) {
    float m = (linePointB.y - linePointA.y) / (linePointB.x - linePointA.x);
    float b = linePointA.y - m * linePointA.x;
    return Math.abs(point.y - (m*point.x+b)) < EPSILON);
}

关于android - 一条线是否包含一个点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20887806/

相关文章:

java - Canvas 不绘制 Android

android - 如何使用android studio构建ndk项目?

java - 当编辑文本在 ListView 中具有焦点时,始终显示所选项目

php - 如何覆盖PHP的路径以使用MAMP路径?

path - 错误 PRJ0003 : Error spawning 'cl.exe'

android - 在 Android 中的特定区域上绘画

java - android 将十六进制转换为字符

android - Android 中的静态 AlarmManager

c# - 在 C# 中,如何检查路径是否为虚拟路径?

android - 在图像android的中间绘制文本