Click here to Skip to main content
15,897,187 members
Articles / Desktop Programming / MFC

The Diffraction Grating Calculator

Rate me:
Please Sign up or sign in to vote.
4.40/5 (5 votes)
30 Oct 2010GPL38 min read 41.5K   678   6  
An MFC Windows program related to Concave Diffraction Gratings using VTK libraries.
// Plot2DFocalPlanes.cpp : implementation file

#include "stdafx.h"
#include "GratingCalculator.h"
#include "Plot2DFocalPlanes.h"

#include "Directory.h"
#include "ObjectList.h"
#include "FocalSpotObj.h"
#include "GratSimulation.h"
#include "DataHolderSingleton.h"
#include "SimRunEngineSingleton.h"
#include "PlotProperties.h"
#include "MainFrm.h"

#include "ChartXYSerie.h"
#include "ChartLineSerie.h"
#include "ChartPointsSerie.h"
#include "ChartSurfaceSerie.h"
#include "ChartGrid.h"
#include "ChartBarSerie.h"
#include "ChartLabel.h"
#include "ChartAxisLabel.h"
#include "ChartStandardAxis.h"
#include "ChartDateTimeAxis.h"
#include "ChartCrossHairCursor.h"
#include "ChartDragLineCursor.h"

#include <math.h>
#include <stdlib.h>
#include <sstream>
#include <iomanip>

using namespace std;

// CPlot2DFocalPlanes

void CCustomCursorListener1::OnCursorMoved(CChartCursor *pCursor, double xValue, double yValue)
{
   CMainFrame::m_PosX = xValue;
   CMainFrame::m_PosY = yValue;
}

IMPLEMENT_DYNCREATE(CPlot2DFocalPlanes, CView)

CPlot2DFocalPlanes::CPlot2DFocalPlanes()
{
   m_bInitCreate = false;
   m_bInitUpdate = false;

   m_SeriesColour[0]  = RGB(255,  0,  0);
   m_SeriesColour[1]  = RGB(255,  0,  0);
   m_SeriesColour[2]  = RGB(  0,255,  0);
   m_SeriesColour[3]  = RGB(  0,255,  0);
   m_SeriesColour[4]  = RGB(  0,  0,255);
   m_SeriesColour[5]  = RGB(  0,  0,255);
   m_SeriesColour[6]  = RGB( 64,  0,  0);
   m_SeriesColour[7]  = RGB( 64,  0,  0);
   m_SeriesColour[8]  = RGB(128,128,  0);
   m_SeriesColour[9]  = RGB(128,128,  0);
   m_SeriesColour[10] = RGB(  0,192,192);
   m_SeriesColour[11] = RGB(  0,192,192);
   m_SeriesColour[12] = RGB(255,128,  0);
   m_SeriesColour[13] = RGB(255,128,  0);
   m_SeriesColour[14] = RGB(128,  0,  0);
   m_SeriesColour[15] = RGB(128,  0,  0);
   m_SeriesColour[16] = RGB(  0,128,128);
   m_SeriesColour[17] = RGB(  0,128,128);
   m_SeriesColour[18] = RGB(128, 64, 64);
   m_SeriesColour[19] = RGB(128, 64, 64);
   m_SeriesColour[20] = RGB(  0,128,  0);
   m_SeriesColour[21] = RGB(  0,128,  0);
   m_SeriesColour[22] = RGB(192,  0,192);
   m_SeriesColour[23] = RGB(192,  0,192);
   m_SeriesColour[24] = RGB(  0,  0, 64);
   m_SeriesColour[25] = RGB(  0,  0, 64);
   m_SeriesColour[26] = RGB(128,  0,128);
   m_SeriesColour[27] = RGB(128,  0,128);
   m_SeriesColour[28] = RGB( 64, 64,  0);
   m_SeriesColour[29] = RGB( 64, 64,  0);
   m_SeriesColour[30] = RGB(128,  0,  0);
   m_SeriesColour[31] = RGB(128,  0,  0);
   m_SeriesColour[32] = RGB(128,128,128);
   m_SeriesColour[33] = RGB(128,128,128);
   m_SeriesColour[34] = RGB(128,128,255);
   m_SeriesColour[35] = RGB(128,128,255);
   for (int k=36; k<MAX_SERIES_NO; k++)
   {
      m_SeriesColour[k] = RGB(0,0,0);
   }

   CSimRunEngineSingleton::GetInstance()->SetObserver((CWnd*) this);
}

