Java Reference
In-Depth Information
about
position
as the cursor is dragged. The angle in
Figure 20-21
is exaggerated so you can see what is go-
ing on during a single mouse, dragged event. The
mousePressed()
method is called when the button is first
pressed at some arbitrary position, and the cursor position is recorded in
start
. When the
mouseDragged()
method is called, you record the cursor position in
last
, and you now need to calculate
angle
. You must
apply a little high school math to get this, which you can ignore if your recall of trigonometry is nonexistent.
You can get the length of the perpendicular from the point
start
in
Figure 20-21
to the line from
posi-
tion
to
last
by using a static method in the
Line2D
class:
double perp = Line2D.ptLineDist(position.x, position.y,
last.x, last.y,
start.x, start.y);
The
ptLineDist()
method calculates the perpendicular distance of the point specified by the last two
arguments to the line specified by the first four arguments as a value of type
double
. The first pair of ar-
guments are the coordinates of the beginning of the line, and the second pair are the coordinates of the end
point.
You know how to get the distance from
position
to
start
. You just apply the
distance()
method that
is defined in the
Point
class:
double hypotenuse = position.distance(start);
sin
-1
(perp/hypotenuse)
This comes from the definition of what the sine of an angle is. The
Math
class provides the
asin()
meth-
od to calculate
sin
-1
values (also called arcsine values), so you can calculate
angle
as
double angle = Math.asin(perp/hypotenuse);
The
asin()
method returns an angle in radians between −π/2 and π/2, which is fine for the situation
you are dealing with in Sketcher. You are unlikely to create an angle outside this range for a single
mouseDragged()
event unless there is something seriously awry with your PC.
Of course, you need to know which way the rotation is going, clockwise or counterclockwise. Another static
method in the
Line2D
class can help out here. The
relativeCCW()
method determines where a point lies
with respect to a line. If you have to rotate the line clockwise to reach the point, the method returns −1, and
if you have to rotate the line counterclockwise, it returns + 1. It returns zero if the points are collinear. You
can use this method to test whether the point
last
is clockwise or counterclockwise with respect to the line
from
position
to
start
. Because angles rotating the coordinate system clockwise are positive, you can
calculate a suitably signed value for
angle
with the following statement:
double angle = -Line2D.relativeCCW(position.x, position.y,
start.x, start.y,
last.x, last.y)*Math.asin(perp/hypotenuse);
The minus sign is necessary because the method returns −1 when
last
is clockwise with respect to the
line from
position
to
start
. That's all the math you need. Let's do it.