Create Hine-lineRemoval
This commit is contained in:
1 parent
ac41fb2b3b
commit
40f8b7827d
51 files changed
+3340
No files matched your search
@@ -0,0 +1,456 @@
|
||||
// TestView.cpp : implementation of the CTestView class
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Test.h"
|
||||
#include "TestDoc.h"
|
||||
#include "TestView.h"
|
||||
#include "math.h" //数学头文件
|
||||
#define PI 3.1415926 // 圆周率
|
||||
#ifdef _DEBUG
|
||||
#define new DEBUG_NEW
|
||||
#undef THIS_FILE
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CTestView
|
||||
|
||||
IMPLEMENT_DYNCREATE(CTestView, CView)
|
||||
|
||||
BEGIN_MESSAGE_MAP(CTestView, CView)
|
||||
//{{AFX_MSG_MAP(CTestView)
|
||||
ON_WM_LBUTTONDOWN()
|
||||
ON_WM_RBUTTONDBLCLK()
|
||||
ON_WM_TIMER()
|
||||
ON_WM_KEYDOWN()
|
||||
ON_WM_ERASEBKGND()
|
||||
ON_COMMAND(IDM_PLAY, OnPlay)
|
||||
ON_UPDATE_COMMAND_UI(IDM_PLAY, OnUpdatePlay)
|
||||
//}}AFX_MSG_MAP
|
||||
// Standard printing commands
|
||||
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
|
||||
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
|
||||
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CTestView construction/destruction
|
||||
|
||||
CTestView::CTestView()
|
||||
{
|
||||
// TODO: add construction code here
|
||||
bPlay = FALSE;
|
||||
R = 800.0;
|
||||
d = 1000;
|
||||
Phi = 45.0;
|
||||
Theta = 45.0;
|
||||
Alpha = 0.0;
|
||||
Beta = 0.0;
|
||||
}
|
||||
|
||||
CTestView::~CTestView()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL CTestView::PreCreateWindow(CREATESTRUCT &cs)
|
||||
{
|
||||
// TODO: Modify the Window class or styles here by modifying
|
||||
// the CREATESTRUCT cs
|
||||
|
||||
return CView::PreCreateWindow(cs);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CTestView drawing
|
||||
|
||||
void CTestView::OnDraw(CDC *pDC)
|
||||
{
|
||||
CTestDoc *pDoc = GetDocument();
|
||||
ASSERT_VALID(pDoc);
|
||||
// TODO: add draw code for native data here
|
||||
DoubleBuffer();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CTestView printing
|
||||
|
||||
BOOL CTestView::OnPreparePrinting(CPrintInfo *pInfo)
|
||||
{
|
||||
// default preparation
|
||||
return DoPreparePrinting(pInfo);
|
||||
}
|
||||
|
||||
void CTestView::OnBeginPrinting(CDC * /*pDC*/, CPrintInfo * /*pInfo*/)
|
||||
{
|
||||
// TODO: add extra initialization before printing
|
||||
}
|
||||
|
||||
void CTestView::OnEndPrinting(CDC * /*pDC*/, CPrintInfo * /*pInfo*/)
|
||||
{
|
||||
// TODO: add cleanup after printing
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CTestView diagnostics
|
||||
|
||||
#ifdef _DEBUG
|
||||
void CTestView::AssertValid() const
|
||||
{
|
||||
CView::AssertValid();
|
||||
}
|
||||
|
||||
void CTestView::Dump(CDumpContext &dc) const
|
||||
{
|
||||
CView::Dump(dc);
|
||||
}
|
||||
|
||||
CTestDoc *CTestView::GetDocument() // non-debug version is inline
|
||||
{
|
||||
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTestDoc)));
|
||||
return (CTestDoc *)m_pDocument;
|
||||
}
|
||||
#endif //_DEBUG
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CTestView message handlers
|
||||
|
||||
void CTestView::ReadVertex() // 点表
|
||||
{
|
||||
const double Golden_Section = (sqrt(5.0) - 1.0) / 2.0; // 黄金分割比例
|
||||
double a = 160; // 黄金矩形长半边的边长
|
||||
double b = a * Golden_Section; // 黄金矩形短半边的边长
|
||||
// 顶点的三维坐标(x,y,z)
|
||||
V[0].x = 0;
|
||||
V[0].y = a;
|
||||
V[0].z = b;
|
||||
V[1].x = 0;
|
||||
V[1].y = a;
|
||||
V[1].z = -b;
|
||||
V[2].x = a;
|
||||
V[2].y = b;
|
||||
V[2].z = 0;
|
||||
V[3].x = a;
|
||||
V[3].y = -b;
|
||||
V[3].z = 0;
|
||||
V[4].x = 0;
|
||||
V[4].y = -a;
|
||||
V[4].z = -b;
|
||||
V[5].x = 0;
|
||||
V[5].y = -a;
|
||||
V[5].z = b;
|
||||
V[6].x = b;
|
||||
V[6].y = 0;
|
||||
V[6].z = a;
|
||||
V[7].x = -b;
|
||||
V[7].y = 0;
|
||||
V[7].z = a;
|
||||
V[8].x = b;
|
||||
V[8].y = 0;
|
||||
V[8].z = -a;
|
||||
V[9].x = -b;
|
||||
V[9].y = 0;
|
||||
V[9].z = -a;
|
||||
V[10].x = -a;
|
||||
V[10].y = b;
|
||||
V[10].z = 0;
|
||||
V[11].x = -a;
|
||||
V[11].y = -b;
|
||||
V[11].z = 0;
|
||||
}
|
||||
|
||||
void CTestView::ReadFace() // 面表
|
||||
{
|
||||
// 面的顶点数和面的顶点索引
|
||||
F[0].SetNum(3);
|
||||
F[0].vI[0] = 0;
|
||||
F[0].vI[1] = 6;
|
||||
F[0].vI[2] = 2;
|
||||
F[1].SetNum(3);
|
||||
F[1].vI[0] = 2;
|
||||
F[1].vI[1] = 6;
|
||||
F[1].vI[2] = 3;
|
||||
F[2].SetNum(3);
|
||||
F[2].vI[0] = 3;
|
||||
F[2].vI[1] = 6;
|
||||
F[2].vI[2] = 5;
|
||||
F[3].SetNum(3);
|
||||
F[3].vI[0] = 5;
|
||||
F[3].vI[1] = 6;
|
||||
F[3].vI[2] = 7;
|
||||
F[4].SetNum(3);
|
||||
F[4].vI[0] = 0;
|
||||
F[4].vI[1] = 7;
|
||||
F[4].vI[2] = 6;
|
||||
F[5].SetNum(3);
|
||||
F[5].vI[0] = 2;
|
||||
F[5].vI[1] = 3;
|
||||
F[5].vI[2] = 8;
|
||||
F[6].SetNum(3);
|
||||
F[6].vI[0] = 1;
|
||||
F[6].vI[1] = 2;
|
||||
F[6].vI[2] = 8;
|
||||
F[7].SetNum(3);
|
||||
F[7].vI[0] = 0;
|
||||
F[7].vI[1] = 2;
|
||||
F[7].vI[2] = 1;
|
||||
F[8].SetNum(3);
|
||||
F[8].vI[0] = 0;
|
||||
F[8].vI[1] = 1;
|
||||
F[8].vI[2] = 10;
|
||||
F[9].SetNum(3);
|
||||
F[9].vI[0] = 1;
|
||||
F[9].vI[1] = 9;
|
||||
F[9].vI[2] = 10;
|
||||
F[10].SetNum(3);
|
||||
F[10].vI[0] = 1;
|
||||
F[10].vI[1] = 8;
|
||||
F[10].vI[2] = 9;
|
||||
F[11].SetNum(3);
|
||||
F[11].vI[0] = 3;
|
||||
F[11].vI[1] = 4;
|
||||
F[11].vI[2] = 8;
|
||||
F[12].SetNum(3);
|
||||
F[12].vI[0] = 3;
|
||||
F[12].vI[1] = 5;
|
||||
F[12].vI[2] = 4;
|
||||
F[13].SetNum(3);
|
||||
F[13].vI[0] = 4;
|
||||
F[13].vI[1] = 5;
|
||||
F[13].vI[2] = 11;
|
||||
F[14].SetNum(3);
|
||||
F[14].vI[0] = 7;
|
||||
F[14].vI[1] = 10;
|
||||
F[14].vI[2] = 11;
|
||||
F[15].SetNum(3);
|
||||
F[15].vI[0] = 0;
|
||||
F[15].vI[1] = 10;
|
||||
F[15].vI[2] = 7;
|
||||
F[16].SetNum(3);
|
||||
F[16].vI[0] = 4;
|
||||
F[16].vI[1] = 11;
|
||||
F[16].vI[2] = 9;
|
||||
F[17].SetNum(3);
|
||||
F[17].vI[0] = 4;
|
||||
F[17].vI[1] = 9;
|
||||
F[17].vI[2] = 8;
|
||||
F[18].SetNum(3);
|
||||
F[18].vI[0] = 5;
|
||||
F[18].vI[1] = 7;
|
||||
F[18].vI[2] = 11;
|
||||
F[19].SetNum(3);
|
||||
F[19].vI[0] = 9;
|
||||
F[19].vI[1] = 11;
|
||||
F[19].vI[2] = 10;
|
||||
}
|
||||
|
||||
void CTestView::InitParameter() // 透视变换参数初始化
|
||||
{
|
||||
k[1] = sin(PI * Theta / 180);
|
||||
k[2] = sin(PI * Phi / 180);
|
||||
k[3] = cos(PI * Theta / 180);
|
||||
k[4] = cos(PI * Phi / 180);
|
||||
k[5] = k[2] * k[3];
|
||||
k[6] = k[2] * k[1];
|
||||
k[7] = k[4] * k[3];
|
||||
k[8] = k[4] * k[1];
|
||||
ViewPoint.x = R * k[6];
|
||||
ViewPoint.y = R * k[4];
|
||||
ViewPoint.z = R * k[5];
|
||||
}
|
||||
|
||||
void CTestView::PerProject(CP3 P) // 透视变换
|
||||
{
|
||||
CP3 ViewP;
|
||||
ViewP.x = P.x * k[3] - P.z * k[1]; // 观察坐标系三维坐标
|
||||
ViewP.y = -P.x * k[8] + P.y * k[2] - P.z * k[7];
|
||||
ViewP.z = -P.x * k[6] - P.y * k[4] - P.z * k[5] + R;
|
||||
ScreenP.x = d * ViewP.x / ViewP.z; // 屏幕坐标系二维坐标
|
||||
ScreenP.y = d * ViewP.y / ViewP.z;
|
||||
}
|
||||
|
||||
void CTestView::DoubleBuffer() // 双缓冲
|
||||
{
|
||||
CDC *pDC = GetDC();
|
||||
CRect rect; // 定义客户区
|
||||
GetClientRect(&rect); // 获得客户区的大小
|
||||
pDC->SetMapMode(MM_ANISOTROPIC); // pDC自定义坐标系
|
||||
pDC->SetWindowExt(rect.Width(), rect.Height()); // 设置窗口范围
|
||||
pDC->SetViewportExt(rect.Width(), -rect.Height()); // x轴水平向右,y轴垂直向上
|
||||
pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2); // 屏幕中心为原点
|
||||
CDC MemDC; // 内存DC
|
||||
CBitmap NewBitmap, *pOldBitmap; // 内存中承载图像的临时位图
|
||||
MemDC.CreateCompatibleDC(pDC); // 建立与屏幕pDC兼容的MemDC
|
||||
NewBitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()); // 创建兼容位图
|
||||
pOldBitmap = MemDC.SelectObject(&NewBitmap); // 将兼容位图选入MemDC
|
||||
MemDC.FillSolidRect(&rect, pDC->GetBkColor()); // 按原来背景填充客户区,否则是黑色
|
||||
MemDC.SetMapMode(MM_ANISOTROPIC); // MemDC自定义坐标系
|
||||
MemDC.SetWindowExt(rect.Width(), rect.Height());
|
||||
MemDC.SetViewportExt(rect.Width(), -rect.Height());
|
||||
MemDC.SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
|
||||
DrawObject(&MemDC);
|
||||
pDC->BitBlt(-rect.Width() / 2, -rect.Height() / 2, rect.Width(), rect.Height(), &MemDC, -rect.Width() / 2, -rect.Height() / 2, SRCCOPY); // 将内存位图拷贝到屏幕
|
||||
MemDC.SelectObject(pOldBitmap); // 恢复位图
|
||||
NewBitmap.DeleteObject(); // 删除位图
|
||||
ReleaseDC(pDC); // 释放DC
|
||||
}
|
||||
|
||||
void CTestView::DrawObject(CDC *pDC) // 绘制物体表面
|
||||
{
|
||||
CP3 p[4];
|
||||
double theta, phi; // theta控制小圆旋转,phi控制大圆旋转
|
||||
double pi = 3.14159, delta = pi / 20;
|
||||
double R = 150; // 大圆半径
|
||||
double r = 50; // 小圆半径
|
||||
|
||||
for (theta = 0; theta <= 2 * pi; theta += delta)
|
||||
for (phi = 0; phi <= 2 * pi; phi += delta)
|
||||
{
|
||||
// 计算圆环体上的四个顶点
|
||||
p[0].x = (R + r * cos(theta)) * cos(phi);
|
||||
p[0].y = (R + r * cos(theta)) * sin(phi);
|
||||
p[0].z = r * sin(theta);
|
||||
|
||||
p[1].x = (R + r * cos(theta)) * cos(phi + delta);
|
||||
p[1].y = (R + r * cos(theta)) * sin(phi + delta);
|
||||
p[1].z = r * sin(theta);
|
||||
|
||||
p[2].x = (R + r * cos(theta + delta)) * cos(phi + delta);
|
||||
p[2].y = (R + r * cos(theta + delta)) * sin(phi + delta);
|
||||
p[2].z = r * sin(theta + delta);
|
||||
|
||||
p[3].x = (R + r * cos(theta + delta)) * cos(phi);
|
||||
p[3].y = (R + r * cos(theta + delta)) * sin(phi);
|
||||
p[3].z = r * sin(theta + delta);
|
||||
|
||||
// ... 保持其余代码不变 ...
|
||||
tran.SetMat(p, 4);
|
||||
tran.RotateX(Alpha);
|
||||
tran.RotateY(Beta);
|
||||
|
||||
CVector ViewVector(p[0], ViewPoint);
|
||||
ViewVector = ViewVector.Normalize();
|
||||
CFace f;
|
||||
f.SetFaceNormal(p[0], p[1], p[2]);
|
||||
f.fNormal.Normalize();
|
||||
if (Dot(ViewVector, f.fNormal) >= 0)
|
||||
{
|
||||
CP2 t;
|
||||
CLine *line = new CLine;
|
||||
for (int nPoint = 0; nPoint < 4; nPoint++)
|
||||
{
|
||||
PerProject(p[nPoint]);
|
||||
if (0 == nPoint)
|
||||
{
|
||||
line->MoveTo(pDC, ScreenP);
|
||||
t = ScreenP;
|
||||
}
|
||||
else
|
||||
line->LineTo(pDC, ScreenP);
|
||||
}
|
||||
line->LineTo(pDC, t);
|
||||
delete line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTestView::OnLButtonDown(UINT nFlags, CPoint point) // 鼠标左键函数
|
||||
{
|
||||
// TODO: Add your message handler code here and/or call default
|
||||
R = R + 100;
|
||||
InitParameter();
|
||||
Invalidate(FALSE);
|
||||
CView::OnLButtonDown(nFlags, point);
|
||||
}
|
||||
|
||||
void CTestView::OnRButtonDblClk(UINT nFlags, CPoint point) // 鼠标右键函数
|
||||
{
|
||||
// TODO: Add your message handler code here and/or call default
|
||||
R = R - 100;
|
||||
InitParameter();
|
||||
Invalidate(FALSE);
|
||||
CView::OnRButtonDblClk(nFlags, point);
|
||||
}
|
||||
|
||||
void CTestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||||
{
|
||||
// TODO: Add your message handler code here and/or call default
|
||||
if (!bPlay)
|
||||
{
|
||||
switch (nChar)
|
||||
{
|
||||
case VK_UP:
|
||||
Alpha = -5;
|
||||
tran.RotateX(Alpha);
|
||||
break;
|
||||
case VK_DOWN:
|
||||
Alpha = 5;
|
||||
tran.RotateX(Alpha);
|
||||
break;
|
||||
case VK_LEFT:
|
||||
Beta = -5;
|
||||
tran.RotateY(Beta);
|
||||
break;
|
||||
case VK_RIGHT:
|
||||
Beta = 5;
|
||||
tran.RotateY(Beta);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Invalidate(FALSE);
|
||||
}
|
||||
CView::OnKeyDown(nChar, nRepCnt, nFlags);
|
||||
}
|
||||
|
||||
void CTestView::OnPlay()
|
||||
{
|
||||
// TODO: Add your command handler code here
|
||||
bPlay = bPlay ? FALSE : TRUE;
|
||||
if (bPlay)
|
||||
SetTimer(1, 150, NULL); // 启动定时器
|
||||
else
|
||||
KillTimer(1); // 关闭定时器
|
||||
}
|
||||
|
||||
void CTestView::OnTimer(UINT nIDEvent) // 动画时间函数
|
||||
{
|
||||
// TODO: Add your message handler code here and/or call default
|
||||
Alpha += 5;
|
||||
Beta += 5;
|
||||
// tran.RotateX(Alpha);
|
||||
// tran.RotateY(Beta);
|
||||
Invalidate(FALSE);
|
||||
CView::OnTimer(nIDEvent);
|
||||
}
|
||||
|
||||
void CTestView::OnUpdatePlay(CCmdUI *pCmdUI)
|
||||
{
|
||||
// TODO: Add your command update UI handler code here
|
||||
if (bPlay)
|
||||
{
|
||||
pCmdUI->SetCheck(TRUE);
|
||||
pCmdUI->SetText("停止");
|
||||
}
|
||||
else
|
||||
{
|
||||
pCmdUI->SetCheck(FALSE);
|
||||
pCmdUI->SetText("开始");
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CTestView::OnEraseBkgnd(CDC *pDC)
|
||||
{
|
||||
// TODO: Add your message handler code here and/or call default
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CTestView::OnInitialUpdate()
|
||||
{
|
||||
CView::OnInitialUpdate();
|
||||
// TODO: Add your specialized code here and/or call the base class
|
||||
ReadVertex();
|
||||
ReadFace();
|
||||
// tran.SetMat(V,12);
|
||||
InitParameter();
|
||||
}
|
||||
Reference in new issue
Block a user