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

Last change on this file since 13486 was 12581, checked in by bastiK, 7 years ago

see #14794 - javadoc

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