comparison Framework/Radiography/RadiographyScene.cpp @ 409:99c9b3238008

AffineTransform2D
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 12 Nov 2018 15:38:11 +0100
parents 6834c236b36d
children 6decc0ba9da5
comparison
equal deleted inserted replaced
408:6834c236b36d 409:99c9b3238008
41 { 41 {
42 return x * x; 42 return x * x;
43 } 43 }
44 44
45 45
46 static Matrix CreateOffsetMatrix(double dx,
47 double dy)
48 {
49 Matrix m = LinearAlgebra::IdentityMatrix(3);
50 m(0, 2) = dx;
51 m(1, 2) = dy;
52 return m;
53 }
54
55
56 static Matrix CreateScalingMatrix(double sx,
57 double sy)
58 {
59 Matrix m = LinearAlgebra::IdentityMatrix(3);
60 m(0, 0) = sx;
61 m(1, 1) = sy;
62 return m;
63 }
64
65
66 static Matrix CreateRotationMatrix(double angle)
67 {
68 Matrix m;
69 const double v[] = { cos(angle), -sin(angle), 0,
70 sin(angle), cos(angle), 0,
71 0, 0, 1 };
72 LinearAlgebra::FillMatrix(m, 3, 3, v);
73 return m;
74 }
75
76
77 static void ApplyTransform(double& x /* inout */,
78 double& y /* inout */,
79 const Matrix& transform)
80 {
81 Vector p;
82 LinearAlgebra::AssignVector(p, x, y, 1);
83
84 Vector q = LinearAlgebra::Product(transform, p);
85
86 if (!LinearAlgebra::IsNear(q[2], 1.0))
87 {
88 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
89 }
90 else
91 {
92 x = q[0];
93 y = q[1];
94 }
95 }
96
97
98
99 void RadiographyScene::Layer::UpdateTransform() 46 void RadiographyScene::Layer::UpdateTransform()
100 { 47 {
101 transform_ = CreateScalingMatrix(pixelSpacingX_, pixelSpacingY_); 48 transform_ = AffineTransform2D::CreateScaling(pixelSpacingX_, pixelSpacingY_);
102 49
103 double centerX, centerY; 50 double centerX, centerY;
104 GetCenter(centerX, centerY); 51 GetCenter(centerX, centerY);
105 52
106 transform_ = LinearAlgebra::Product( 53 transform_ = AffineTransform2D::Combine(
107 CreateOffsetMatrix(panX_ + centerX, panY_ + centerY), 54 AffineTransform2D::CreateOffset(panX_ + centerX, panY_ + centerY),
108 CreateRotationMatrix(angle_), 55 AffineTransform2D::CreateRotation(angle_),
109 CreateOffsetMatrix(-centerX, -centerY), 56 AffineTransform2D::CreateOffset(-centerX, -centerY),
110 transform_); 57 transform_);
111 58
112 LinearAlgebra::InvertMatrix(transformInverse_, transform_); 59 transformInverse_ = AffineTransform2D::Invert(transform_);
113 } 60 }
114 61
115 62
116 void RadiographyScene::Layer::AddToExtent(Extent2D& extent, 63 void RadiographyScene::Layer::AddToExtent(Extent2D& extent,
117 double x, 64 double x,
118 double y) const 65 double y) const
119 { 66 {
120 ApplyTransform(x, y, transform_); 67 transform_.Apply(x, y);
121 extent.AddPoint(x, y); 68 extent.AddPoint(x, y);
122 } 69 }
123 70
124 71
125 void RadiographyScene::Layer::GetCornerInternal(double& x, 72 void RadiographyScene::Layer::GetCornerInternal(double& x,
159 106
160 default: 107 default:
161 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 108 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
162 } 109 }
163 110
164 ApplyTransform(x, y, transform_); 111 transform_.Apply(x, y);
165 } 112 }
166 113
167 114
168 bool RadiographyScene::Layer::Contains(double x, 115 bool RadiographyScene::Layer::Contains(double x,
169 double y) const 116 double y) const
170 { 117 {
171 ApplyTransform(x, y, transformInverse_); 118 transformInverse_.Apply(x, y);
172 119
173 unsigned int cropX, cropY, cropWidth, cropHeight; 120 unsigned int cropX, cropY, cropWidth, cropHeight;
174 GetCrop(cropX, cropY, cropWidth, cropHeight); 121 GetCrop(cropX, cropY, cropWidth, cropHeight);
175 122
176 return (x >= cropX && x <= cropX + cropWidth && 123 return (x >= cropX && x <= cropX + cropWidth &&
193 cairo_set_line_width(cr, 2.0 / zoom); 140 cairo_set_line_width(cr, 2.0 / zoom);
194 141
195 double x, y; 142 double x, y;
196 x = dx; 143 x = dx;
197 y = dy; 144 y = dy;
198 ApplyTransform(x, y, transform_); 145 transform_.Apply(x, y);
199 cairo_move_to(cr, x, y); 146 cairo_move_to(cr, x, y);
200 147
201 x = dx + dwidth; 148 x = dx + dwidth;
202 y = dy; 149 y = dy;
203 ApplyTransform(x, y, transform_); 150 transform_.Apply(x, y);
204 cairo_line_to(cr, x, y); 151 cairo_line_to(cr, x, y);
205 152
206 x = dx + dwidth; 153 x = dx + dwidth;
207 y = dy + dheight; 154 y = dy + dheight;
208 ApplyTransform(x, y, transform_); 155 transform_.Apply(x, y);
209 cairo_line_to(cr, x, y); 156 cairo_line_to(cr, x, y);
210 157
211 x = dx; 158 x = dx;
212 y = dy + dheight; 159 y = dy + dheight;
213 ApplyTransform(x, y, transform_); 160 transform_.Apply(x, y);
214 cairo_line_to(cr, x, y); 161 cairo_line_to(cr, x, y);
215 162
216 x = dx; 163 x = dx;
217 y = dy; 164 y = dy;
218 ApplyTransform(x, y, transform_); 165 transform_.Apply(x, y);
219 cairo_line_to(cr, x, y); 166 cairo_line_to(cr, x, y);
220 167
221 cairo_stroke(cr); 168 cairo_stroke(cr);
222 } 169 }
223 170
343 { 290 {
344 return false; 291 return false;
345 } 292 }
346 else 293 else
347 { 294 {
348 ApplyTransform(sceneX, sceneY, transformInverse_); 295 transformInverse_.Apply(sceneX, sceneY);
349 296
350 int x = static_cast<int>(std::floor(sceneX)); 297 int x = static_cast<int>(std::floor(sceneX));
351 int y = static_cast<int>(std::floor(sceneY)); 298 int y = static_cast<int>(std::floor(sceneY));
352 299
353 if (x < 0) 300 if (x < 0)
402 void RadiographyScene::Layer::GetCenter(double& centerX, 349 void RadiographyScene::Layer::GetCenter(double& centerX,
403 double& centerY) const 350 double& centerY) const
404 { 351 {
405 centerX = static_cast<double>(width_) / 2.0; 352 centerX = static_cast<double>(width_) / 2.0;
406 centerY = static_cast<double>(height_) / 2.0; 353 centerY = static_cast<double>(height_) / 2.0;
407 ApplyTransform(centerX, centerY, transform_); 354 transform_.Apply(centerX, centerY);
408 } 355 }
409 356
410 357
411 void RadiographyScene::Layer::GetCorner(double& x /* out */, 358 void RadiographyScene::Layer::GetCorner(double& x /* out */,
412 double& y /* out */, 359 double& y /* out */,
596 return false; 543 return false;
597 } 544 }
598 545
599 546
600 virtual void Render(Orthanc::ImageAccessor& buffer, 547 virtual void Render(Orthanc::ImageAccessor& buffer,
601 const Matrix& viewTransform, 548 const AffineTransform2D& viewTransform,
602 ImageInterpolation interpolation) const 549 ImageInterpolation interpolation) const
603 { 550 {
604 if (alpha_.get() == NULL) 551 if (alpha_.get() == NULL)
605 { 552 {
606 return; 553 return;
612 } 559 }
613 560
614 unsigned int cropX, cropY, cropWidth, cropHeight; 561 unsigned int cropX, cropY, cropWidth, cropHeight;
615 GetCrop(cropX, cropY, cropWidth, cropHeight); 562 GetCrop(cropX, cropY, cropWidth, cropHeight);
616 563
617 Matrix m = LinearAlgebra::Product(viewTransform, 564 const AffineTransform2D t = AffineTransform2D::Combine(
618 GetTransform(), 565 viewTransform, GetTransform(),
619 CreateOffsetMatrix(cropX, cropY)); 566 AffineTransform2D::CreateOffset(cropX, cropY));
620 567
621 Orthanc::ImageAccessor cropped; 568 Orthanc::ImageAccessor cropped;
622 alpha_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); 569 alpha_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight);
623 570
624 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false); 571 Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false);
625 ApplyProjectiveTransform(tmp, cropped, m, interpolation, true /* clear */); 572
573 t.Apply(tmp, cropped, interpolation, true /* clear */);
626 574
627 // Blit 575 // Blit
628 const unsigned int width = buffer.GetWidth(); 576 const unsigned int width = buffer.GetWidth();
629 const unsigned int height = buffer.GetHeight(); 577 const unsigned int height = buffer.GetHeight();
630 578
754 ApplyConverter(); 702 ApplyConverter();
755 } 703 }
756 704
757 705
758 virtual void Render(Orthanc::ImageAccessor& buffer, 706 virtual void Render(Orthanc::ImageAccessor& buffer,
759 const Matrix& viewTransform, 707 const AffineTransform2D& viewTransform,
760 ImageInterpolation interpolation) const 708 ImageInterpolation interpolation) const
761 { 709 {
762 if (converted_.get() != NULL) 710 if (converted_.get() != NULL)
763 { 711 {
764 if (converted_->GetFormat() != Orthanc::PixelFormat_Float32) 712 if (converted_->GetFormat() != Orthanc::PixelFormat_Float32)
767 } 715 }
768 716
769 unsigned int cropX, cropY, cropWidth, cropHeight; 717 unsigned int cropX, cropY, cropWidth, cropHeight;
770 GetCrop(cropX, cropY, cropWidth, cropHeight); 718 GetCrop(cropX, cropY, cropWidth, cropHeight);
771 719
772 Matrix m = LinearAlgebra::Product(viewTransform, 720 AffineTransform2D t = AffineTransform2D::Combine(
773 GetTransform(), 721 viewTransform, GetTransform(),
774 CreateOffsetMatrix(cropX, cropY)); 722 AffineTransform2D::CreateOffset(cropX, cropY));
775 723
776 Orthanc::ImageAccessor cropped; 724 Orthanc::ImageAccessor cropped;
777 converted_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); 725 converted_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight);
778 726
779 ApplyProjectiveTransform(buffer, cropped, m, interpolation, false); 727 t.Apply(buffer, cropped, interpolation, false);
780 } 728 }
781 } 729 }
782 730
783 731
784 virtual bool GetDefaultWindowing(float& center, 732 virtual bool GetDefaultWindowing(float& center,
1050 return extent; 998 return extent;
1051 } 999 }
1052 1000
1053 1001
1054 void RadiographyScene::Render(Orthanc::ImageAccessor& buffer, 1002 void RadiographyScene::Render(Orthanc::ImageAccessor& buffer,
1055 const Matrix& viewTransform, 1003 const AffineTransform2D& viewTransform,
1056 ImageInterpolation interpolation) const 1004 ImageInterpolation interpolation) const
1057 { 1005 {
1058 Orthanc::ImageProcessing::Set(buffer, 0); 1006 Orthanc::ImageProcessing::Set(buffer, 0);
1059 1007
1060 // Render layers in the background-to-foreground order 1008 // Render layers in the background-to-foreground order
1171 1119
1172 Orthanc::Image layers(Orthanc::PixelFormat_Float32, 1120 Orthanc::Image layers(Orthanc::PixelFormat_Float32,
1173 static_cast<unsigned int>(w), 1121 static_cast<unsigned int>(w),
1174 static_cast<unsigned int>(h), false); 1122 static_cast<unsigned int>(h), false);
1175 1123
1176 Matrix view = LinearAlgebra::Product( 1124 AffineTransform2D view = AffineTransform2D::Combine(
1177 CreateScalingMatrix(1.0 / pixelSpacingX, 1.0 / pixelSpacingY), 1125 AffineTransform2D::CreateScaling(1.0 / pixelSpacingX, 1.0 / pixelSpacingY),
1178 CreateOffsetMatrix(-extent.GetX1(), -extent.GetY1())); 1126 AffineTransform2D::CreateOffset(-extent.GetX1(), -extent.GetY1()));
1179 1127
1180 Render(layers, view, interpolation); 1128 Render(layers, view, interpolation);
1181 1129
1182 Orthanc::Image rendered(Orthanc::PixelFormat_Grayscale16, 1130 Orthanc::Image rendered(Orthanc::PixelFormat_Grayscale16,
1183 layers.GetWidth(), layers.GetHeight(), false); 1131 layers.GetWidth(), layers.GetHeight(), false);