source: josm/trunk/src/org/openstreetmap/josm/command/ScaleCommand.java@ 11940

Last change on this file since 11940 was 10663, checked in by Don-vip, 8 years ago

fix #13223 - Minor command class fixes (patch by michael2402, modified) - gsoc-core

  • Property svn:eol-style set to native
File size: 3.5 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;
7import java.util.Objects;
8
9import org.openstreetmap.josm.data.coor.EastNorth;
10import org.openstreetmap.josm.data.osm.Node;
11import org.openstreetmap.josm.data.osm.OsmPrimitive;
12
13public class ScaleCommand extends TransformNodesCommand {
14 /**
15 * Pivot point
16 */
17 private final EastNorth pivot;
18
19 /**
20 * Current scaling factor applied
21 */
22 private double scalingFactor;
23
24 /**
25 * World position of the mouse when the user started the command.
26 */
27 private final EastNorth startEN;
28
29 /**
30 * Creates a ScaleCommand.
31 * Assign the initial object set, compute pivot point.
32 * Computation of pivot point is done by the same rules that are used in
33 * the "align nodes in circle" action.
34 * @param objects objects to fetch nodes from
35 * @param currentEN cuurent eats/north
36 */
37 public ScaleCommand(Collection<? extends OsmPrimitive> objects, EastNorth currentEN) {
38 super(objects);
39
40 pivot = getNodesCenter();
41
42 // We remember the very first position of the mouse for this action.
43 // Note that SelectAction will keep the same ScaleCommand when the user
44 // releases the button and presses it again with the same modifiers.
45 // The very first point of this operation is stored here.
46 startEN = currentEN;
47
48 handleEvent(currentEN);
49 }
50
51 /**
52 * Compute new scaling factor and transform nodes accordingly.
53 */
54 @Override
55 public final void handleEvent(EastNorth currentEN) {
56 double startAngle = Math.atan2(startEN.east()-pivot.east(), startEN.north()-pivot.north());
57 double endAngle = Math.atan2(currentEN.east()-pivot.east(), currentEN.north()-pivot.north());
58 double startDistance = pivot.distance(startEN);
59 double currentDistance = pivot.distance(currentEN);
60 setScalingFactor(Math.cos(startAngle-endAngle) * currentDistance / startDistance);
61 transformNodes();
62 }
63
64 /**
65 * Set the scaling factor
66 * @param scalingFactor The scaling factor.
67 */
68 protected void setScalingFactor(double scalingFactor) {
69 this.scalingFactor = scalingFactor;
70 }
71
72 /**
73 * Scale nodes.
74 */
75 @Override
76 protected void transformNodes() {
77 for (Node n : nodes) {
78 EastNorth oldEastNorth = oldStates.get(n).getEastNorth();
79 double dx = oldEastNorth.east() - pivot.east();
80 double dy = oldEastNorth.north() - pivot.north();
81 double nx = pivot.east() + scalingFactor * dx;
82 double ny = pivot.north() + scalingFactor * dy;
83 n.setEastNorth(new EastNorth(nx, ny));
84 }
85 }
86
87 @Override
88 public String getDescriptionText() {
89 return trn("Scale {0} node", "Scale {0} nodes", nodes.size(), nodes.size());
90 }
91
92 @Override
93 public int hashCode() {
94 return Objects.hash(super.hashCode(), pivot, scalingFactor, startEN);
95 }
96
97 @Override
98 public boolean equals(Object obj) {
99 if (this == obj) return true;
100 if (obj == null || getClass() != obj.getClass()) return false;
101 if (!super.equals(obj)) return false;
102 ScaleCommand that = (ScaleCommand) obj;
103 return Double.compare(that.scalingFactor, scalingFactor) == 0 &&
104 Objects.equals(pivot, that.pivot) &&
105 Objects.equals(startEN, that.startEN);
106 }
107}
Note: See TracBrowser for help on using the repository browser.