CPlot2DFocalPlanes::~CPlot2DFocalPlanes()
{
}

BEGIN_MESSAGE_MAP(CPlot2DFocalPlanes, CView)
   ON_WM_CREATE()
   ON_WM_SIZE()
   ON_COMMAND(ID_DISPLAY_PLOT2DFOCALLINES, &CPlot2DFocalPlanes::OnPlotData)
   ON_COMMAND(ID_DISPLAY_RESETPLOT, &CPlot2DFocalPlanes::OnPlotReset)
   ON_COMMAND(ID_DISPLAY_PLOTPROPERTIES, &CPlot2DFocalPlanes::OnPlotProp)
   ON_MESSAGE(WM_SIM_MSG_ENDED, &CPlot2DFocalPlanes::OnPlot)
   ON_COMMAND(ID_FILE_PRINT, &CPlot2DFocalPlanes::OnFilePrint)
   ON_COMMAND(ID_FILE_PRINT_DIRECT, &CPlot2DFocalPlanes::OnFilePrint)
END_MESSAGE_MAP()

// CPlot2DFocalPlanes drawing

void CPlot2DFocalPlanes::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

// CPlot2DFocalPlanes diagnostics

#ifdef _DEBUG
void CPlot2DFocalPlanes::AssertValid() const
{
	CView::AssertValid();
}

#ifndef _WIN32_WCE
void CPlot2DFocalPlanes::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif
#endif //_DEBUG

// CPlot2DFocalPlanes message handlers

int CPlot2DFocalPlanes::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
   if (CView::OnCreate(lpCreateStruct) == -1)
      return -1;

   if ( !m_bInitCreate )
   {
      CRect rect;
      GetClientRect(&rect);
      m_PlotChart.Create(this,rect,998);
   }

   m_bInitCreate = true;

   return 0;
}

void CPlot2DFocalPlanes::OnSize(UINT nType, int cx, int cy)
{
   CView::OnSize(nType, cx, cy);

   if (m_PlotChart.GetSafeHwnd())
   {
      CRect rect;
      GetClientRect(rect);
      m_PlotChart.MoveWindow(rect);
   }
}

void CPlot2DFocalPlanes::OnInitialUpdate()
{
   CView::OnInitialUpdate();

   if (!m_bInitUpdate)
   {
      // 1. Chart init
      SetChartDefaults();

      // 2. Set up the chart with default values
      InitPlotChart();

      m_pMouseListener = new CCustomMouseListener1;
      m_pVertCursor = m_PlotChart.CreateDragLineCursor(CChartCtrl::BottomAxis);
      m_pHorzCursor = m_PlotChart.CreateDragLineCursor(CChartCtrl::LeftAxis);
      m_pCursorListener = new CCustomCursorListener1;
      m_pVertCursor->RegisterListener(m_pCursorListener);
      m_pHorzCursor->RegisterListener(m_pCursorListener);
   }

   m_PlotChart.RefreshCtrl();
   m_bInitUpdate = true;
}

