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

Revision 4918, 3.2 KB checked in by simon04, 3 months ago (diff)

fix #7370 - Refactor Command.getDescription

  • Property svn:eol-style set to native
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.Icon;
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 String getDescriptionText() {
102        return trn("Rotate {0} node", "Rotate {0} nodes", nodes.size(), nodes.size());
103    }
104
105    @Override
106    public Icon getDescriptionIcon() {
107        return ImageProvider.get("data", "node");
108    }
109}
Note: See TracBrowser for help on using the repository browser.