19,468
社区成员
发帖
与我相关
我的任务
分享
BOOL CDraw3DcubeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
int iEdgeLength = 100;
//set eight corner coordinate
CCubeEx::RECTCOOR rcDTL(0,0,0); //下方左上
CCubeEx::RECTCOOR rcDTR(iEdgeLength,0,0);
CCubeEx::RECTCOOR rcDBL(0,iEdgeLength,0);
CCubeEx::RECTCOOR rcDBR(iEdgeLength,iEdgeLength,0);
CCubeEx::RECTCOOR rcUTL(0,0,iEdgeLength); //下方左上
CCubeEx::RECTCOOR rcUTR(iEdgeLength,0,iEdgeLength);
CCubeEx::RECTCOOR rcUBL(0,iEdgeLength,iEdgeLength);
CCubeEx::RECTCOOR rcUBR(iEdgeLength,iEdgeLength,iEdgeLength);
//down side fore edges
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcDTL,rcDTR ) ); //back
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcDTR,rcDBR ) ); //right
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcDBL,rcDBR ) ); //front
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcDTL,rcDBL ) ); //left
//mid side fore edges
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcDTL,rcUTL ) );
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcDTR,rcUTR ) );
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcDBL,rcUBL ) );
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcDBR,rcUBR ) );
//up side fore edges
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcUTL,rcUTR ) );
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcUTR,rcUBR ) );
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcUBL,rcUBR ) );
m_cube.lineVtOrg.push_back( CCubeEx::LINESEG( rcUTL,rcUBL ) );
m_cube.CalcRotaCoor();
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDraw3DcubeDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CClientDC dc(this);
CRect rt;
GetClientRect(rt);
dc.FillRect(rt,&CBrush(GetSysColor(COLOR_3DFACE)));
m_cube.DrawLineSegs(dc);
CDialog::OnPaint();
}
}
void CDraw3DcubeDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bLBtnDown = 1;
m_ptLBtnDown = point;
m_ptCubeMoveOrg = CPoint(m_cube.m_ix,m_cube.m_iy);
CDialog::OnLButtonDown(nFlags, point);
}
void CDraw3DcubeDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bLBtnDown = 0;
CDialog::OnLButtonUp(nFlags, point);
}
void CDraw3DcubeDlg::OnMouseMove(UINT nFlags, CPoint point)
{
static CPoint ptOld;
if (ptOld == point) return;
ptOld = point;
const double PI = 3.141592654;
if ((nFlags & MK_LBUTTON) && m_bLBtnDown) //左键
{
int iDeltaX = point.x - m_ptLBtnDown.x;
int iDeltaY = point.y - m_ptLBtnDown.y;
m_cube.m_ix = m_ptCubeMoveOrg.x + iDeltaX;
m_cube.m_iy = m_ptCubeMoveOrg.y + iDeltaY;
m_cube.CalcRotaCoor();
SendMessage(WM_PAINT,0,0);
}
if ((nFlags & MK_RBUTTON) && m_bRBtnDown) //右键
{
int iDeltaX = point.x - m_ptRBtnDown.x;
int iDeltaY = point.y - m_ptRBtnDown.y;
m_cube.m_dThet = m_dCubeThetOrg - PI/180*iDeltaY;
m_cube.m_dPhi = m_dCubePhiOrg - PI/180*iDeltaX;
m_cube.CalcRotaCoor();
SendMessage(WM_PAINT,0,0);
CClientDC dc(this);
dc.FillRect(CRect(10,10,100,30),&CBrush(GetSysColor(COLOR_3DFACE)));
CString str;
str.Format("m_dPhi = %lf",m_cube.m_dPhi/PI*180);
dc.TextOut(10,10,str);
str.Format("m_dThet = %lf",m_cube.m_dThet/PI*180);
dc.TextOut(10,30,str);
//TRACE("new phi = %f\n",m_cube.m_dPhi);
}
CDialog::OnMouseMove(nFlags, point);
}
void CDraw3DcubeDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bRBtnDown = 1;
m_ptRBtnDown = point;
m_dCubeThetOrg = m_cube.m_dThet;
m_dCubePhiOrg = m_cube.m_dPhi;
//TRACE("phi = %f\n",m_dCubePhiOrg);
CDialog::OnRButtonDown(nFlags, point);
}
void CDraw3DcubeDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
m_bRBtnDown = 0;
CDialog::OnRButtonUp(nFlags, point);
}
// CubeEx.h: interface for the CCubeEx class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CUBEEX_H__1D73BB62_BF3A_4BB8_ACF8_864D1950538F__INCLUDED_)
#define AFX_CUBEEX_H__1D73BB62_BF3A_4BB8_ACF8_864D1950538F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <vector>
using std::vector;
/*
关于数学变量与模型的描述
|Z
|
|
|
|
|
|
|90度
|___________________X
/120度
/
/
/
/
/
Y/
θ,Thet 旋转的时候,与Z轴的夹角
φ,Phi 旋转的时候,与Y轴的夹角
*/
class CCubeEx
{
public:
typedef struct __RECTCOOR{
double x;
double y;
double z;
__RECTCOOR():x(0),y(0),z(0){} //无参构造
__RECTCOOR(double dx,double dy,double dz):x(dx),y(dy),z(dz){} //有参构造
//重载 + 号运算,方便移位代码
__RECTCOOR operator+(const __RECTCOOR& rc){
return __RECTCOOR(rc.x+x,rc.y+y,rc.z+z);
}
}RECTCOOR,*PRECTCOOR; //代表3D直角坐标点
typedef struct __LINESEG{
RECTCOOR ptStart;
RECTCOOR ptEnd;
__LINESEG():ptStart(0,0,0),ptEnd(0,0,0){} //无参构造
__LINESEG(RECTCOOR pt1,RECTCOOR pt2):ptStart(pt1),ptEnd(pt2){} //有参构造
}LINESEG,*PLINESEG; //代表线段
public:
double m_dThet; //绕Y轴转的角度
double m_dPhi; //转Z轴转的角度
vector<LINESEG> lineVtOrg;
vector<LINESEG> lineVtRota;
int m_ix,m_iy; //显示时,相对于屏幕的偏移
public:
BOOL CalcRotaZCoor(vector<LINESEG>& lvSrc,vector<LINESEG>& lvDst); //计算绕Z轴转后新坐标
BOOL CalcRotaXCoor(vector<LINESEG>& lvSrc,vector<LINESEG>& lvDst); //计算绕Y轴转后新坐标
BOOL CalcRotaCoor();
POINT RectCoorTo2D135Deg(RECTCOOR& rc);
POINT RectCoorTo2D120Deg(RECTCOOR& rc);
POINT RectCoorTo2DThree120Deg(RECTCOOR& rc);
POINT RectCoorTo2DDisplay(RECTCOOR& rc);
BOOL DrawLineSegs(CDC& dc);
public:
CCubeEx();
virtual ~CCubeEx();
};
#endif // !defined(AFX_CUBEEX_H__1D73BB62_BF3A_4BB8_ACF8_864D1950538F__INCLUDED_)
// CubeEx.cpp: implementation of the CCubeEx class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "draw3dcube.h"
#include "CubeEx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include <cmath>
CCubeEx::CCubeEx():m_dThet(0),m_dPhi(0),m_ix(200),m_iy(200)
{
}
CCubeEx::~CCubeEx()
{
}
BOOL CCubeEx::CalcRotaZCoor(vector<LINESEG>& lvSrc,vector<LINESEG>& lvDst)
{
vector<LINESEG> lvBuf;
lvBuf = lvSrc;
int iSize = lvSrc.size();
double dCosPhi;
double dSinPhi;
for (int i=0;i<iSize;i++)
{
//直角坐标旋转公式
dCosPhi = cos(m_dPhi);
dSinPhi = sin(m_dPhi);
lvBuf[i].ptStart.x = lvSrc[i].ptStart.x*dCosPhi - lvSrc[i].ptStart.y*dSinPhi;
lvBuf[i].ptStart.y = lvSrc[i].ptStart.y*dCosPhi + lvSrc[i].ptStart.x*dSinPhi;
lvBuf[i].ptEnd.x = lvSrc[i].ptEnd.x*dCosPhi - lvSrc[i].ptEnd.y*dSinPhi;
lvBuf[i].ptEnd.y = lvSrc[i].ptEnd.y*dCosPhi + lvSrc[i].ptEnd.x*dSinPhi;
}
lvDst = lvBuf;
return 1;
}
BOOL CCubeEx::CalcRotaXCoor(vector<LINESEG>& lvSrc,vector<LINESEG>& lvDst)
{
vector<LINESEG> lvBuf;
lvBuf = lvSrc;
int iSize = lvSrc.size();
double dCosThet;
double dSinThet;
for (int i=0;i<iSize;i++)
{
//直角坐标旋转公式
dCosThet = cos(m_dThet);
dSinThet = sin(m_dThet);
lvBuf[i].ptStart.y = lvSrc[i].ptStart.y*dCosThet - lvSrc[i].ptStart.z*dSinThet;
lvBuf[i].ptStart.z = lvSrc[i].ptStart.z*dCosThet + lvSrc[i].ptStart.y*dSinThet;
lvBuf[i].ptEnd.y = lvSrc[i].ptEnd.y*dCosThet - lvSrc[i].ptEnd.z*dSinThet;
lvBuf[i].ptEnd.z = lvSrc[i].ptEnd.z*dCosThet + lvSrc[i].ptEnd.y*dSinThet;
}
lvDst = lvBuf;
return 1;
}
BOOL CCubeEx::CalcRotaCoor()
{
lineVtRota = lineVtOrg;
CalcRotaZCoor(lineVtOrg,lineVtRota);
CalcRotaXCoor(lineVtRota,lineVtRota);
return 1;
}
POINT CCubeEx::RectCoorTo2D135Deg(RECTCOOR& rc)
{
POINT pt2D;
pt2D.x = rc.x - rc.y*sqrt(0.5); //3D coor to display 2D coor
pt2D.y = - rc.z + rc.y*sqrt(0.5);
return pt2D;
}
POINT CCubeEx::RectCoorTo2D120Deg(RECTCOOR& rc)
{
POINT pt2D;
pt2D.x = rc.x - rc.y*sin(P_30);
pt2D.y = rc.y*cos(P_30) - rc.z;
return pt2D;
}
POINT CCubeEx::RectCoorTo2DThree120Deg(RECTCOOR &rc)
{
POINT pt2D;
pt2D.x = rc.x*cos(P_30) - rc.y*cos(P_30);
pt2D.y = rc.x*sin(P_30) + rc.y*sin(P_30) - rc.z;
return pt2D;
}
POINT CCubeEx::RectCoorTo2DDisplay(RECTCOOR& rc)
{
//return RectCoorTo2D135Deg(rc);
return RectCoorTo2D120Deg(rc);
//return RectCoorTo2DThree120Deg(rc);
}
BOOL CCubeEx::DrawLineSegs(CDC& dc)
{
int i;
int iLen = lineVtRota.size();
POINT pt11 = RectCoorTo2DDisplay(lineVtRota[0].ptStart);
POINT pt22 = RectCoorTo2DDisplay(lineVtRota[0].ptEnd);
pt11.x += m_ix; pt22.x += m_ix;
pt11.y += m_iy; pt22.y += m_iy;
dc.TextOut(pt11.x,pt11.y,"(0,0,0)");
dc.TextOut(pt22.x,pt22.y,"X");
CPen penGreen(PS_SOLID,1,RGB(0,255,0));
CPen* pOldPen = dc.SelectObject(&penGreen);
dc.MoveTo(pt11);
dc.LineTo(pt22);
CPen penRed(PS_SOLID,1,RGB(255,0,0));
dc.SelectObject(&penRed);
for (i=1;i<4;i++)
{
POINT pt1 = RectCoorTo2DDisplay(lineVtRota[i].ptStart);
POINT pt2 = RectCoorTo2DDisplay(lineVtRota[i].ptEnd);
pt1.x += m_ix; pt2.x += m_ix;
pt1.y += m_iy; pt2.y += m_iy;
dc.MoveTo(pt1);
dc.LineTo(pt2);
if (3 == i)
{
dc.TextOut(pt2.x,pt2.y,"Y");
}
}
CPen penBlue(PS_SOLID,1,RGB(0,0,255));
dc.SelectObject(penBlue);
POINT pt41 = RectCoorTo2DDisplay(lineVtRota[i].ptStart);
POINT pt42 = RectCoorTo2DDisplay(lineVtRota[i].ptEnd);
pt41.x += m_ix; pt42.x += m_ix;
pt41.y += m_iy; pt42.y += m_iy;
dc.MoveTo(pt41);
dc.LineTo(pt42);
dc.TextOut(pt42.x,pt42.y,"Z");
i++;
CPen penYellow(PS_SOLID,1,RGB(0,255,255));
dc.SelectObject(&penYellow);
for (;i<8;i++)
{
POINT pt1 = RectCoorTo2DDisplay(lineVtRota[i].ptStart);
POINT pt2 = RectCoorTo2DDisplay(lineVtRota[i].ptEnd);
pt1.x += m_ix; pt2.x += m_ix;
pt1.y += m_iy; pt2.y += m_iy;
dc.MoveTo(pt1);
dc.LineTo(pt2);
}
CPen penPurple(PS_SOLID,1,RGB(255,0,255));
dc.SelectObject(&penPurple);
for (i=8;i<iLen;i++)
{
POINT pt1 = RectCoorTo2DDisplay(lineVtRota[i].ptStart);
POINT pt2 = RectCoorTo2DDisplay(lineVtRota[i].ptEnd);
pt1.x += m_ix; pt2.x += m_ix;
pt1.y += m_iy; pt2.y += m_iy;
dc.MoveTo(pt1);
dc.LineTo(pt2);
}
dc.SelectObject(pOldPen);
return 1;
}