void CPlot2DFocalPlanes::SetChartDefaults(void)
{
   m_dBottomAxisMin = 0.0;
   m_dBottomAxisMax = 100.0;
   m_dLeftAxisMin   = 0.0;
   m_dLeftAxisMax   = 100.0;
   m_dTopAxisMin    = 0.0;
   m_dTopAxisMax    = 100.0;
   m_dRightAxisMin  = 0.0;
   m_dRightAxisMax  = 100.0;

   _tcscpy(m_czBottomAxisLabel,_T("X Focal Plane Position [cm]"));
   _tcscpy(m_czLeftAxisLabel,_T("Y Focal Plane Position [cm]"));
   _tcscpy(m_czTopAxisLabel,_T(""));
   _tcscpy(m_czRightAxisLabel,_T("Y Focal Plane Position [cm]"));

   _tcscpy(m_czPlotTitle,_T("Focal Plane Positions"));

   // Set the grids
   m_bBottomAxisGrid = true;
   m_bLeftAxisGrid = true;
   m_bTopAxisGrid = true;
   m_bRightAxisGrid = true;

   // Series Properties (defaults)
   for (int k=0; k<MAX_SERIES_NO; k=k+2)
   {
      // 0) Line, 1) Points, 2) Surface
      m_nSeriesType[k] = 0;
      m_nSeriesType[k+1] = 1;

      m_nLineWidth[k]   = 2;
      m_nLineWidth[k+1] = 2;
      m_nPenStyle[k]    = PS_SOLID;
      m_nPenStyle[k+1]  = PS_SOLID;

      m_nPointsType[k]     = CChartPointsSerie::ptTriangle;
      m_nPointsType[k+1]   = CChartPointsSerie::ptTriangle;
      m_nPointsWidth[k]    = 8;
      m_nPointsWidth[k+1]  = 8;
      m_nPointsHeight[k]   = 8;
      m_nPointsHeight[k+1] = 8;
   }

   m_BackgroundColor = RGB( 250, 250, 104 );
}

void CPlot2DFocalPlanes::InitPlotChart(void)
{
   // 1. Axis defs
   CChartStandardAxis* pBottomAxis = NULL;
   pBottomAxis = m_PlotChart.CreateStandardAxis(CChartCtrl::BottomAxis);
   if (pBottomAxis)
   {
      pBottomAxis->SetMinMax(m_dBottomAxisMin, m_dBottomAxisMax);
      pBottomAxis->GetLabel()->SetVisible(true);
      pBottomAxis->GetLabel()->SetText(m_czBottomAxisLabel);
      pBottomAxis->GetGrid()->SetVisible(true);
   }

   CChartStandardAxis* pLeftAxis = NULL;
   pLeftAxis = m_PlotChart.CreateStandardAxis(CChartCtrl::LeftAxis);
   if (pLeftAxis)
   {
      pLeftAxis->SetMinMax(m_dLeftAxisMin, m_dLeftAxisMax);
      pLeftAxis->GetLabel()->SetVisible(true);
      pLeftAxis->GetLabel()->SetText(m_czLeftAxisLabel);
      pLeftAxis->GetGrid()->SetVisible(true);
   }

   CChartStandardAxis* pTopAxis = NULL;
   pTopAxis = m_PlotChart.CreateStandardAxis(CChartCtrl::TopAxis);
   if (pTopAxis)
   {
      pTopAxis->SetMinMax(m_dTopAxisMin, m_dTopAxisMax);
      pTopAxis->GetLabel()->SetVisible(false);
      pTopAxis->GetLabel()->SetText(m_czTopAxisLabel);
      pTopAxis->GetGrid()->SetVisible(true);
   }

   CChartStandardAxis* pRightAxis = NULL;
   pRightAxis = m_PlotChart.CreateStandardAxis(CChartCtrl::RightAxis);
   if (pRightAxis)
   {
      pRightAxis->SetMinMax(m_dRightAxisMin, m_dRightAxisMax);
      pRightAxis->GetLabel()->SetVisible(true);
      pRightAxis->GetLabel()->SetText(m_czRightAxisLabel);
      pRightAxis->GetGrid()->SetVisible(true);
   }

   // 2. Background Color
   m_PlotChart.SetBackColor(m_BackgroundColor);

   // 3. Legend
   m_PlotChart.GetLegend()->SetVisible(true);

   // 4. Title
   CChartTitle* pTitle = NULL;
   pTitle = m_PlotChart.GetTitle();
   if (pTitle)
   {
      pTitle->RemoveAll();
      pTitle->AddString(m_czPlotTitle);
   }

   // 5. Zoom
   m_PlotChart.SetZoomEnabled(true);

   // 6. Refresh
   m_PlotChart.RefreshCtrl();
}

