实验六 背向面消隐算法

1.实验目的:

了解背向面消隐的基本原理,利用VC实现三棱锥的消隐处理。

2.实验内容:

(1) 阅读教材P139页了解背向面消隐的基本原理;

(2) 阅读教材P194页了解矢量的点积与叉积;

(3) 运行示范代码,了解背向面消隐的实现。

3.实验代码:

完整代码下载:/Files/opengl/BackfaceCull.rar

核心代码如下:

void CBackfaceCullView::OnDraw(CDC* pDC)

{

CBackfaceCullDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

CRect rect;

GetClientRect(&rect);

pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);

mT.p[3][0] = lx; mT.p[3][1] = ly;mT.p[3][2] = lz;

mRx.p[1][1] = cos(alpha); mRx.p[2][1] = -sin(alpha);mRx.p[1][2] = sin(alpha); mRx.p[2][2] = cos(alpha);

mRy.p[0][0] = cos(phi); mRy.p[0][2] = -sin(phi); mRy.p[2][0] = sin(phi); mRy.p[2][2] = cos(phi);

mP.p[2][2] = 0;

//mP.p[2][3] = -1/d;

//mP.p[2][3] = 0;

mTemp = Multiply(mT, mRy);

mTemp = Multiply(mTemp, mRx);

mA = Multiply(mTemp, mP);

PyramidProject();

DrawPyramid(pDC);

}

void CBackfaceCullView::DrawPyramid(CDC* pDC)

{

int ptIdx[3];

for(int face=0;face<4;face++)

{

int num =fInfo[face].num;//面的总顶点数

for(int i=0;i<num;i++)//循环

{

ptIdx[i] = GetPtIdx(fInfo[face], i);//面的顶点号

}

bool bDraw = true;

if(m_bHide)

{

//计算面的外法向量

/*

| i j k |

|x2-x1 y2-y1 z2-z1 |

|x3-x2 y3-y2 z3-z2 |

*/

double x1 = m_tmpPt[ptIdx[0]].x;

double y1 = m_tmpPt[ptIdx[0]].y;

double z1 = m_tmpPt[ptIdx[0]].z;

double x2 = m_tmpPt[ptIdx[1]].x;

double y2 = m_tmpPt[ptIdx[1]].y;

double z2 = m_tmpPt[ptIdx[1]].z;

double x3 = m_tmpPt[ptIdx[2]].x;

double y3 = m_tmpPt[ptIdx[2]].y;

double z3 = m_tmpPt[ptIdx[2]].z;

double xn,yn,zn,vn;

xn = (y2 - y1)*(z3-z2) - (y3-y2)*(z2-z1);

yn = -(x2-x1)*(z3-z2) + (x3-x2)*(z2-z1);

zn = (x2-x1)*(y3-y2) - (x3-x2)*(y2-y1); //计算每个面的法矢

vn = sqrt(xn*xn + yn*yn + zn*zn);

xn = xn/vn; yn = yn/vn; zn = zn/vn; //视点方向在(0,0,-1)处

if(zn < 0.0) //视线方向与Z轴同向,当法矢的Z方向分量大于0时,与实现方向成小于90度的角,面可见

{

bDraw = false;

}

}

if(bDraw)

{

for(int j=0; j<3; j++)

{

int idx0 = ptIdx[j];

int idx1 = ((j== 2) ? ptIdx[0]:ptIdx[j+1]);

pDC->MoveTo(m_Pt2d[idx0].x, m_Pt2d[idx0].y);

pDC->LineTo(m_Pt2d[idx1].x, m_Pt2d[idx1].y);

}

}

}

}

4.代码说明:

(1)ReadPoint:定义三棱锥的4个顶点,每个顶点用三维坐标表示;

(2)ReadFace:定义三棱锥的4个面的顶点信息,顶点顺序为逆时针以保证该面的法线向外;

(3)对每个面,读出三个顶点,使用(V2-V1)╳(V3-V2)计算外法向量N;

(4)采用正面投影显示三棱锥,即z’=0;视线方向向量S为(0,0,-1);

(5)未消隐处理下,不计算视向量S与法向量N的点积,直接绘制;

(6)消隐处理下,计算视向量S与法向量N的点积为-zn,如果-zn>0即zn<0为背向面,不绘制面;否则绘制;

(7)设置键盘的上下左右键用于调整三棱锥的显示角度;

(8)三棱锥示意图:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏专知

【重磅】深度学习顶会 ICLR 2018 匿名提交论文列表(附pdf下载链接)

【导读】ICLR,全称为「International Conference on Learning Representations」(国际学习表征会议),201...

664100
来自专栏懒人开发

(7.1)James Stewart Calculus 5th Edition:Integration by Parts

注意: 这样做,目的是为了 降阶, 如果转换后,对应的没有起到 降阶 的作用,就没有什么意义了

11510
来自专栏新智元

深度学习挑战冯·诺依曼结构

【新智元导读】想挑战冯·诺依曼,就必须从三个要素入手:基本操作,例如加减乘除;逻辑流程控制,例如if-else-then,for,while;设存储器,内存和硬...

407110
来自专栏CreateAMind

神经网络图灵机(Neural Turing Machines, NTM)论文完整翻译

16840
来自专栏落影的专栏

GPUImage详细解析(二)

解析 GPUImage详细解析(一) 上一篇介绍的是GPUImageFramebuffer和GPUImageFilter。 简单回顾一下: GPUImag...

30330
来自专栏吉浦迅科技

DAY2:阅读CUDA C Programming Guide之编程模型

25240
来自专栏CreateAMind

神经网络图灵机(Neural Turing Machines, NTM)论文完整翻译

Alex Graves gravesa@google.com Greg Wayne gregwayne@google.com Ivo Danihelka dan...

11020
来自专栏菩提树下的杨过

Oracle BIEE (Business Intelligence) 11g 11.1.1.6.0 学习(4)创建多维钻取分析

  在上一节时,我们创建了一个基于部门号的工资分类汇总。 这里就引出了一个概念:维度   专业的解释大家自行百度,这里就不班门弄斧了。从数据的使用角度看,维度可...

20990
来自专栏机器学习算法工程师

深入理解TensorFlow中的tf.metrics算子

本文翻译自Avoiding headaches with tf.metrics,原作者保留版权。

41120
来自专栏Soul Joy Hub

TensorFlow指南(一)——上手TensorFlow

http://blog.csdn.net/u011239443/article/details/79066094 TensorFlow是谷歌开源的深度学习库...

52950

扫码关注云+社区

领取腾讯云代金券