Java Reference
In-Depth Information
This comes from the definition of what the sine of an angle is. The Math class provides a method to
calculate sin-1 values (also called arcsine values), so we can calculate angle as:
double angle = Math.asin(perp/hypotenuse);
The asin() method returns an angle in radians between -
/2, which is fine for us. We are
unlikely to create an angle outside this range for a mouseDragged() event.
π
/2 and
π
Of course, we 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. We can use this to test
whether the point, last , is clockwise or counterclockwise with respect to the line from position to
start . Since angles rotating the coordinate system clockwise are positive, we can calculate a suitably
signed value for angle with the 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 we need. Let's do it.
Try It Out - Rotating Elements
To deal with ROTATE mode in the mouseDragged() method, we can add an extra else if clause
after the one we added for MOVE :
} else if(button1Down && mode == ROTATE && selectedElement != null) {
selectedElement.draw(g2D); // Draw to erase the element
selectedElement.rotate(getAngle(selectedElement.getPosition(),
start, last));
selectedElement.draw(g2D); // Draw in its new position
start = last; // Make start current point
}
After drawing the element to erase it, we call its rotate() method to rotate it and then redraw it in the
new position. We will add the definition for the rotate() method to the Element class in a moment.
The argument to the rotate() method is the angle in radians through which the element is to be
rotated, and that is returned by a helper method, getAngle() . We can add that to the
MouseHandler class as:
// Helper method for calculating getAngle()
double getAngle(Point position, Point start, Point last) {
// Get perpendicular distance from last to the line from position to start
double perp = Line2D.ptLineDist(position.x, position.y,
last.x, last.y, start.x, start.y);
// Get the distance from position to start
double hypotenuse = position.distance(start);
Search WWH ::




Custom Search