void CPlot2DFocalPlanes::SetChartProperties(void)
{
   // 1. Axis defs
   CChartAxis* pBottomAxis = NULL;
   pBottomAxis = m_PlotChart.GetBottomAxis();
   if (pBottomAxis)
   {
      pBottomAxis->SetMinMax(m_dBottomAxisMin, m_dBottomAxisMax);
      pBottomAxis->GetLabel()->SetVisible(true);
      pBottomAxis->GetLabel()->SetText(m_czBottomAxisLabel);
      pBottomAxis->GetGrid()->SetVisible(m_bBottomAxisGrid);
   }

   CChartAxis* pLeftAxis = NULL;
   pLeftAxis = m_PlotChart.GetLeftAxis();
   if (pLeftAxis)
   {
      pLeftAxis->SetMinMax(m_dLeftAxisMin, m_dLeftAxisMax);
      pLeftAxis->GetLabel()->SetVisible(true);
      pLeftAxis->GetLabel()->SetText(m_czLeftAxisLabel);
      pLeftAxis->GetGrid()->SetVisible(m_bLeftAxisGrid);
   }

   CChartAxis* pTopAxis = NULL;
   pTopAxis = m_PlotChart.GetTopAxis();
   if (pTopAxis)
   {
      pTopAxis->SetMinMax(m_dTopAxisMin, m_dTopAxisMax);
      pTopAxis->GetLabel()->SetVisible(false);
      pTopAxis->GetLabel()->SetText(m_czTopAxisLabel);
      pTopAxis->GetGrid()->SetVisible(m_bTopAxisGrid);
   }

   CChartAxis* pRightAxis = NULL;
   pRightAxis = m_PlotChart.GetRightAxis();
   if (pRightAxis)
   {
      pRightAxis->SetMinMax(m_dRightAxisMin, m_dRightAxisMax);
      pRightAxis->GetLabel()->SetVisible(true);
      pRightAxis->GetLabel()->SetText(m_czRightAxisLabel);
      pRightAxis->GetGrid()->SetVisible(m_bRightAxisGrid);
   }

   // 2. Background Color
   m_PlotChart.SetBackColor(m_BackgroundColor);

   // 3. Legend
   m_PlotChart.GetLegend()->SetVisible(true);

   // 4. Title
   CChartTitle* pTitle = NULL;
   pTitle = m_PlotChart.GetTitle();
   if (pTitle)
   {
      pTitle->RemoveAll();
      pTitle->AddString(m_czPlotTitle);
   }
}

