Mercurial > hg > orthanc-stone
annotate Framework/Radiography/RadiographyLayerRotateTracker.cpp @ 1116:a08699daf78b broker
ParsedDicomFileCache
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 04 Nov 2019 15:54:35 +0100 |
parents | 4f2416d519b4 |
children | 2d8ab34c8c91 |
rev | line source |
---|---|
414 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
439 | 5 * Copyright (C) 2017-2019 Osimis S.A., Belgium |
414 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "RadiographyLayerRotateTracker.h" | |
23 | |
24 #include "RadiographySceneCommand.h" | |
25 | |
26 #include <Core/OrthancException.h> | |
27 | |
28 #include <boost/math/constants/constants.hpp> | |
29 #include <boost/math/special_functions/round.hpp> | |
30 | |
31 namespace OrthancStone | |
32 { | |
33 class RadiographyLayerRotateTracker::UndoRedoCommand : public RadiographySceneCommand | |
34 { | |
35 private: | |
36 double sourceAngle_; | |
37 double targetAngle_; | |
38 | |
39 static int ToDegrees(double angle) | |
40 { | |
41 return boost::math::iround(angle * 180.0 / boost::math::constants::pi<double>()); | |
42 } | |
43 | |
44 protected: | |
45 virtual void UndoInternal(RadiographyLayer& layer) const | |
46 { | |
47 LOG(INFO) << "Undo - Set angle to " << ToDegrees(sourceAngle_) << " degrees"; | |
48 layer.SetAngle(sourceAngle_); | |
49 } | |
50 | |
51 virtual void RedoInternal(RadiographyLayer& layer) const | |
52 { | |
53 LOG(INFO) << "Redo - Set angle to " << ToDegrees(sourceAngle_) << " degrees"; | |
54 layer.SetAngle(targetAngle_); | |
55 } | |
56 | |
57 public: | |
58 UndoRedoCommand(const RadiographyLayerRotateTracker& tracker) : | |
59 RadiographySceneCommand(tracker.accessor_), | |
60 sourceAngle_(tracker.originalAngle_), | |
430 | 61 targetAngle_(tracker.accessor_.GetLayer().GetGeometry().GetAngle()) |
414 | 62 { |
63 } | |
64 }; | |
65 | |
66 | |
67 bool RadiographyLayerRotateTracker::ComputeAngle(double& angle /* out */, | |
68 double sceneX, | |
69 double sceneY) const | |
70 { | |
71 Vector u; | |
72 LinearAlgebra::AssignVector(u, sceneX - centerX_, sceneY - centerY_); | |
73 | |
74 double nu = boost::numeric::ublas::norm_2(u); | |
75 | |
76 if (!LinearAlgebra::IsCloseToZero(nu)) | |
77 { | |
78 u /= nu; | |
79 angle = atan2(u[1], u[0]); | |
80 return true; | |
81 } | |
82 else | |
83 { | |
84 return false; | |
85 } | |
86 } | |
87 | |
88 | |
89 RadiographyLayerRotateTracker::RadiographyLayerRotateTracker(UndoRedoStack& undoRedoStack, | |
90 RadiographyScene& scene, | |
726
4f2416d519b4
moving layers, widgets and loaders to Deprecated namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
457
diff
changeset
|
91 const Deprecated::ViewportGeometry& view, |
414 | 92 size_t layer, |
93 double x, | |
94 double y, | |
95 bool roundAngles) : | |
96 undoRedoStack_(undoRedoStack), | |
97 accessor_(scene, layer), | |
98 roundAngles_(roundAngles) | |
99 { | |
100 if (accessor_.IsValid()) | |
101 { | |
102 accessor_.GetLayer().GetCenter(centerX_, centerY_); | |
430 | 103 originalAngle_ = accessor_.GetLayer().GetGeometry().GetAngle(); |
414 | 104 |
105 double sceneX, sceneY; | |
106 view.MapDisplayToScene(sceneX, sceneY, x, y); | |
107 | |
108 if (!ComputeAngle(clickAngle_, x, y)) | |
109 { | |
110 accessor_.Invalidate(); | |
111 } | |
112 } | |
113 } | |
114 | |
115 | |
116 void RadiographyLayerRotateTracker::Render(CairoContext& context, | |
117 double zoom) | |
118 { | |
119 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
120 } | |
121 | |
122 | |
123 void RadiographyLayerRotateTracker::MouseUp() | |
124 { | |
125 if (accessor_.IsValid()) | |
126 { | |
127 undoRedoStack_.Add(new UndoRedoCommand(*this)); | |
128 } | |
129 } | |
130 | |
131 | |
132 void RadiographyLayerRotateTracker::MouseMove(int displayX, | |
133 int displayY, | |
134 double sceneX, | |
457
3b4df9925db6
added support for 'touch' in mouse trackers. This is still a bit hacky and we need to refactor it to make it clean. Thanks to that, Pan and zoom are available together with 2 touches
Alain Mazy <alain@mazy.be>
parents:
440
diff
changeset
|
135 double sceneY, |
726
4f2416d519b4
moving layers, widgets and loaders to Deprecated namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
457
diff
changeset
|
136 const std::vector<Deprecated::Touch>& displayTouches, |
4f2416d519b4
moving layers, widgets and loaders to Deprecated namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
457
diff
changeset
|
137 const std::vector<Deprecated::Touch>& sceneTouches) |
414 | 138 { |
139 static const double ROUND_ANGLE = 15.0 / 180.0 * boost::math::constants::pi<double>(); | |
140 | |
141 double angle; | |
142 | |
143 if (accessor_.IsValid() && | |
144 ComputeAngle(angle, sceneX, sceneY)) | |
145 { | |
146 angle = angle - clickAngle_ + originalAngle_; | |
147 | |
148 if (roundAngles_) | |
149 { | |
150 angle = boost::math::round<double>((angle / ROUND_ANGLE) * ROUND_ANGLE); | |
151 } | |
152 | |
153 accessor_.GetLayer().SetAngle(angle); | |
154 } | |
155 } | |
156 } |