Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GraphTools.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
10 /* This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This software is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public
21  * License along with this software. If not, see
22  * <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #include "panoinc_WX.h"
27 #include "GraphTools.h"
29 
30 namespace wxGraphTools
31 {
32 IMPLEMENT_CLASS(GraphPopupWindow, wxPopupTransientWindow)
33 
34 GraphPopupWindow::GraphPopupWindow(wxWindow* parent, wxBitmap bitmap) : wxPopupTransientWindow(parent)
35 {
36  m_bitmapControl = new wxStaticBitmap(this, wxID_ANY, bitmap);
37  m_bitmapControl->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(GraphPopupWindow::OnLeftDown), NULL, this);
38  m_bitmapControl->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(GraphPopupWindow::OnRightDown), NULL, this);
39  wxBoxSizer* topsizer = new wxBoxSizer(wxHORIZONTAL);
40  topsizer->Add(m_bitmapControl, wxEXPAND);
41  SetSizerAndFit(topsizer);
42 };
43 
44 void GraphPopupWindow::OnLeftDown(wxMouseEvent &e)
45 {
46  Dismiss();
47 };
48 
49 void GraphPopupWindow::OnRightDown(wxMouseEvent &e)
50 {
51  wxConfigBase* config = wxConfigBase::Get();
52  wxFileDialog dlg(this,
53  _("Save graph"),
54  config->Read(wxT("/actualPath"), wxT("")), wxT(""),
55  _("Bitmap (*.bmp)|*.bmp|PNG-File (*.png)|*.png"),
56  wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
57  dlg.SetDirectory(config->Read(wxT("/actualPath"), wxT("")));
58  dlg.SetFilterIndex(config->Read(wxT("/lastImageTypeIndex"), 0l));
59  if (dlg.ShowModal() == wxID_OK)
60  {
61  config->Write(wxT("/actualPath"), dlg.GetDirectory()); // remember for later
62  wxFileName filename(dlg.GetPath());
63  int imageType = dlg.GetFilterIndex();
64  config->Write(wxT("/lastImageTypeIndex"), imageType);
65  if (!filename.HasExt())
66  {
67  switch (imageType)
68  {
69  case 1:
70  filename.SetExt(wxT("png"));
71  break;
72  case 0:
73  default:
74  filename.SetExt(wxT("bmp"));
75  break;
76  };
77  };
78  if (filename.FileExists())
79  {
80  int d = wxMessageBox(wxString::Format(_("File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
81  _("Save image"), wxYES_NO | wxICON_QUESTION);
82  if (d != wxYES)
83  {
84  return;
85  }
86  }
87  switch (imageType)
88  {
89  case 1:
90  m_bitmapControl->GetBitmap().SaveFile(filename.GetFullPath(), wxBITMAP_TYPE_PNG);
91  break;
92  case 0:
93  default:
94  m_bitmapControl->GetBitmap().SaveFile(filename.GetFullPath(), wxBITMAP_TYPE_BMP);
95  break;
96  };
97  };
98 };
99 
100 /*help class to draw charts */
101 Graph::Graph(int graphWidth, int graphHeight, wxColour backgroundColour)
102 {
103  m_width = graphWidth;
104  m_height = graphHeight;
105  //create bitmap
106  m_bitmap = new wxBitmap(m_width, m_height);
107  m_dc.SelectObject(*m_bitmap);
108  m_dc.SetBackground(wxBrush(backgroundColour));
109  m_dc.Clear();
110  //draw border
111  m_dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)));
112  m_dc.SetBrush(*wxTRANSPARENT_BRUSH);
113  m_dc.DrawRectangle(0, 0, m_width, m_height);
114  SetChartArea(0, 0, m_width, m_height);
115  SetChartDisplay(0, 0, 1, 1);
116 };
117 
120 {
121  m_dc.SelectObject(wxNullBitmap);
122 };
123 
125 void Graph::SetChartArea(int left, int top, int right, int bottom)
126 {
127  m_dc.DestroyClippingRegion();
128  m_left = left;
129  m_top = top;
130  m_right = right;
131  m_bottom = bottom;
132  m_dc.SetClippingRegion(m_left - 1, m_top - 1, m_right - m_left + 2, m_bottom - m_top + 2);
133 };
134 
136 void Graph::SetChartDisplay(double xmin, double ymin, double xmax, double ymax)
137 {
138  m_xmin = xmin;
139  m_ymin = ymin;
140  m_xmax = xmax;
141  m_ymax = ymax;
142 };
143 
145 void Graph::DrawGrid(size_t linesX, size_t linesY)
146 {
147  m_dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)));
148  for (size_t i = 0; i < linesX; i++)
149  {
150  int x = TransformX((double)i*(m_xmax - m_xmin) / (linesX - 1) + m_xmin);
151  m_dc.DrawLine(x, m_top, x, m_bottom);
152  };
153  for (size_t i = 0; i < linesY; i++)
154  {
155  int y = TransformY((double)i*(m_ymax - m_ymin) / (linesY - 1) + m_ymin);
156  m_dc.DrawLine(m_left, y, m_right, y);
157  };
158 };
159 
161 void Graph::DrawLine(std::vector<hugin_utils::FDiff2D> points, wxColour colour, int penWidth)
162 {
163  if (points.size() < 2)
164  {
165  return;
166  };
167  wxPoint *polygonPoints = new wxPoint[points.size()];
168  for (size_t i = 0; i < points.size(); i++)
169  {
170  polygonPoints[i].x = TransformX(points[i].x);
171  polygonPoints[i].y = TransformY(points[i].y);
172  };
173  m_dc.SetPen(wxPen(colour, penWidth));
174  m_dc.DrawLines(points.size(), polygonPoints);
175  delete[]polygonPoints;
176 };
177 
178 const wxBitmap Graph::GetGraph() const
179 {
180  return *m_bitmap;
181 };
182 
183 int Graph::TransformX(double x)
184 {
185  return hugin_utils::round((x - m_xmin) / (m_xmax - m_xmin)*(m_right - m_left) + m_left);
186 };
187 
188 int Graph::TransformY(double y)
189 {
190  return hugin_utils::round(m_bottom - (y - m_ymin) / (m_ymax - m_ymin)*(m_bottom - m_top));
191 };
192 
194 {
195 #define NRPOINTS 100
197  opts.setHFOV(srcImage.getHFOV());
199  opts.setWidth(srcImage.getWidth());
200  opts.setHeight(srcImage.getHeight());
202  transform.createTransform(srcImage, opts);
203 
204  const double minLength = std::min<double>(srcImage.getWidth(), srcImage.getHeight()) / 2.0;
205  const double maxR = std::sqrt(static_cast<double>(srcImage.getWidth()*srcImage.getWidth() + srcImage.getHeight()*srcImage.getHeight())) / (2.0*minLength);
206  //draw graph
207  Graph graph(300, 200, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
208  graph.SetChartArea(10, 10, 290, 190);
209  graph.SetChartDisplay(0, -0.1, maxR, 0.1);
210  graph.DrawGrid(6, 7);
211  std::vector<hugin_utils::FDiff2D> points;
212  // draw helper lines
213  // help line at r=1
214  points.push_back(hugin_utils::FDiff2D(1, -0.1));
215  points.push_back(hugin_utils::FDiff2D(1, 0.1));
216  graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT), 1);
217  points.clear();
218  // helper line at r=width/height (for landscape images), maximal radius in horizontal (or vertical) direction
219  // chart goes to r for diagonal
220  const double rMaxHorzVert = std::max<double>(srcImage.getWidth(), srcImage.getHeight()) / (2.0*minLength);
221  points.push_back(hugin_utils::FDiff2D(rMaxHorzVert, -0.1));
222  points.push_back(hugin_utils::FDiff2D(rMaxHorzVert, 0.1));
223  graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT), 1);
224  points.clear();
225  // now draw distortion graph
226  double r = 0;
227  for (size_t i = 0; i < NRPOINTS; i++)
228  {
229  double x, y;
230  if (transform.transform(x, y, r*minLength, 0))
231  {
232  points.push_back(hugin_utils::FDiff2D(r, x / minLength - r));
233  };
234  r += maxR / (NRPOINTS - 1);
235  };
236  graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 2);
237  // return bitmap
238  return graph.GetGraph();
239 };
240 
241 } // namespace
void OnLeftDown(wxMouseEvent &e)
Definition: GraphTools.cpp:44
wxBitmap * m_bitmap
Definition: GraphTools.h:81
#define NRPOINTS
void setHeight(unsigned int h)
set panorama height
wxStaticBitmap * m_bitmapControl
Definition: GraphTools.h:46
simple popup to show graph
Definition: GraphTools.h:38
wxMemoryDC m_dc
Definition: GraphTools.h:82
int getHeight() const
Get the height of the image in pixels.
Definition: SrcPanoImage.h:276
vigra::pair< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImage(const ROIImage< Image, Mask > &img)
Definition: ROIImage.h:300
void DrawGrid(size_t linesX, size_t linesY)
draws the grid with linesX lines in x-direction and linexY lines in y-direction
Definition: GraphTools.cpp:145
bool transform(double &x_dest, double &y_dest, double x_src, double y_src) const
excecute transform
double round(double x)
Definition: hugin_math.h:50
~Graph()
destructor
Definition: GraphTools.cpp:119
void OnRightDown(wxMouseEvent &e)
Definition: GraphTools.cpp:49
int getWidth() const
Get the width of the image in pixels.
Definition: SrcPanoImage.h:266
int TransformX(double x)
Definition: GraphTools.cpp:183
void SetChartArea(int left, int top, int right, int bottom)
set where to draw the chart on the bitmap
Definition: GraphTools.cpp:125
void SetChartDisplay(double xmin, double ymin, double xmax, double ymax)
set the real dimension of the chart
Definition: GraphTools.cpp:136
void DrawLine(std::vector< hugin_utils::FDiff2D > points, wxColour colour, int penWidth=1)
draws a line with the coordinates given in points
Definition: GraphTools.cpp:161
void setHFOV(double h, bool keepView=true)
set the horizontal field of view.
help class to draw charts
Definition: GraphTools.h:51
include file for the hugin project
Holds transformations for Image -&gt; Pano and the other way.
int TransformY(double y)
Definition: GraphTools.cpp:188
wxBitmap GetDistortionGraph(const HuginBase::SrcPanoImage &srcImage)
return wxBitmap with graph of distortion for given SrcPanoImage
Definition: GraphTools.cpp:193
const wxBitmap GetGraph() const
Definition: GraphTools.cpp:178
All variables of a source image.
Definition: SrcPanoImage.h:194
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
Panorama image options.
Graph(int graphWidth, int graphHeight, wxColour backgroundColour)
constructors, set size and background colour of resulting bitmap
Definition: GraphTools.cpp:101
void createTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
initialize pano-&gt;image transformation
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true