// ThreeDChartRotationDlg.cpp : implementation file
//
#include "stdafx.h"
#include "resource.h"
#include "ThreeDChartRotationDlg.h"
#include <math.h>
#include <vector>
#include <assert.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//
// Constructor
//
CThreeDChartRotationDlg::CThreeDChartRotationDlg(CWnd* pParent /*=NULL*/)
: CDialog(IDD_THREEDCHARTROTATION, pParent)
{
// 3D view angles
m_elevationAngle = 30;
m_rotationAngle = 45;
// Keep track of mouse drag
m_isDragging = false;
m_lastMouseX = -1;
m_lastMouseY = -1;
}
//
// Destructor
//
CThreeDChartRotationDlg::~CThreeDChartRotationDlg()
{
delete m_ChartViewer.getChart();
}
void CThreeDChartRotationDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_ChartViewer, m_ChartViewer);
DDX_Control(pDX, IDC_CHECK1, m_DrawFrameOnRotate);
}
BEGIN_MESSAGE_MAP(CThreeDChartRotationDlg, CDialog)
ON_CONTROL(CVN_ViewPortChanged, IDC_ChartViewer, OnViewPortChanged)
ON_CONTROL(CVN_MouseMoveChart, IDC_ChartViewer, OnMouseMoveChart)
ON_CONTROL(BN_CLICKED, IDC_ChartViewer, OnMouseUpChart)
END_MESSAGE_MAP()
//
// Initialization
//
BOOL CThreeDChartRotationDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// To handle mouse drags, it is necessary to enable mouse capture. By default, MFC does not
// enable mouse capture. In ChartDirector, we can use MouseUsageDefaultCapture to enable it.
m_ChartViewer.setMouseUsage(Chart::MouseUsageDefaultCapture);
// Update the viewport to display the chart
m_ChartViewer.updateViewPort(true, false);
// In this example, the default is to draw wire frame on rotate
m_DrawFrameOnRotate.SetCheck(1);
return TRUE;
}
//
// View port changed event
//
void CThreeDChartRotationDlg::OnViewPortChanged()
{
// Update the chart if necessary
if (m_ChartViewer.needUpdateChart())
drawChart(&m_ChartViewer);
}
//
// Draw the chart and display it in the given viewer
//
void CThreeDChartRotationDlg::drawChart(CChartViewer *viewer)
{
std::vector<double> dataX(100);
std::vector<double> dataY(100);
std::vector<double> dataZ(100);
for (int i = 0; i < 100; ++i)
{
double angle = i * 10 * 3.1416 / 180;
dataX[i] = 8 * sin(angle);
dataY[i] = 8 * cos(angle);
dataZ[i] = 0.08 * i;
}
// Create a SurfaceChart object of size 720 x 600 pixels
ThreeDScatterChart*c = new ThreeDScatterChart(720, 600);
// Set the center of the plot region at (330, 290), and set width x depth x height to
// 360 x 360 x 270 pixels
c->setPlotRegion(330, 290, 360, 360, 270);
c->addScatterGroup(DoubleArray(dataX.data(), dataX.size()),
DoubleArray(dataY.data(), dataY.size()), DoubleArray(dataZ.data(), dataZ.size()),
"", Chart::SquareShape, 1, Chart::Transparent);
// Set the view angles
c->setViewAngle(m_elevationAngle, m_rotationAngle);
// Set the x, y and z axis titles using 10 points Arial Bold font
c->xAxis()->setTitle("X", "Arial Bold", 15);
c->yAxis()->setTitle("Y", "Arial Bold", 15);
// Set axis label font
c->xAxis()->setLabelStyle("Arial", 10);
c->yAxis()->setLabelStyle("Arial", 10);
c->zAxis()->setLabelStyle("Arial", 10);
c->colorAxis()->setLabelStyle("Arial", 10);
c->makeChart();
double x0 = c->getXCoor(dataX[0], dataY[0], dataZ[0]);
double y0 = c->getYCoor(dataX[0], dataY[0], dataZ[0]);
for (int i = 1; i < dataX.size(); ++i)
{
double x1 = c->getXCoor(dataX[i], dataY[i], dataZ[i]);
double y1 = c->getYCoor(dataX[i], dataY[i], dataZ[i]);
c->addLine(x0, y0, x1, y1, 0x66aaee);
x0 = x1;
y0 = y1;
}
// Output the chart
delete viewer->getChart();
viewer->setChart(c);
}
void CThreeDChartRotationDlg::drawChart2(CChartViewer* viewer)
{
std::vector<double> dataX(100);
std::vector<double> dataY(100);
std::vector<double> dataZ(100);
std::vector<double> arrowX(100);
std::vector<double> arrowY(100);
std::vector<double> arrowZ(100);
for (int i = 0; i < 100; ++i)
{
double angle = i * 10 * 3.1416 / 180;
dataX[i] = 8 * sin(angle);
dataY[i] = 8 * cos(angle);
dataZ[i] = 0.08 * i;
arrowX[i] = 2 * cos(angle);
arrowY[i] = 2 * sin(angle);
arrowZ[i] = 0; // 0.6 * sin(angle + i * 0.2);
}
// Create a SurfaceChart object of size 720 x 600 pixels
ThreeDScatterChart* c = new ThreeDScatterChart(720, 600);
// Set the center of the plot region at (330, 290), and set width x depth x height to
// 360 x 360 x 270 pixels
c->setPlotRegion(330, 290, 360, 360, 270);
c->addScatterGroup(DoubleArray(dataX.data(), dataX.size()),
DoubleArray(dataY.data(), dataY.size()), DoubleArray(dataZ.data(), dataZ.size()),
"", Chart::SquareShape, 1, Chart::Transparent);
// Set the view angles
c->setViewAngle(m_elevationAngle, m_rotationAngle);
// Set the x, y and z axis titles using 10 points Arial Bold font
c->xAxis()->setTitle("X", "Arial Bold", 15);
c->yAxis()->setTitle("Y", "Arial Bold", 15);
// Set axis label font
c->xAxis()->setLabelStyle("Arial", 10);
c->yAxis()->setLabelStyle("Arial", 10);
c->zAxis()->setLabelStyle("Arial", 10);
c->colorAxis()->setLabelStyle("Arial", 10);
c->makeChart();
for (int i = 1; i < dataX.size(); ++i)
{
double x0 = c->getXCoor(dataX[i], dataY[i], dataZ[i]);
double y0 = c->getYCoor(dataX[i], dataY[i], dataZ[i]);
double x1 = c->getXCoor(dataX[i] + arrowX[i], dataY[i] + arrowY[i], dataZ[i] + arrowZ[i]);
double y1 = c->getYCoor(dataX[i] + arrowX[i], dataY[i] + arrowY[i], dataZ[i] + arrowZ[i]);
c->addLine(x0, y0, x1, y1, 0x66aaee);
double dx = x1 - x0;
double dy = y1 - y0;
double len = (std::max)(1.0, sqrt(dx * dx + dy * dy));
dx *= 10 / len;
dy *= 10 / len;
c->addLine(x1, y1, x1 - dx + dy / 4, y1 - dy - dx / 4, 0x66aaee);
c->addLine(x1, y1, x1 - dx - dy / 4, y1 - dy + dx / 4, 0x66aaee);
}
// Output the chart
delete viewer->getChart();
viewer->setChart(c);
}
//
// Rotate surface chart when mouse is moving over plotarea
//
void CThreeDChartRotationDlg::OnMouseMoveChart()
{
int mouseX = m_ChartViewer.getChartMouseX();
int mouseY = m_ChartViewer.getChartMouseY();
// Drag occurs if mouse button is down and the mouse is captured by the m_ChartViewer
if (((GetKeyState(VK_LBUTTON) & 0x100) != 0) && (GetCapture() == &m_ChartViewer))
{
if (m_isDragging)
{
// The chart is configured to rotate by 90 degrees when the mouse moves from
// left to right, which is the plot region width (360 pixels). Similarly, the
// elevation changes by 90 degrees when the mouse moves from top to buttom,
// which is the plot region height (270 pixels).
m_rotationAngle += (m_lastMouseX - mouseX) * 90.0 / 360;
m_elevationAngle += (mouseY - m_lastMouseY) * 90.0 / 270;
m_ChartViewer.updateViewPort(true, false);
}
// Keep track of the last mouse position
m_lastMouseX = mouseX;
m_lastMouseY = mouseY;
m_isDragging = true;
}
}
//
// Stops dragging on mouse up
//
void CThreeDChartRotationDlg::OnMouseUpChart()
{
m_isDragging = false;
m_ChartViewer.updateViewPort(true, false);
}
|