// 02View.h: CMy02View 类的接口
//
#pragma once
#include"CFace.h"
#include"cp3.h"
#include"CTransform.h"
class CMy02View : public CView
{
protected: // 仅从序列化创建
CMy02View() noexcept;
DECLARE_DYNCREATE(CMy02View)
// 特性
public:
CMy02Doc* GetDocument() const;
// 操作
public:
CRect rect;
cp3 V[8];
CFace F[6];
CTransform T;
void SetPoint();
void SetFace();
void DrawObject(CDC* pDC);
cp2 Project(cp3);
// 重写
public:
virtual void OnDraw(CDC* pDC); // 重写以绘制该视图
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
// 实现
public:
virtual ~CMy02View();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// 生成的消息映射函数
protected:
afx_msg void OnFilePrintPreview();
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
};
#ifndef _DEBUG // 02View.cpp 中的调试版本
inline CMy02Doc* CMy02View::GetDocument() const
{ return reinterpret_cast<CMy02Doc*>(m_pDocument); }
#endif
// 02View.cpp: CMy02View 类的实现
//
#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "02.h"
#endif
#include "02Doc.h"
#include "02View.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMy02View
IMPLEMENT_DYNCREATE(CMy02View, CView)
BEGIN_MESSAGE_MAP(CMy02View, CView)
// 标准打印命令
ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CMy02View::OnFilePrintPreview)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
ON_WM_KEYDOWN()
END_MESSAGE_MAP()
// CMy02View 构造/析构
CMy02View::CMy02View() noexcept
{
// TODO: 在此处添加构造代码
SetPoint();
SetFace();
T.SetMat(V, 8);
}
CMy02View::~CMy02View()
{
}
BOOL CMy02View::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改
// CREATESTRUCT cs 来修改窗口类或样式
return CView::PreCreateWindow(cs);
}
// CMy02View 绘图
void CMy02View::OnDraw(CDC* pDC)
{
CMy02Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
GetClientRect(&rect);//获得客户区矩形
pDC->SetMapMode(MM_ANISOTROPIC);//设置映射模式
pDC->SetWindowExt(rect.Width(), rect.Height());//设置窗口
pDC->SetViewportExt(rect.Width(), -rect.Height());//设置视区;
pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);//
rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);//客户区矩形矫正
DrawObject(pDC);
// TODO: 在此处为本机数据添加绘制代码
}
// CMy02View 打印
void CMy02View::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
AFXPrintPreview(this);
#endif
}
BOOL CMy02View::OnPreparePrinting(CPrintInfo* pInfo)
{
// 默认准备
return DoPreparePrinting(pInfo);
}
void CMy02View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加额外的打印前进行的初始化过程
}
void CMy02View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加打印后进行的清理过程
}
void CMy02View::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
ClientToScreen(&point);
OnContextMenu(this, point);
}
void CMy02View::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
// CMy02View 诊断
#ifdef _DEBUG
void CMy02View::AssertValid() const
{
CView::AssertValid();
}
void CMy02View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMy02Doc* CMy02View::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy02Doc)));
return (CMy02Doc*)m_pDocument;
}
#endif //_DEBUG
// CMy02View 消息处理程序
void CMy02View::SetPoint()
{
int a = 100;
V[0].x = 0, V[0].y = 0, V[0].z = 0;
V[1].x = a, V[1].y = 0, V[1].z = 0;
V[2].x = a, V[2].y = a, V[2].z = 0;
V[3].x = 0, V[3].y = a, V[3].z = 0;
V[4].x = 0, V[4].y = 0, V[4].z = a;
V[5].x = a, V[5].y = 0, V[5].z = a;
V[6].x = a, V[6].y = a, V[6].z = a;
V[7].x = 0, V[7].y = a, V[7].z = a;
}
void CMy02View::SetFace()
{
F[0].SetNum(4); F[0].VI[0] = 4; F[0].VI[1] = 5; F[0].VI[2] = 6; F[0].VI[3] = 7;//前面点的序号
F[1].SetNum(4); F[1].VI[0] = 0; F[1].VI[1] = 3; F[1].VI[2] = 2; F[1].VI[3] = 1;//后
F[2].SetNum(4); F[2].VI[0] = 0; F[2].VI[1] = 4; F[2].VI[2] = 7; F[2].VI[3] = 3;//左
F[3].SetNum(4); F[3].VI[0] = 1; F[3].VI[1] = 2; F[3].VI[2] = 6; F[3].VI[3] = 5;//右
F[4].SetNum(4); F[4].VI[0] = 0; F[4].VI[1] = 1; F[4].VI[2] = 5; F[4].VI[3] = 4;//下
F[5].SetNum(4); F[5].VI[0] = 2; F[5].VI[1] = 3; F[5].VI[2] = 7; F[5].VI[3] = 6;//上
}
void CMy02View::DrawObject(CDC* pDC)
{
pDC->MoveTo(0, 0);
pDC->LineTo(rect.Width() / 2, 0);
pDC->MoveTo(0, 0);
pDC->LineTo(0, rect.Height() / 2);
cp3 Z;
cp2 X;
Z.x = 0;
Z.y = 0;
Z.z = rect.Width() / 2;
X = Project(Z);
pDC->MoveTo(0, 0);
pDC->LineTo(X.x, X.y);
int i, j;
cp2 SP,pt;
for(i=0;i<6;i++)//面循环
for (j = 0;j < 4;j++)
{
SP=Project(V[F[i].VI[j]]);
if (j == 0)
{ //移动到起到
pDC->MoveTo(SP.x, SP.y);//当前点
pt = SP;
}
else
//画到下一个点
pDC->LineTo(SP.x, SP.y);
}
pDC->LineTo(pt.x, pt.y);
}
cp2 CMy02View::Project(cp3 P)
{
//正交投影
cp2 ScreenP;
/*ScreenP.x = P.x;
ScreenP.y = P.y;*/
//斜投影
/*ScreenP.x = P.x-P.z*0.707;
ScreenP.y = P.y - P.z * 0.707;*/
//斜二测投影
//ScreenP.x = P.x - P.z * 0.3536;
//ScreenP.y = P.y - P.z * 0.3536;
ScreenP.x = P.x - P.z * sqrt(2);
ScreenP.y = P.y - P.z * sqrt(2);
//透视投影
return ScreenP;
}
void CMy02View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch (nChar)
{
case'W'://向上平移
case VK_UP:
T.Translate(0,10,0);break;
case'S'://向下平移
case VK_DOWN:
T.Translate(0, -10,0);break;
case'N'://向左平移
case VK_LEFT:
T.Translate(-10, 0,0);break;
case'D'://向右平移
case VK_RIGHT:
T.Translate(10, 0,0);break;
case'H'://向前平移
T.Translate(0, 0, 10);break;
case'V'://向后平移
T.Translate(0, 0, -10);break;
case'A'://等比例放大
case VK_F1:
T.Scale(1.5, 1.5,1.5);break;
case'B'://等比例缩小
case VK_F2:
T.Scale(0.5, 0.5,0.5);break;
case'E'://X复合旋转
case VK_F3:
T.RotateX(30);break;
case'F'://Y复合旋转
case VK_F4:
T.RotateY(-30);break;
case'1':
T.RotateZ(30);break;
case'G'://关于xoy轴反射变换
case VK_F5:
T.ReflectXOY();break;
case'T'://关于yoz轴反射变换
case VK_F6:
T.ReflectYOZ();break;
case'I'://关于zox反射变换
case VK_F7:
T.ReflectZOX();break;
case'J'://X轴正向错切变换
case VK_F8:
T.ShearX(1, 1);break;
case'K'://Y轴正向错切变换
case VK_F9:
T.ShearY(1, 1);break;
case'M'://Z轴正向错切变换
case VK_F10:
T.ShearZ(1, 1);break;
case'Q'://Y轴负向错切变换
case VK_F11:
SetPoint();
}
Invalidate();
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
#pragma once
class CFace
{
public:
CFace(void);
~CFace(void);
void SetNum(int vn);
public:
//顶点数量
int VNum;
//保存若干个整形序号,动态数组
int *VI;
};
#include "pch.h"
#include "CFace.h"
CFace::CFace()
{
//VI = new int(VNum);//定义整型变量,变量的值
VI = NULL;
}
CFace::~CFace()
{
}
void CFace::SetNum(int vn)
{
VI = new int[vn];//定义整形数组,括号里数组的元素个数
VNum = vn;
}
#pragma once
class cp2
{
public:
cp2(void);
~cp2(void);
cp2(double x, double y);//带参构造
public:
double x;
double y;
double w;
};
#include "pch.h"
#include "cp2.h"
cp2::cp2()
{
w = 1;
}
cp2::~cp2()
{
}
cp2::cp2(double x, double y)
{
this->x = x;
this->y=y;
w = 1;
}
#pragma once
#include"cp2.h"
class cp3:
public cp2
{
public:
cp3(void);
~cp3(void);
cp3(double x, double y,double z);//带参构造
public:
/*double x;
double y;*/
double z;
};
#include "pch.h"
#include "cp3.h"
cp3::cp3()
{
}
cp3::~cp3()
{
}
cp3::cp3(double x, double y, double z) :cp2(x, y)
{
this->z = z;
}
#pragma once
#include"cp3.h"
class CTransform
{
public:
CTransform();
~CTransform();
void SetMat(cp3*, int n);
void Identity();//初始化二维数组
void Translate(double dx, double dy, double dz);//平移变换矩阵
void Scale(double, double, double);//比例变换矩阵
void RotateX(double);//x轴旋转变换
void RotateY(double);//y轴旋转变换
void RotateZ(double);
void ReflectX();//x轴反射变换矩阵
void ReflectY();
void ReflectZ();
void ReflectXOY();//XOY面反射变换矩阵
void ReflectYOZ();
void ReflectZOX();
void ShearX(double,double);//x方向错切变换矩阵
void ShearY(double, double);
void ShearZ(double, double);
void MulMat();//矩阵相乘
public:
double T[4][4];
cp3 * pOld;
int PNum;
};
#include "pch.h"
#include "CTransform.h"
#include"cp3.h"
#define PI 3.1415926
CTransform::CTransform(void) {
}
CTransform::~CTransform(void) {
}
void CTransform::SetMat(cp3* p, int n)
{
pOld = p;
PNum = n;
}
void CTransform::Identity()
{
/*T[0][0] = 1.0;T[0][1] = 0.0;T[0][2] = 0.0;T[0][3] = 0.0;
T[1][0] = 0.0;T[1][1] = 1.0;T[1][2] = 0.0;T[1][3] = 0.0;
T[2][0] = 0.0;T[2][1] = 0.0;T[2][2] = 1.0;T[2][3] = 0.0;
T[3][0] = 0.0;T[3][1] = 0.0;T[3][2] = 0.0;T[2][3] = 1.0;*/
T[0][0] = 1; T[0][1] = 0; T[0][2] = 0; T[0][3] = 0;
T[1][0] = 0; T[1][1] = 1; T[1][2] = 0; T[1][3] = 0;
T[2][0] = 0; T[2][1] = 0; T[2][2] = 1; T[2][3] = 0;
T[3][0] = 0; T[3][1] = 0; T[3][2] = 0; T[3][3] = 1;
}
void CTransform::MulMat()
{
int i;
cp3* pNew = new cp3[PNum];
for (i = 0;i < PNum;i++)
{
pNew[i].x = pOld[i].x;
pNew[i].y = pOld[i].y;
pNew[i].z = pOld[i].z;
pNew[i].w = pOld[i].w;
}
for (i = 0;i < PNum;i++)
{
/*pOld[i].x = pNew[i].x * T[0][0]
+ pNew[i].y * T[1][0]
+ pNew[i].z * T[2][0]
+ pNew[i].w * T[3][0];
pOld[i].y = pNew[i].x * T[0][1]
+ pNew[i].y * T[1][1]
+ pNew[i].z * T[2][1]
+ pNew[i].w * T[3][1];
pOld[i].z = pNew[i].x * T[0][2]
+ pNew[i].y * T[1][2]
+ pNew[i].z * T[2][2]
+ pNew[i].w * T[3][2];
pOld[i].w = pNew[i].x * T[0][3]
+ pNew[i].y * T[1][3]
+ pNew[i].z * T[2][3]
+ pNew[i].w * T[3][3];*/
pOld[i].x = pNew[i].x * T[0][0] + pNew[i].y * T[1][0] + pNew[i].z * T[2][0] + pNew[i].w * T[3][0];
pOld[i].y = pNew[i].x * T[0][1] + pNew[i].y * T[1][1] + pNew[i].z * T[2][1] + pNew[i].w * T[3][1];
pOld[i].z = pNew[i].x * T[0][2] + pNew[i].y * T[1][2] + pNew[i].z * T[2][2] + pNew[i].w * T[3][2];
pOld[i].w = pNew[i].x * T[0][3] + pNew[i].y * T[1][3] + pNew[i].z * T[2][3] + pNew[i].w * T[3][3];
}
delete[]pNew;
}
void CTransform::Translate(double dx, double dy, double dz)//平移
{
Identity();
T[3][0] = dx; T[3][1] = dy; T[3][2] = dz;
MulMat();
}
void CTransform::Scale(double sx, double sy,double sz)
{
Identity();
T[0][0] = sx;T[1][1] = sy;T[2][2] = sz;
MulMat();
}
void CTransform::RotateX(double beta)
{
Identity();
double rad = beta * PI / 180;
T[1][1] = cos(rad);T[1][2] = sin(rad);
T[2][1] = -sin(rad);T[2][2] = cos(rad);
MulMat();
}
void CTransform::RotateY(double beta)
{
Identity();
double rad = beta * PI / 180;
T[0][0] = cos(rad);T[0][2] = -sin(rad);
T[2][0] = sin(rad);T[2][2] = cos(rad);
MulMat();
}
void CTransform::RotateZ(double beta)
{
Identity();
double rad = beta * PI / 180;
T[0][0] = cos(rad);T[0][1] = sin(rad);
T[1][0] = -sin(rad);T[1][1] = cos(rad);
MulMat();
}
void CTransform::ReflectX()
{
Identity();
T[1][1] = -1;T[2][2] = -1;
MulMat();
}
void CTransform::ReflectY()
{
Identity();
T[0][0] = -1;T[2][2] = -1;
MulMat();
}
void CTransform::ReflectZ()
{
Identity();
T[0][0] = -1;T[1][1] = -1;
MulMat();
}
void CTransform::ReflectXOY()
{
Identity();
T[2][2] = -1;
MulMat();
}
void CTransform::ReflectYOZ()
{
Identity();
T[0][0] = -1;
MulMat();
}
void CTransform::ReflectZOX()
{
Identity();
T[1][1] = -1;
MulMat();
}
void CTransform::ShearX(double d, double g)
{
Identity();
T[1][0] = d;T[2][0] = g;
MulMat();
}
void CTransform::ShearY(double b, double h)
{
Identity();
T[0][1] = b;T[2][1] = h;
MulMat();
}
void CTransform::ShearZ(double c, double f)
{
Identity();
T[0][1] = c;T[1][0] = f;
MulMat();
}