source: josm/trunk/src/org/openstreetmap/josm/command/RotateCommand.java@ 4677

Last change on this file since 4677 was 3702, checked in by bastiK, 13 years ago

applied #5652 (patch by Olivier Croquette) - add support for scaling objects

  • Property svn:eol-style set to native
File size: 3.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.command;
3
4import static org.openstreetmap.josm.tools.I18n.trn;
5
6import java.util.Collection;
7
8import javax.swing.JLabel;
9
10import org.openstreetmap.josm.data.coor.EastNorth;
11import org.openstreetmap.josm.data.osm.Node;
12import org.openstreetmap.josm.data.osm.OsmPrimitive;
13import org.openstreetmap.josm.tools.ImageProvider;
14
15/**
16 * RotateCommand rotates a number of objects around their centre.
17 *
18 * @author Frederik Ramm <frederik@remote.org>
19 */
20public class RotateCommand extends TransformNodesCommand {
21
22 /**
23 * Pivot point
24 */
25 private EastNorth pivot;
26
27 /**
28 * World position of the mouse when the user started the command.
29 *
30 */
31 EastNorth startEN = null;
32
33 /**
34 * angle of rotation starting click to pivot
35 */
36 private double startAngle = 0.0;
37
38 /**
39 * computed rotation angle between starting click and current mouse pos
40 */
41 private double rotationAngle = 0.0;
42
43 /**
44 * Creates a RotateCommand.
45 * Assign the initial object set, compute pivot point and inital rotation angle.
46 */
47 public RotateCommand(Collection<OsmPrimitive> objects, EastNorth currentEN) {
48 super(objects);
49
50 pivot = getNodesCenter();
51
52 // We remember the very first position of the mouse for this action.
53 // Note that SelectAction will keep the same ScaleCommand when the user
54 // releases the button and presses it again with the same modifiers.
55 // The very first point of this operation is stored here.
56 startEN = currentEN;
57
58 startAngle = getAngle(currentEN);
59 rotationAngle = 0.0;
60
61 handleEvent(currentEN);
62 }
63
64 /**
65 * Get angle between the horizontal axis and the line formed by the pivot and give points.
66 **/
67 protected double getAngle(EastNorth currentEN) {
68 if ( pivot == null )
69 return 0.0; // should never happen by contract
70 return Math.atan2(currentEN.east()-pivot.east(), currentEN.north()-pivot.north());
71 }
72
73 /**
74 * Compute new rotation angle and transform nodes accordingly.
75 */
76 @Override
77 public void handleEvent(EastNorth currentEN) {
78 double currentAngle = getAngle(currentEN);
79 rotationAngle = currentAngle - startAngle;
80 transformNodes();
81 }
82
83 /**
84 * Rotate nodes.
85 */
86 @Override
87 protected void transformNodes() {
88 for (Node n : nodes) {
89 double cosPhi = Math.cos(rotationAngle);
90 double sinPhi = Math.sin(rotationAngle);
91 EastNorth oldEastNorth = oldStates.get(n).eastNorth;
92 double x = oldEastNorth.east() - pivot.east();
93 double y = oldEastNorth.north() - pivot.north();
94 double nx = cosPhi * x + sinPhi * y + pivot.east();
95 double ny = -sinPhi * x + cosPhi * y + pivot.north();
96 n.setEastNorth(new EastNorth(nx, ny));
97 }
98 }
99
100 @Override
101 public JLabel getDescription() {
102 return new JLabel(trn("Rotate {0} node", "Rotate {0} nodes", nodes.size(), nodes.size()), ImageProvider.get("data", "node"), JLabel.HORIZONTAL);
103 }
104}
Note: See TracBrowser for help on using the repository browser.