void CPlot2DFocalPlanes::AddSeriesToChart(int k, CObjectList* pList)
{
   CChartXYSerie* pSeries = NULL;
   switch (m_nSeriesType[k])
   {
      // Line series
   case 0:
      {
         CChartLineSerie* pLineSeries = NULL;
         pLineSeries = m_PlotChart.CreateLineSerie();
         if (pLineSeries)
         {
            pLineSeries->SetWidth(m_nLineWidth[k]);
            pLineSeries->SetPenStyle(m_nPenStyle[k]);
            pSeries = pLineSeries;
         }
      }
      break;

      // Points series
   case 1:
      {
         CChartPointsSerie* pPointsSeries = NULL;
         pPointsSeries = m_PlotChart.CreatePointsSerie();
         if (pPointsSeries)
         {
            switch (m_nPointsType[k])
            {
            case 0:
               pPointsSeries->SetPointType(CChartPointsSerie::ptEllipse);
               break;

            case 1:
               pPointsSeries->SetPointType(CChartPointsSerie::ptRectangle);
               break;

            case 2:
               pPointsSeries->SetPointType(CChartPointsSerie::ptTriangle);
               break;
            }
            pPointsSeries->SetPointSize(m_nPointsWidth[k],m_nPointsHeight[k]);
            pSeries = pPointsSeries;
         }
      }
      break;

      // No Surface series
   case 2:
      {
         pSeries = NULL;
      }
      break;

   default:
      {
         pSeries = NULL;
      }
      break;
   }

   if (NULL == pSeries)
      return;

   pSeries->RegisterMouseListener(m_pMouseListener);

   pSeries->SetSeriesOrdering(poNoOrdering);

   double dAngle;
   ((CFocalSpotObj*) pList->GetObjectByIdx(0))->GetAttribute(FS_ANGLE)->Get_Double(dAngle);
   CString szName;
   szName.Format(_T("Angle = %06f"),dAngle);

   pSeries->SetName(szName.GetBuffer());
   pSeries->SetColor(m_SeriesColour[k]);

   // Retrieve the data
   // buffers...
   UINT32 kount = pList->GetObjectCount();

   double *dXpoints = new double[kount];
   double *dYpoints = new double[kount];

   CFocalSpotObj* pObj = NULL;
   for (UINT32 iObj = 0; iObj < kount; iObj++)
   {
      pObj = NULL;
      pObj = (CFocalSpotObj*) pList->GetObjectByIdx(iObj);
      if (pObj)
      {
         pObj->GetAttribute(FS_POS_X)->Get_Double(dXpoints[iObj]);
         pObj->GetAttribute(FS_POS_Y)->Get_Double(dYpoints[iObj]);
      }
   }

   pSeries->SetPoints(dXpoints,dYpoints,(unsigned int) kount);

   try { delete [] dXpoints; } catch(...) { NULL; }
   try { delete [] dYpoints; } catch(...) { NULL; }
}

void CPlot2DFocalPlanes::PlotDataToChart()
{
   m_PlotChart.RemoveAllSeries();

   CGratSimulation* pSim = NULL;
   pSim = CDataHolderSingleton::GetInstance()->GetSimulation();

   // if no data just reset chart
   if ( NULL == pSim || pSim->GetList()->GetObjectCount() == 0 )
   {
      SetChartDefaults();
      SetChartProperties();
      m_PlotChart.RefreshCtrl();
      return;
   }

   // set all charts & series properties
   m_dBottomAxisMin = 1.0e+33;
   m_dBottomAxisMax = 0.0;
   m_dLeftAxisMin   = 1.0e+33;
   m_dLeftAxisMax   = 0.0;
   double X, Y;
   CFocalSpotObj* pObj = NULL;
   pObj = pSim->GetFirstResult();
   while(pObj)
   {
      pObj->GetAttribute(FS_POS_X)->Get_Double(X);
      pObj->GetAttribute(FS_POS_Y)->Get_Double(Y);
      if ( X <= m_dBottomAxisMin )
         m_dBottomAxisMin = X;
      if ( X >= m_dBottomAxisMax )
         m_dBottomAxisMax = X;
      if ( Y <= m_dLeftAxisMin )
         m_dLeftAxisMin = Y;
      if ( X >= m_dLeftAxisMax )
         m_dLeftAxisMax = Y;
      pObj = pSim->GetNextResult();
   }
   m_dBottomAxisMin = m_dBottomAxisMin - 0.1*m_dBottomAxisMin;
   m_dBottomAxisMax = m_dBottomAxisMax + 0.1*m_dBottomAxisMax;
   m_dLeftAxisMin = m_dLeftAxisMin - 0.1*m_dLeftAxisMin;
   m_dLeftAxisMax = m_dLeftAxisMax + 0.1*m_dLeftAxisMax;
   m_dTopAxisMin = m_dBottomAxisMin;
   m_dTopAxisMax = m_dBottomAxisMax;
   m_dRightAxisMin = m_dLeftAxisMin;
   m_dRightAxisMax = m_dLeftAxisMax;

   SetChartProperties();

   int k = 0;
   CObjectList List;
   pObj = pSim->GetFirstResult();
   double dAngle, dAnglePrevious;
   int i = 0;
   while(pObj)
   {
      pObj->GetAttribute(FS_ANGLE)->Get_Double(dAngle);
      if ( i == 0 )
      {
         dAnglePrevious = dAngle;
         i++;
      }
      if ( dAnglePrevious == dAngle )
      {
         List.AddObject((POINTER) pObj);
      }
      else
      {
         // Add data to chart
         AddSeriesToChart(k,&List);
         k++;
         AddSeriesToChart(k,&List);
         k++;
         List.EraseAllEntries();
         List.AddObject((POINTER) pObj);
      }
      dAnglePrevious = dAngle;
      pObj = pSim->GetNextResult();
      if ( pObj == NULL ) // Last series
      {
         // Add data to chart
         AddSeriesToChart(k,&List);
         k++;
         AddSeriesToChart(k,&List);
         k++;
         List.EraseAllEntries();
      }
   }

   // Refresh
   m_PlotChart.RefreshCtrl();
}

