TBTK
Need a break? Support the development by playing Polarity Puzzles
PlotCanvas.h
1 /* Copyright 2017 Kristofer Björnson
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
17 
24 #ifndef COM_DAFER45_TBTK_PLOT_CANVAS
25 #define COM_DAFER45_TBTK_PLOT_CANVAS
26 
27 #include "TBTK/TBTKMacros.h"
28 
29 #include <string>
30 
31 #include <opencv2/core/core.hpp>
32 #include <opencv2/highgui/highgui.hpp>
33 #include <opencv2/imgproc/imgproc.hpp>
34 
35 namespace TBTK{
36 namespace Plot{
37 
38 class PlotCanvas{
39 public:
41  PlotCanvas();
42 
44  ~PlotCanvas();
45 
47  void setWidth(unsigned int width);
48 
50  void setHeight(unsigned int height);
51 
53  void setPadding(
54  double paddingLeft,
55  double paddingRight,
56  double paddingBottom,
57  double paddingTop
58  );
59 
61  void setBoundsX(double minX, double maxX);
62 
64  void setBoundsY(double minY, double maxY);
65 
67  void setBounds(double minX, double maxX, double minY, double maxY);
68 
70  double getMinX() const;
71 
73  double getMaxX() const;
74 
76  double getMinY() const;
77 
79  double getMaxY() const;
80 
82  void setLabelX(const std::string &labelX);
83 
85  void setLabelY(const std::string &labelY);
86 
88  void setShowColorBox(bool showColorBox);
89 
91  bool getShowColorBox() const;
92 
94  void setBoundsColor(double minColor, double maxColor);
95 
97  void setCanvas(cv::Mat &canvas);
98 
100  const cv::Mat& getCanvas() const;
101 
103  void clear();
104 
106  void setPixel(
107  unsigned int x,
108  unsigned int y,
109  unsigned char red,
110  unsigned char green,
111  unsigned char blue
112  );
113 
115  void drawLine(
116  double x0,
117  double y0,
118  double x1,
119  double y1,
120  const std::vector<unsigned char> &color,
121  unsigned int width
122  );
123 
125  void drawCircle(
126  double x,
127  double y,
128  unsigned int size,
129  const std::vector<unsigned char> &color
130  );
131 
133  void save(std::string filename) const;
134 private:
136  cv::Mat canvas;
137 
139  double width, height;
140 
142  unsigned int paddingLeft, paddingRight, paddingBottom, paddingTop;
143 
145  double minX, maxX, minY, maxY;
146 
148  std::string labelX, labelY;
149 
151  bool showColorBox;
152 
154  double minColor, maxColor;
155 
157  static constexpr unsigned int COLOR_BOX_WINDOW_WIDTH = 100;
158 
160  void drawColorBox();
161 public:
164  cv::Point getCVPoint(double x, double y) const;
165 
167  void drawAxes();
168 };
169 
170 inline void PlotCanvas::setWidth(unsigned int width){
171  this->width = width;
172 }
173 
174 inline void PlotCanvas::setHeight(unsigned int height){
175  this->height = height;
176 }
177 
178 inline void PlotCanvas::setPadding(
179  double paddingLeft,
180  double paddingRight,
181  double paddingBottom,
182  double paddingTop
183 ){
184  this->paddingLeft = paddingLeft;
185  this->paddingRight = paddingRight;
186  this->paddingBottom = paddingBottom;
187  this->paddingTop = paddingTop;
188 }
189 
190 inline void PlotCanvas::setBoundsX(
191  double minX,
192  double maxX
193 ){
194  TBTKAssert(
195  minX <= maxX,
196  "Canvas::setBoundsX()",
197  "minX has to be smaller than maxX.",
198  ""
199  );
200 
201  if(minX == maxX){
202  this->minX = minX - 1e-10;
203  this->maxX = maxX + 1e-10;
204  }
205  else{
206  this->minX = minX;
207  this->maxX = maxX;
208  }
209 }
210 
211 inline void PlotCanvas::setBoundsY(
212  double minY,
213  double maxY
214 ){
215  TBTKAssert(
216  minY <= maxY,
217  "Canvas::setBoundsY()",
218  "minY has to be smaller than maxY.",
219  ""
220  );
221 
222  if(minY == maxY){
223  this->minY = minY - 1e-10;
224  this->maxY = maxY + 1e-10;
225  }
226  else{
227  this->minY = minY;
228  this->maxY = maxY;
229  }
230 }
231 
232 inline void PlotCanvas::setBounds(
233  double minX,
234  double maxX,
235  double minY,
236  double maxY
237 ){
238  setBoundsX(minX, maxX);
239  setBoundsY(minY, maxY);
240 }
241 
242 inline double PlotCanvas::getMinX() const{
243  return minX;
244 }
245 
246 inline double PlotCanvas::getMaxX() const{
247  return maxX;
248 }
249 
250 inline double PlotCanvas::getMinY() const{
251  return minY;
252 }
253 
254 inline double PlotCanvas::getMaxY() const{
255  return maxY;
256 }
257 
258 inline void PlotCanvas::setLabelX(const std::string &labelX){
259  this->labelX = labelX;
260 }
261 
262 inline void PlotCanvas::setLabelY(const std::string &labelY){
263  this->labelY = labelY;
264 }
265 
266 inline void PlotCanvas::setShowColorBox(bool showColorBox){
267  this->showColorBox = showColorBox;
268 }
269 
270 inline bool PlotCanvas::getShowColorBox() const{
271  return showColorBox;
272 }
273 
274 inline void PlotCanvas::setBoundsColor(double minColor, double maxColor){
275  this->minColor = minColor;
276  this->maxColor = maxColor;
277 }
278 
279 inline void PlotCanvas::setCanvas(cv::Mat &canvas){
280  this->canvas = canvas;
281 }
282 
283 inline const cv::Mat& PlotCanvas::getCanvas() const{
284  return canvas;
285 }
286 
287 inline cv::Point PlotCanvas::getCVPoint(double x, double y) const{
288  double width = maxX - minX;
289  double height = maxY - minY;
290  return cv::Point(
291  paddingLeft + (1 - (paddingLeft + paddingRight + showColorBox*COLOR_BOX_WINDOW_WIDTH)/(double)canvas.cols)*canvas.cols*(x - minX)/(double)width,
292  canvas.rows - 1 - (paddingBottom + (1 - (paddingBottom + paddingTop)/(double)canvas.rows)*canvas.rows*(y - minY)/(double)height)
293  );
294 }
295 
296 inline void PlotCanvas::clear(){
297  canvas = cv::Mat::zeros(height, width, CV_8UC3);
298  cv::rectangle(
299  canvas,
300  cv::Point(0, 0),
301  cv::Point(width-1, height-1),
302  cv::Scalar(255, 255, 255),
303 #if CV_MAJOR_VERSION > 3
304  cv::FILLED,
305 #else
306  CV_FILLED,
307 #endif
308  8,
309  0
310  );
311 }
312 
313 inline void PlotCanvas::setPixel(
314  unsigned int x,
315  unsigned int y,
316  unsigned char red,
317  unsigned char green,
318  unsigned char blue
319 ){
320  canvas.at<cv::Vec3b>(y, x)[0] = blue;
321  canvas.at<cv::Vec3b>(y, x)[1] = green;
322  canvas.at<cv::Vec3b>(y, x)[2] = red;
323 }
324 
325 inline void PlotCanvas::drawLine(
326  double x0,
327  double y0,
328  double x1,
329  double y1,
330  const std::vector<unsigned char> &color,
331  unsigned int width
332 ){
333  //Clip lines
334  if(x1 < x0){
335  double temp = x0;
336  x0 = x1;
337  x1 = temp;
338  temp = y0;
339  y0 = y1;
340  y1 = temp;
341  }
342  if(x0 < minX && x1 < minX)
343  return;
344  if(x0 > maxX && x1 > maxX)
345  return;
346  if(x0 < minX){
347  if(x1 - x0 != 0)
348  y0 += (minX - x0)*(y1 - y0)/(x1 - x0);
349  x0 = minX;
350  }
351  if(x1 > maxX){
352  if(x1 - x0 != 0)
353  y1 -= (x1 - maxX)*(y1 - y0)/(x1 - x0);
354  x1 = maxX;
355  }
356  if(y0 < minY && y1 < minY)
357  return;
358  if(y0 > maxY && y1 > maxY)
359  return;
360  if(y0 < minY){
361  if(y1 - y0 != 0)
362  x0 += (minY - y0)*(x1 - x0)/(y1 - y0);
363  y0 = minY;
364  }
365  if(y1 > maxY){
366  if(y1 - y0 != 0)
367  x1 -= (y1 - maxY)*(x1 - x0)/(y1 - y0);
368  y1 = maxY;
369  }
370 
371  //Draw line
372  cv::line(
373  canvas,
374  getCVPoint(x0, y0),
375  getCVPoint(x1, y1),
376  cv::Scalar(color[2], color[1], color[0]),
377  width,
378 #if CV_MAJOR_VERSION > 3
379  cv::LINE_AA
380 #else
381  CV_AA
382 #endif
383  );
384 }
385 
386 inline void PlotCanvas::drawCircle(
387  double x,
388  double y,
389  unsigned int size,
390  const std::vector<unsigned char> &color
391 ){
392  //Clip point
393  if(x < minX)
394  return;
395  if(x > maxX)
396  return;
397  if(y < minY)
398  return;
399  if(y > maxY)
400  return;
401 
402  //Draw cirlce
403  cv::circle(
404  canvas,
405  getCVPoint(x, y),
406  size,
407  cv::Scalar(color[2], color[1], color[0]),
408  -1,
409 #if CV_MAJOR_VERSION > 3
410  cv::LINE_AA
411 #else
412  CV_AA
413 #endif
414  );
415 }
416 
417 inline void PlotCanvas::save(std::string filename) const{
418  imwrite(filename, canvas);
419 }
420 
421 }; //End namespace Plot
422 }; //End namespace TBTK
423 
424 #endif
425 
Precompiler macros.
Definition: Boolean.h:32