English 中文(简体)
How to select a line
原标题:

So I m trying to figure out how to implement a method of selecting lines or edges in a drawing area but my math is a bit lacking. This is what I got so far:

  • A collection of lines, each line has two end points (one to start and one to end the line)
  • The lines are drawn correctly on a canvas
  • Mouse clicks events are received when clicking the canvas, so I can get the x and y coordinate of the mouse pointer

I know I can iterate through the list of lines, but I have no idea how to construct an algorithm to select a line by a given coordinate (i.e. the mouse click). Anyone got any ideas or point me to the right direction?

// 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;
}
最佳回答

Best way to do this is to use the intersects method of the line. Like another user mentioned, you need to have a buffer area around where they clicked. So create a rectangle centered around your mouse coordinate, then test that rectangle for intersection with your line. Here s some code that should work (don t have a compiler or anything, but should be easily modifiable)

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

}

问题回答

Well, first off, since a mathematical line has no width it s going to be very difficult for a user to click exactly ON the line. As such, your best bet is to come up with some reasonable buffer (like 1 or 2 pixels or if your line graphically has a width use that) and calculate the distance from the point of the mouse click to the line. If the distance falls within your buffer then select the line. If you fall within that buffer for multiple lines, select the one that came closest.

Line maths here:

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

Shortest distance between a point and a line segment

If you use the 2D api then this is already taken care of.

You can use Line2D.Double class to represent the lines. The Line2D.Double class has a contains() method that tells you if a Point is onthe line or not.

Sorry, mathematics are still required... This is from java.awt.geom.Line2D:

public boolean contains(double x, double y)

Tests if a specified coordinate is inside the boundary of this Line2D. This method is required to implement the Shape interface, but in the case of Line2D objects it always returns false since a line contains no area.

Specified by: contains in interface Shape

Parameters: x - the X coordinate of the specified point to be tested y - the Y coordinate of the specified point to be tested

Returns: false because a Line2D contains no area.

Since: 1.2

I recommend Tojis answer





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签