Sherif - 2 years ago 76
Java Question

# How to draw a line that points correctly at images at the corners of the screen

I have some fixed position images at every screen edge and I want to find a way to be able to point at them correctly, I get both my old and new mouse points from MouseMoved and with those 2 points and the angle I can draw a line that reaches the end of the screen but unfortunately I can't make that line point correctly at the images

What your program is trying to do is:

1. Find the angle that the line is supposed to have.
2. Start by assuming the line is going to be very long so that it crosses the edge of the rectangle.
3. Then cut it off at the point of crossing.

For example, assume the rectangle is 180 by 120, and that your angle is 45ยบ. The larger of the dimensions is 180, so you draw a line of length 180 at that angle:

So you want to cut the line where the arrow is. Both your `newX` and your `newY` are outside of the frame. According to the logic of your program, you see that `newX` is greater than 1750, and so you cut it to 180 (the frame max y in my example). And the value of `newY` is greater than 850, and so you cut it to 120 (the rectangle's max Y in my example).

This means that almost always, you'll end up with the line end being at (180,120) instead of where the arrow is. This is because you just adjusted one coordinate, but you failed to find the corresponding Y on the line before continuing.

Basically, when you cut down `newX` to `getWidth() - 100`, you also need to find Y that will go with it and is on the same line. So you need to calculate Y again. Instead of:

``````    if (newX  > 1720)
{
newX  = getWidth() - 100;
}
``````

You need to have

``````    if (newX  > 1720)
{
newX  = getWidth() - 100;
newY = Math.round(oldY + (newX - oldX)*Math.tan(angle));
}
``````

The new value of `newY` may still be outside of the rectangle. In fact, the new point is this:

So now you will adjust the value of Y - but again, you have to be careful, and match the value of X to that Y according to the same angle.

But beware: the method is not very good to begin with. Taking `Math.max(getWidth(), getHeight())` as the initial length of the line is only going to work for certain points. But what if your point is near one corner and the other point is near the opposite corner? The diagonal of the rectangle is longer than either its width and height. So you'll get a line that is too short and won't reach the edge.

You could calculate the diagonal instead of `max`, but perhaps you should adopt a different method:

1. Calculate the linear formula of the line (any line is $y = ax+b$).
2. Calculate the Y for `x=100` and `x=width-100`
3. Calculate the X for `y=100` and `y=height-100`
4. Now you have four pairs of X and Y, find out which one of them is the correct one. Only two are going to be inside the frame, and only one of these is in the right direction.

In fact, you don't need to calculate four points. If the original `newX` from the mouse event was to the right of the `oldX`, only calculate the formula at the right edge. The left edge doesn't interest you. If it was on the left, only calculate at the left edge. If the original `newY` from the mouse event was below the `oldY`, only calculate the formula at the lower edge, and if it was higher, only at the top edge. You'll end up with two points. Only one of them is "legal" (both x and y are in the rectangle), and you use that.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download