代码之家  ›  专栏  ›  技术社区  ›  Spoike Otávio Décio

如何选择线条

  •  2
  • Spoike Otávio Décio  · 技术社区  · 16 年前

    所以我想知道如何实现在绘图区域中选择线条或边缘的方法,但是我的数学有点欠缺。这就是我到目前为止所得到的:

    • 一组行,每行有两个端点(一个起点,一个终点)
    • 线条在画布上绘制正确
    • 单击画布时会收到鼠标单击事件,因此我可以获取鼠标指针的X和Y坐标。

    我知道我可以遍历行列表,但我不知道如何构造一种算法,通过给定的坐标(即鼠标单击)来选择行。有人有什么想法或是指点我正确的方向吗?

    // import java.awt.Point
    
    public Line selectLine(Point mousePoint) {
        for (Line l : getLines()) {
            Point start = l.getStart();
            Point end = l.getEnd();
            if (canSelect(start, end, mousePoint)) {
                return l; // found line!
            }
        }
        return null; // could not find line at mousePoint
    }
    
    public boolean canSelect(Point start, Point end, Point selectAt) {
        // How do I do this?
        return false;
    }
    
    4 回复  |  直到 16 年前
        1
  •  7
  •   I82Much    16 年前

    最好的方法是使用直线的相交方法。像前面提到的另一个用户一样,您需要在他们单击的地方有一个缓冲区。因此,创建一个以鼠标坐标为中心的矩形,然后测试该矩形是否与线相交。下面是一些应该工作的代码(没有编译器或其他东西,但是应该很容易修改)

    // Width and height of rectangular region around mouse
    // pointer to use for hit detection on lines
    private static final int HIT_BOX_SIZE = 2;
    
    
    
    public void mousePressed(MouseEvent e) {
        int x = e.getX();
        int y = e.getY();
    
        Line2D clickedLine = getClickedLine(x, y);
    }
    
    
    /**
    * Returns the first line in the collection of lines that
    * is close enough to where the user clicked, or null if
    * no such line exists
    *
    */
    
    public Line2D getClickedLine(int x, int y) {
    int boxX = x - HIT_BOX_SIZE / 2;
    int boxY = y - HIT_BOX_SIZE / 2;
    
    int width = HIT_BOX_SIZE;
    int height = HIT_BOX_SIZE;
    
    for (Line2D line : getLines()) {
        if (line.intersects(boxX, boxY, width, height) {
            return line;
        }       
    }
    return null;
    

    }

        2
  •  4
  •   Vincent Ramdhanie    16 年前

    如果您使用的是2dapi,那么它已经得到了处理。

    你可以用 Line2D.Double 类来表示行。double类有一个contains()方法,它告诉您点是否在直线上。

        3
  •  4
  •   Community Mohan Dere    9 年前

    首先,由于一条数学线没有宽度,用户很难准确地点击它。因此,您的最佳选择是找到一些合理的缓冲区(如1或2像素,或者如果您的线条以图形方式具有宽度,则使用该缓冲区),并计算从鼠标单击点到线条的距离。如果距离在缓冲区内,则选择该行。如果您属于多行缓冲区,请选择最接近的一行。

    这里是线条数学:

    http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html

    Shortest distance between a point and a line segment

        4
  •  0
  •   Andreas_D    16 年前

    对不起,数学还是需要的…来自java.awt.geom.line2d:

    公共布尔值包含(double x, 双Y)

    测试指定的坐标是否在该行的边界2d内。 此方法需要实现 形状接口,但在这种情况下 它总是返回的Line2d对象 错误,因为行不包含区域。

    指定: 包含在接口形状中

    参数: x-待测点的x坐标 y-待测点的y坐标

    返回: false,因为line2d不包含任何区域。

    因为: 1.2

    我推荐东芝的答案