Mercurial > hg > orthanc-stone
comparison Applications/Samples/SingleFrameEditorApplication.h @ 346:c2e040ea8fbe am-2
rotation transform
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 22 Oct 2018 19:40:36 +0200 |
parents | 55438b1ca317 |
children | cd65103c9172 |
comparison
equal
deleted
inserted
replaced
345:55438b1ca317 | 346:c2e040ea8fbe |
---|---|
65 Matrix transform_; | 65 Matrix transform_; |
66 double pixelSpacingX_; | 66 double pixelSpacingX_; |
67 double pixelSpacingY_; | 67 double pixelSpacingY_; |
68 double panX_; | 68 double panX_; |
69 double panY_; | 69 double panY_; |
70 | 70 double angle_; |
71 | 71 |
72 void UpdateTransform() | 72 |
73 { | 73 static Matrix CreateOffsetMatrix(double dx, |
74 transform_ = LinearAlgebra::IdentityMatrix(3); | 74 double dy) |
75 | 75 { |
76 transform_(0, 0) = pixelSpacingX_; | 76 Matrix m = LinearAlgebra::IdentityMatrix(3); |
77 transform_(1, 1) = pixelSpacingY_; | 77 m(0, 2) = dx; |
78 transform_(0, 2) = panX_; | 78 m(1, 2) = dy; |
79 transform_(1, 2) = panY_; | 79 return m; |
80 | 80 } |
81 #if 0 | 81 |
82 double a = 10.0 / 180.0 * boost::math::constants::pi<double>(); | 82 |
83 static Matrix CreateScalingMatrix(double sx, | |
84 double sy) | |
85 { | |
86 Matrix m = LinearAlgebra::IdentityMatrix(3); | |
87 m(0, 0) = sx; | |
88 m(1, 1) = sy; | |
89 return m; | |
90 } | |
91 | |
92 | |
93 static Matrix CreateRotationMatrix(double angle) | |
94 { | |
83 Matrix m; | 95 Matrix m; |
84 const double v[] = { cos(a), -sin(a), 0, | 96 const double v[] = { cos(angle), -sin(angle), 0, |
85 sin(a), cos(a), 0, | 97 sin(angle), cos(angle), 0, |
86 0, 0, 1 }; | 98 0, 0, 1 }; |
87 LinearAlgebra::FillMatrix(m, 3, 3, v); | 99 LinearAlgebra::FillMatrix(m, 3, 3, v); |
88 transform_ = LinearAlgebra::Product(m, transform_); | 100 return m; |
89 #endif | 101 } |
90 } | 102 |
91 | 103 |
92 | 104 static void ApplyTransform(double& x /* inout */, |
93 void MapImageToScene(double& x, | 105 double& y /* inout */, |
94 double& y) const | 106 const Matrix& transform) |
95 { | 107 { |
96 Vector p; | 108 Vector p; |
97 LinearAlgebra::AssignVector(p, x, y, 1); | 109 LinearAlgebra::AssignVector(p, x, y, 1); |
98 | 110 |
99 Vector q = LinearAlgebra::Product(transform_, p); | 111 Vector q = LinearAlgebra::Product(transform, p); |
100 | 112 |
101 if (!LinearAlgebra::IsNear(q[2], 1.0)) | 113 if (!LinearAlgebra::IsNear(q[2], 1.0)) |
102 { | 114 { |
103 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | 115 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
104 } | 116 } |
108 y = q[1]; | 120 y = q[1]; |
109 } | 121 } |
110 } | 122 } |
111 | 123 |
112 | 124 |
125 void UpdateTransform() | |
126 { | |
127 transform_ = CreateScalingMatrix(pixelSpacingX_, pixelSpacingY_); | |
128 | |
129 double centerX = static_cast<double>(width_) / 2.0; | |
130 double centerY = static_cast<double>(height_) / 2.0; | |
131 ApplyTransform(centerX, centerY, transform_); | |
132 | |
133 transform_ = LinearAlgebra::Product( | |
134 CreateOffsetMatrix(panX_ + centerX, panY_ + centerY), | |
135 CreateRotationMatrix(angle_), | |
136 CreateOffsetMatrix(-centerX, -centerY), transform_); | |
137 } | |
138 | |
139 | |
113 void AddToExtent(Extent2D& extent, | 140 void AddToExtent(Extent2D& extent, |
114 double x, | 141 double x, |
115 double y) const | 142 double y) const |
116 { | 143 { |
117 MapImageToScene(x, y); | 144 ApplyTransform(x, y, transform_); |
118 extent.AddPoint(x, y); | 145 extent.AddPoint(x, y); |
119 } | 146 } |
120 | 147 |
121 | 148 |
122 public: | 149 public: |
127 height_(0), | 154 height_(0), |
128 hasCrop_(false), | 155 hasCrop_(false), |
129 pixelSpacingX_(1), | 156 pixelSpacingX_(1), |
130 pixelSpacingY_(1), | 157 pixelSpacingY_(1), |
131 panX_(0), | 158 panX_(0), |
132 panY_(0) | 159 panY_(0), |
160 angle_(45.0 / 180.0 * boost::math::constants::pi<double>()) | |
133 { | 161 { |
134 UpdateTransform(); | 162 UpdateTransform(); |
135 } | 163 } |
136 | 164 |
137 virtual ~Bitmap() | 165 virtual ~Bitmap() |
174 width = width_; | 202 width = width_; |
175 height = height_; | 203 height = height_; |
176 } | 204 } |
177 } | 205 } |
178 | 206 |
207 void SetAngle(double angle) | |
208 { | |
209 angle_ = angle; | |
210 UpdateTransform(); | |
211 } | |
212 | |
213 double GetAngle() const | |
214 { | |
215 return angle_; | |
216 } | |
217 | |
179 bool IsVisible() const | 218 bool IsVisible() const |
180 { | 219 { |
181 return visible_; | 220 return visible_; |
182 } | 221 } |
183 | 222 |
198 } | 237 } |
199 | 238 |
200 hasSize_ = true; | 239 hasSize_ = true; |
201 width_ = width; | 240 width_ = width; |
202 height_ = height; | 241 height_ = height; |
242 | |
243 UpdateTransform(); | |
203 } | 244 } |
204 | 245 |
205 | 246 |
206 void CheckSize(unsigned int width, | 247 void CheckSize(unsigned int width, |
207 unsigned int height) | 248 unsigned int height) |
331 cairo_set_line_width(cr, 2.0 / zoom); | 372 cairo_set_line_width(cr, 2.0 / zoom); |
332 | 373 |
333 double x, y; | 374 double x, y; |
334 x = dx; | 375 x = dx; |
335 y = dy; | 376 y = dy; |
336 MapImageToScene(x, y); | 377 ApplyTransform(x, y, transform_); |
337 cairo_move_to(cr, x, y); | 378 cairo_move_to(cr, x, y); |
338 | 379 |
339 x = dx + dwidth; | 380 x = dx + dwidth; |
340 y = dy; | 381 y = dy; |
341 MapImageToScene(x, y); | 382 ApplyTransform(x, y, transform_); |
342 cairo_line_to(cr, x, y); | 383 cairo_line_to(cr, x, y); |
343 | 384 |
344 x = dx + dwidth; | 385 x = dx + dwidth; |
345 y = dy + dheight; | 386 y = dy + dheight; |
346 MapImageToScene(x, y); | 387 ApplyTransform(x, y, transform_); |
347 cairo_line_to(cr, x, y); | 388 cairo_line_to(cr, x, y); |
348 | 389 |
349 x = dx; | 390 x = dx; |
350 y = dy + dheight; | 391 y = dy + dheight; |
351 MapImageToScene(x, y); | 392 ApplyTransform(x, y, transform_); |
352 cairo_line_to(cr, x, y); | 393 cairo_line_to(cr, x, y); |
353 | 394 |
354 x = dx; | 395 x = dx; |
355 y = dy; | 396 y = dy; |
356 MapImageToScene(x, y); | 397 ApplyTransform(x, y, transform_); |
357 cairo_line_to(cr, x, y); | 398 cairo_line_to(cr, x, y); |
358 | 399 |
359 cairo_stroke(cr); | 400 cairo_stroke(cr); |
360 } | 401 } |
361 }; | 402 }; |
605 void Select(size_t bitmap) | 646 void Select(size_t bitmap) |
606 { | 647 { |
607 hasSelection_ = true; | 648 hasSelection_ = true; |
608 selectedBitmap_ = bitmap; | 649 selectedBitmap_ = bitmap; |
609 } | 650 } |
651 | |
652 | |
653 bool GetSelectedBitmap(size_t& bitmap) const | |
654 { | |
655 if (hasSelection_) | |
656 { | |
657 bitmap = selectedBitmap_; | |
658 return true; | |
659 } | |
660 else | |
661 { | |
662 return false; | |
663 } | |
664 } | |
610 | 665 |
611 | 666 |
612 virtual ~BitmapStack() | 667 virtual ~BitmapStack() |
613 { | 668 { |
614 for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); it++) | 669 for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); it++) |
689 } | 744 } |
690 | 745 |
691 | 746 |
692 void OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | 747 void OnTagsReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) |
693 { | 748 { |
694 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload)->GetValue(); | 749 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload.get())->GetValue(); |
695 | 750 |
696 printf("JSON received: [%s] (%ld bytes) for bitmap %ld\n", | 751 printf("JSON received: [%s] (%ld bytes) for bitmap %ld\n", |
697 message.Uri.c_str(), message.AnswerSize, index); | 752 message.Uri.c_str(), message.AnswerSize, index); |
698 | 753 |
699 Bitmaps::iterator bitmap = bitmaps_.find(index); | 754 Bitmaps::iterator bitmap = bitmaps_.find(index); |
718 } | 773 } |
719 | 774 |
720 | 775 |
721 void OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) | 776 void OnFrameReceived(const OrthancApiClient::BinaryResponseReadyMessage& message) |
722 { | 777 { |
723 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload)->GetValue(); | 778 size_t index = dynamic_cast<Orthanc::SingleValueObject<size_t>*>(message.Payload.get())->GetValue(); |
724 | 779 |
725 printf("Frame received: [%s] (%ld bytes) for bitmap %ld\n", | 780 printf("Frame received: [%s] (%ld bytes) for bitmap %ld\n", |
726 message.Uri.c_str(), message.AnswerSize, index); | 781 message.Uri.c_str(), message.AnswerSize, index); |
727 | 782 |
728 Bitmaps::iterator bitmap = bitmaps_.find(index); | 783 Bitmaps::iterator bitmap = bitmaps_.find(index); |
943 IStatusBar* statusBar) | 998 IStatusBar* statusBar) |
944 { | 999 { |
945 if (button == MouseButton_Left) | 1000 if (button == MouseButton_Left) |
946 { | 1001 { |
947 size_t bitmap; | 1002 size_t bitmap; |
1003 | |
948 if (stack_.LookupBitmap(bitmap, x, y)) | 1004 if (stack_.LookupBitmap(bitmap, x, y)) |
949 { | 1005 { |
950 printf("CLICK on bitmap %ld\n", bitmap); | 1006 printf("CLICK on bitmap %ld\n", bitmap); |
951 stack_.Select(bitmap); | 1007 |
952 return new MoveBitmapTracker(stack_, bitmap, x, y, | 1008 size_t selected; |
953 (modifiers & KeyboardModifiers_Shift)); | 1009 if (stack_.GetSelectedBitmap(selected) && |
1010 bitmap == selected) | |
1011 { | |
1012 return new MoveBitmapTracker(stack_, bitmap, x, y, | |
1013 (modifiers & KeyboardModifiers_Shift)); | |
1014 } | |
1015 else | |
1016 { | |
1017 stack_.Select(bitmap); | |
1018 return NULL; | |
1019 } | |
954 } | 1020 } |
955 else | 1021 else |
956 { | 1022 { |
957 printf("CLICK outside\n"); | 1023 printf("CLICK outside\n"); |
958 stack_.Unselect(); | 1024 stack_.Unselect(); |