LRESULT CPlot2DFocalPlanes::OnPlot(WPARAM wP, LPARAM lP)
{
   // get data chosen
   CWaitCursor wc;
   PlotDataToChart();
   return 1;
}

void CPlot2DFocalPlanes::OnPlotData()
{
   CWaitCursor wc;
   PlotDataToChart();
}

void CPlot2DFocalPlanes::OnPlotReset()
{
   // if any data is there and selected, just re-plot it.
   CWaitCursor wc;
   PlotDataToChart();
}

void CPlot2DFocalPlanes::OnPlotProp()
{
   CPlotProperties dlg;

   for (int k=0; k<MAX_SERIES_NO; k++)
   {
      dlg.m_nLineWidth[k]    = m_nLineWidth[k];
      dlg.m_nPenStyle[k]     = m_nPenStyle[k];
      dlg.m_nPointsType[k]   = m_nPointsType[k];
      dlg.m_nPointsWidth[k]  = m_nPointsWidth[k];
      dlg.m_nPointsHeight[k] = m_nPointsHeight[k];
   }

   // do the dialog
   if (dlg.DoModal() == IDOK) // retrieve the altered settings
   {
      CWaitCursor wc;
      for (int k=0; k<MAX_SERIES_NO; k++)
      {
         m_nLineWidth[k]    = dlg.m_nLineWidth[k];
         m_nPenStyle[k]     = dlg.m_nPenStyle[k];
         m_nPointsType[k]   = dlg.m_nPointsType[k];
         m_nPointsWidth[k]  = dlg.m_nPointsWidth[k];
         m_nPointsHeight[k] = dlg.m_nPointsHeight[k];
      }
      OnPlotReset();
   }
}

void CPlot2DFocalPlanes::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
   // m_PlotChart.OnBeginPrinting(pDC, pInfo);
   CView::OnBeginPrinting(pDC, pInfo);
}

void CPlot2DFocalPlanes::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
   // m_PlotChart.OnEndPrinting(pDC, pInfo);
   CView::OnEndPrinting(pDC, pInfo);
}

BOOL CPlot2DFocalPlanes::OnPreparePrinting(CPrintInfo* pInfo)
{
   return DoPreparePrinting(pInfo);
}

void CPlot2DFocalPlanes::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
   // m_PlotChart.OnPrint(pDC, pInfo);
   CView::OnPrint(pDC, pInfo);
}

void CPlot2DFocalPlanes::OnFilePrint()
{
   TChartString strTitle = _T("Graph");
   m_PlotChart.Print(strTitle,NULL);
}

void CPlot2DFocalPlanes::OnFilePrintPreview()
{
   AFXPrintPreview(this);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer (Senior)
Italy Italy
Senior Software Developer in C/C++ and Oracle.
Ex-physicist holding a Ph.D. on x-ray lasers.

Comments and Discussions