GraphTools.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00010 /*  This program is free software; you can redistribute it and/or
00011  *  modify it under the terms of the GNU General Public
00012  *  License as published by the Free Software Foundation; either
00013  *  version 2 of the License, or (at your option) any later version.
00014  *
00015  *  This software is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  *  General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public
00021  *  License along with this software. If not, see
00022  *  <http://www.gnu.org/licenses/>.
00023  *
00024  */
00025 
00026 #include "panoinc_WX.h"
00027 #include "GraphTools.h"
00028 #include "panotools/PanoToolsInterface.h"
00029 
00030 namespace wxGraphTools
00031 {
00032 IMPLEMENT_CLASS(GraphPopupWindow, wxPopupTransientWindow)
00033 
00034 GraphPopupWindow::GraphPopupWindow(wxWindow* parent, wxBitmap bitmap) : wxPopupTransientWindow(parent)
00035 {
00036     wxPanel* panel = new wxPanel(this);
00037     m_bitmapControl = new wxStaticBitmap(panel, wxID_ANY, bitmap);
00038     panel->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(GraphPopupWindow::OnLeftDown), NULL, this);
00039     m_bitmapControl->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(GraphPopupWindow::OnLeftDown), NULL, this);
00040     m_bitmapControl->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(GraphPopupWindow::OnRightDown), NULL, this);
00041     wxBoxSizer* topsizer = new wxBoxSizer(wxHORIZONTAL);
00042     topsizer->Add(m_bitmapControl);
00043     panel->SetSizer(topsizer);
00044     topsizer->Fit(panel);
00045     topsizer->Fit(this);
00046 };
00047 
00048 void GraphPopupWindow::OnLeftDown(wxMouseEvent &e)
00049 {
00050     Dismiss();
00051 };
00052 
00053 void GraphPopupWindow::OnRightDown(wxMouseEvent &e)
00054 {
00055     wxConfigBase* config = wxConfigBase::Get();
00056     wxFileDialog dlg(this,
00057         _("Save graph"),
00058         config->Read(wxT("/actualPath"), wxT("")), wxT(""),
00059         _("Bitmap (*.bmp)|*.bmp|PNG-File (*.png)|*.png"),
00060         wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);
00061     dlg.SetDirectory(config->Read(wxT("/actualPath"), wxT("")));
00062     dlg.SetFilterIndex(config->Read(wxT("/lastImageTypeIndex"), 0l));
00063     if (dlg.ShowModal() == wxID_OK)
00064     {
00065         config->Write(wxT("/actualPath"), dlg.GetDirectory());  // remember for later
00066         wxFileName filename(dlg.GetPath());
00067         int imageType = dlg.GetFilterIndex();
00068         config->Write(wxT("/lastImageTypeIndex"), imageType);
00069         if (!filename.HasExt())
00070         {
00071             switch (imageType)
00072             {
00073                 case 1:
00074                     filename.SetExt(wxT("png"));
00075                     break;
00076                 case 0:
00077                 default:
00078                     filename.SetExt(wxT("bmp"));
00079                     break;
00080             };
00081         };
00082         if (filename.FileExists())
00083         {
00084             int d = wxMessageBox(wxString::Format(_("File %s exists. Overwrite?"), filename.GetFullPath().c_str()),
00085                 _("Save image"), wxYES_NO | wxICON_QUESTION);
00086             if (d != wxYES)
00087             {
00088                 return;
00089             }
00090         }
00091         switch (imageType)
00092         {
00093             case 1:
00094                 m_bitmapControl->GetBitmap().SaveFile(filename.GetFullPath(), wxBITMAP_TYPE_PNG);
00095                 break;
00096             case 0:
00097             default:
00098                 m_bitmapControl->GetBitmap().SaveFile(filename.GetFullPath(), wxBITMAP_TYPE_BMP);
00099                 break;
00100         };
00101     };
00102 };
00103 
00104 /*help class to draw charts */
00105 Graph::Graph(int graphWidth, int graphHeight, wxColour backgroundColour)
00106 {
00107     m_width = graphWidth;
00108     m_height = graphHeight;
00109     //create bitmap
00110     m_bitmap = new wxBitmap(m_width, m_height);
00111     m_dc.SelectObject(*m_bitmap);
00112     m_dc.SetBackground(wxBrush(backgroundColour));
00113     m_dc.Clear();
00114     //draw border
00115     m_dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)));
00116     m_dc.SetBrush(*wxTRANSPARENT_BRUSH);
00117     m_dc.DrawRectangle(0, 0, m_width, m_height);
00118     SetChartArea(0, 0, m_width, m_height);
00119     SetChartDisplay(0, 0, 1, 1);
00120 };
00121 
00123 Graph::~Graph()
00124 {
00125     m_dc.SelectObject(wxNullBitmap);
00126 };
00127 
00129 void Graph::SetChartArea(int left, int top, int right, int bottom)
00130 {
00131     m_dc.DestroyClippingRegion();
00132     m_left = left;
00133     m_top = top;
00134     m_right = right;
00135     m_bottom = bottom;
00136     m_dc.SetClippingRegion(m_left - 1, m_top - 1, m_right - m_left + 2, m_bottom - m_top + 2);
00137 };
00138 
00140 void Graph::SetChartDisplay(double xmin, double ymin, double xmax, double ymax)
00141 {
00142     m_xmin = xmin;
00143     m_ymin = ymin;
00144     m_xmax = xmax;
00145     m_ymax = ymax;
00146 };
00147 
00149 void Graph::DrawGrid(size_t linesX, size_t linesY)
00150 {
00151     m_dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)));
00152     for (size_t i = 0; i < linesX; i++)
00153     {
00154         int x = TransformX((double)i*(m_xmax - m_xmin) / (linesX - 1) + m_xmin);
00155         m_dc.DrawLine(x, m_top, x, m_bottom);
00156     };
00157     for (size_t i = 0; i < linesY; i++)
00158     {
00159         int y = TransformY((double)i*(m_ymax - m_ymin) / (linesY - 1) + m_ymin);
00160         m_dc.DrawLine(m_left, y, m_right, y);
00161     };
00162 };
00163 
00165 void Graph::DrawLine(std::vector<hugin_utils::FDiff2D> points, wxColour colour, int penWidth)
00166 {
00167     if (points.size() < 2)
00168     {
00169         return;
00170     };
00171     wxPoint *polygonPoints = new wxPoint[points.size()];
00172     for (size_t i = 0; i < points.size(); i++)
00173     {
00174         polygonPoints[i].x = TransformX(points[i].x);
00175         polygonPoints[i].y = TransformY(points[i].y);
00176     };
00177     m_dc.SetPen(wxPen(colour, penWidth));
00178     m_dc.DrawLines(points.size(), polygonPoints);
00179     delete[]polygonPoints;
00180 };
00181 
00182 const wxBitmap Graph::GetGraph() const
00183 {
00184     return *m_bitmap;
00185 };
00186 
00187 int Graph::TransformX(double x)
00188 {
00189     return hugin_utils::round((x - m_xmin) / (m_xmax - m_xmin)*(m_right - m_left) + m_left);
00190 };
00191 
00192 int Graph::TransformY(double y)
00193 {
00194     return hugin_utils::round(m_bottom - (y - m_ymin) / (m_ymax - m_ymin)*(m_bottom - m_top));
00195 };
00196 
00197 wxBitmap GetDistortionGraph(const HuginBase::SrcPanoImage& srcImage)
00198 {
00199 #define NRPOINTS 100
00200     HuginBase::PanoramaOptions opts;
00201     opts.setHFOV(srcImage.getHFOV());
00202     opts.setProjection(HuginBase::PanoramaOptions::RECTILINEAR);
00203     opts.setWidth(srcImage.getWidth());
00204     opts.setHeight(srcImage.getHeight());
00205     HuginBase::PTools::Transform transform;
00206     transform.createTransform(srcImage, opts);
00207 
00208     const double minLength = std::min<double>(srcImage.getWidth(), srcImage.getHeight()) / 2.0;
00209     const double maxR = std::sqrt(static_cast<double>(srcImage.getWidth()*srcImage.getWidth() + srcImage.getHeight()*srcImage.getHeight())) / (2.0*minLength);
00210     //draw graph
00211     Graph graph(300, 200, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
00212     graph.SetChartArea(10, 10, 290, 190);
00213     graph.SetChartDisplay(0, -0.1, maxR, 0.1);
00214     graph.DrawGrid(6, 7);
00215     std::vector<hugin_utils::FDiff2D> points;
00216     // draw helper lines
00217     // help line at r=1
00218     points.push_back(hugin_utils::FDiff2D(1, -0.1));
00219     points.push_back(hugin_utils::FDiff2D(1, 0.1));
00220     graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT), 1);
00221     points.clear();
00222     // helper line at r=width/height (for landscape images), maximal radius in horizontal (or vertical) direction
00223     // chart goes to r for diagonal
00224     const double rMaxHorzVert = std::max<double>(srcImage.getWidth(), srcImage.getHeight()) / (2.0*minLength);
00225     points.push_back(hugin_utils::FDiff2D(rMaxHorzVert, -0.1));
00226     points.push_back(hugin_utils::FDiff2D(rMaxHorzVert, 0.1));
00227     graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT), 1);
00228     points.clear();
00229     // now draw distortion graph
00230     double r = 0;
00231     for (size_t i = 0; i < NRPOINTS; i++)
00232     {
00233         double x, y;
00234         if (transform.transform(x, y, r*minLength, 0))
00235         {
00236             points.push_back(hugin_utils::FDiff2D(r, x / minLength - r));
00237         };
00238         r += maxR / (NRPOINTS - 1);
00239     };
00240     graph.DrawLine(points, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT), 2);
00241     // return bitmap
00242     return graph.GetGraph();
00243 };
00244 
00245 } // namespace

Generated on 20 Apr 2018 for Hugintrunk by  doxygen 1.4.7