![2010-7-14 更新[C++娱乐教程]用VC绘制你自己的箭头.doc_第1页](http://file.renrendoc.com/FileRoot1/2020-1/11/df9a7b6f-02f4-4a6d-84b7-8725b15122b8/df9a7b6f-02f4-4a6d-84b7-8725b15122b81.gif)
![2010-7-14 更新[C++娱乐教程]用VC绘制你自己的箭头.doc_第2页](http://file.renrendoc.com/FileRoot1/2020-1/11/df9a7b6f-02f4-4a6d-84b7-8725b15122b8/df9a7b6f-02f4-4a6d-84b7-8725b15122b82.gif)
![2010-7-14 更新[C++娱乐教程]用VC绘制你自己的箭头.doc_第3页](http://file.renrendoc.com/FileRoot1/2020-1/11/df9a7b6f-02f4-4a6d-84b7-8725b15122b8/df9a7b6f-02f4-4a6d-84b7-8725b15122b83.gif)
![2010-7-14 更新[C++娱乐教程]用VC绘制你自己的箭头.doc_第4页](http://file.renrendoc.com/FileRoot1/2020-1/11/df9a7b6f-02f4-4a6d-84b7-8725b15122b8/df9a7b6f-02f4-4a6d-84b7-8725b15122b84.gif)
![2010-7-14 更新[C++娱乐教程]用VC绘制你自己的箭头.doc_第5页](http://file.renrendoc.com/FileRoot1/2020-1/11/df9a7b6f-02f4-4a6d-84b7-8725b15122b8/df9a7b6f-02f4-4a6d-84b7-8725b15122b85.gif)
已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C+娱乐教程用VC绘制你自己的箭头Lightning0GiNrBLOG:/AegisysBBS:http:/bbs.0GiN/注:转载请声明作者,谢谢在纸上绘制一支箭头或许是再简单不过的事情你用不了两分钟的。但是你有没想过用VC + Win32 API在屏幕上绘制一个“精确”的箭头,就像右图中那样呢?给定两个点A,O的坐标,要求绘制由O指向A的箭头,为简易起见,我们设,AC = CD = 15单位,BAC = (即15度),那么我们只需要得到C、D和B的坐标就可以了。初看起来比较简单,但是拿笔一算,运算量还不小哦,至少对于我来说是不小。而且恼人的是你不得不考虑除数为0的情况。下面证明它是有多么令人恼火如果你不想恼火的话可以直接略过它(它很长的):当你不幸地学习过高中数学的解析几何部分后,我相信你会悲剧地去求AB和AD的斜率(不错,我就是这样悲剧的)。当时我熟练地从书上翻到了和角公式:当然就是AO的斜率,我们定义的15度的正切值,就是AB的斜率了,同理就是AD的斜率嗯,是的,一切都如此完美。实际上如果你这么写,数学老师一般会给你满分个别老师会扣掉1分,极个别会扣掉2分。但是计算机会给你0分因为CPU发现了如果是零的话,在计算AO斜率时会直接导致除数为0的情况导致出现异常这时候用户就会听到清脆的叮呤一声然后程序就崩溃了。更令人沮丧的是,和的计算也存在除数为0的潜在问题。为了解决它,你不得不去验证每一次的分母并做出针对斜率不存在的特殊处理这还不是最倒霉的。在计算AO斜率时,你需要一个浮点数来存储的值,于是在验证的算式中只否会存在除0情况时,麻烦来了你不能用if(dbValue = 0.0)来判断是一个浮点数是否等于0(这是一个常识,参见浮点数的存储原理。当一个值小到足够小时就可以认为它的值为0),为此你需要定义一个精度范围至此,感谢你花费一些不必要的时间来阅读上面这段蓝色文字,相信你已经对这种方法感到绝望了。没关系,我们来看比较好的方法。好的我们回到正题。上回说到了这个问题的题目,下面我们来看比较好的解决方法。为提高效率,这种方法尽量避开了使用浮点数(只在开平方的时候用了两下),变量定义得也不多,而且最重要的是不用考虑除数为0的情况!我们先来计算C点的坐标。如果你认真写过中考时的数学卷子(什么?你没认真写过?),一定会发现本题中存在如下关系:这是一个比例关系,利用了三角形的相似原理,相信我可以从右边的图(哦,还是那张)中找出是哪两个三角形噢不,我好像没有画上那两个三角形不过我相信你还是可以找到它的。(其实用三角函数比较好理解,不过我觉得应该为尚在初中学习的同学着想一点我又说废话了,大家华丽地无视我吧。)将上式由题意(这三个字是万应灵药)去掉绝对值号(实际上可以用向量来推)后得:由此我们算出了C点的坐标。细心的你会发现确保A和O不为同一点时,确实没有除以0的情况出现!不过不要高兴得太早,B、D点的坐标应该怎么办呢?很明显由于对称性(又一个写题时常用的蒙混过关的好词!),BD的连线垂直于AO,我们设垂足为K(求出K的坐标和求C是完全一样的问题,不再赘述),设D到K的水平距离为,垂直距离为(在图中已经标示,可以为负值)。如下的四个结论已经下降到了小学难度:,那么,如何计算和呢?其实方法我在描述C点的计算方法时就已经说过了,我们稍作变化:,如果你理解起来有困难的话,请你思考如下几个问题:1.在求C点时,分子上是x还是y是和所求的值是对应的如求时分子是,为什么求的时候就不一样了呢?2.是怎么来的?如果你思考了以后仍然没有想法的话,你或许说你希望跳过这段,我赞同这点。因为我写出它们的真实目的是告诉大家:看,求和的过程和求C点的过程多么像!这意味着我们可以利用这些相似的地方减少我们的编码量和代码运算量。读到这里,你一定有一个非常非常大的问题想问:你文章的标题不是说要用C+实现么,怎么我看了半天连半行代码也没看到!哦,请你原谅一下,我写作文时基本是以跑题为主,飘移为辅的。所以我语文成绩一直不太好,不过还好,下面的代码部分不需要我和你有多高的语文水平嗯,在出示代码以前,我先介绍一种常用的定点数表示浮点数的技巧,这有助于你理解代码。整数在进行除法等运算的时候不会保留小数部分,这是造成绝大多数人宁肯用double也不用int模拟实数的原因。但是目前为止,计算机处理整数还是比浮点数要快的。如果计算的过程中有3除以5怎么办?这个方法告诉你,先把3乘以一个比较大的数,然后再除以5.在最终要整数结果的时候再把这个大数除掉的OK了。比方说:a 是 3 / 5的运算结果; 求 c = 14 * a。先取一个比较大的数如100,算出100a是60,用60乘以14得840,再用840除以100得整数部分为8.还有一个需要注意的地方,箭头的方向不一定总是像图中所给的那样指向右上角,它可能指向其它方向,也可能立起来或者平躺,它的两翼的方向也存在在同样的问题。这些都需要在测试代码时考虑到。好的,我想应该到了出示代码的时候了:CODE:void Draw(CPoint& pA, CPoint& pO)/ N 和 M 类似于实现定点数const int N = 512;const int M = N * N;const int LEN = 20;const int DST = LEN * 3 / 4; / D 点到 A 点的距离const int HGT = DST / 2; / 两翼距轴的距离assert(DST != 0);CPoint Points4;Points0 = pA;int dx = pO.x - Points0.x;int dy = pO.y - Points0.y;int nLength = dx * dx + dy * dy;assert(nLength != 0); / 始末是同一个点?!int nVal = (int)sqrt(M / nLength);int sx = dx * nVal;int sy = dy * nVal;Points2.x = Points0.x + sx * DST / N;Points2.y = Points0.y + sy * DST / N;CPoint pK; / 我只是出来打酱油的pK.x = Points0.x + sx * LEN / N;pK.y = Points0.y + sy * LEN / N;int wy = sx * HGT / N;int wx = sy * HGT / N;Points1.x = pK.x - wx;Points1.y = pK.y + wy;Points3.x = pK.x + wx;Points3.y = pK.y - wy;printf(A(%d, %d), B(%d, %d) C(%d, %d) D(%d, %d)n, Points0.x, Points0.y, Points1.x, Points1.y, Points2.x, Points2.y, Points3.x, Points3.y);在Win32 GDI API中,我们可以使用函数Polygon函数来将Points数组所指示的四个点连成实心多边形。这个任务非常简单,相信我不用再写出来了。上面的代码在我的老电脑上执行10000000次,用时6500ms。下面是一个优化过的半汇编版,执行10000000次用时为4200ms。写这版本差点把人累倒另外我的汇编水平实在很差,不会用堆栈,只用了寄存器,大家将当反汇编练习着看吧。Void AsmDraw(CPoint* pA, CPoint* pO)/ N 和 M 类似于实现定点数const int N = 512;const int M = N * N;const int LEN = 20;const int DST = LEN * 3 / 4; / D 点到 A 点的距离const int HGT = DST / 2; / 两翼距轴的距离const int OFFSET1 = 1 * sizeof(CPoint);const int OFFSET2 = 2 * sizeof(CPoint);const int OFFSET3 = 3 * sizeof(CPoint);assert(DST != 0);CPoint Points4;CPoint pK;Points0 = *pA;CPoint* Pointer = Points;_ASMpushad;mov edx, dword ptr pO;mov ebx, edxCPoint.x;mov eax, dword ptr Pointer;mov eax, eaxCPoint.x;sub ebx, eax;mov esi, edxCPoint.y;mov eax, dword ptr Pointer;mov eax, eaxCPoint.y;sub esi, eax;mov edi, esi;imul edi, edi;mov ecx, ebx;imul ecx, ecx;add edi, ecx;mov eax, M;xor edx, edx;cdq;idiv edi;push eax;fild dword ptr esp;fsqrt;fistp dword ptr esp;pop eax;mov ecx, eax;imul ecx, ebx;imul esi, eax;mov eax, ecx;imul eax, DST;mov edi, N;xor edx, edx;cdq;idiv edi;mov ebx, dword ptr Pointer;mov edi, ebxCPoint.x;add edi, eax;mov eax, ebx;add eax, OFFSET2;lea eax, eaxCPoint.x;mov eax, edi;mov eax, esi;imul eax, DST;mov edi, N;xor edx, edx;cdq;idiv edi;mov edi, ebxCPoint.y;add edi, eax;mov eax, ebx;add eax, OFFSET2;lea eax, eaxCPoint.y;mov eax, edi;mov eax, ecx;imul eax, LEN;mov edi, N;xor edx, edx;cdq;idiv edi;mov edi, ebxCPoint.x;add edi, eax;lea eax, pK;lea eax, eaxCPoint.x;mov eax, edi;mov eax, esi;imul eax, LEN;mov edi, N;xor edx, edx;cdq;idiv edi;mov edi, ebxCPoint.y;add edi, eax;lea eax, pK;lea eax, eaxCPoint.y;mov eax, edi;mov eax, ecx;imul eax, HGT;mov edi, N;xor edx, edx;cdq;idiv edi;mov ecx, eax;mov eax, esi;imul eax, HGT;mov edi, N;xor edx, edx;cdq;idiv edi;mov esi, eax;lea eax, pK;mov eax, eaxCPoint.x;sub eax, esi;mov edx, ebx;add edx, OFFSET1;lea edi, edxCPoint.x;mov edi, eax;lea eax, pK;mov eax, eaxCPoint.y;add eax, ecx;mov edx, ebx;add edx, OFFSET1;lea edi, edxCPoint.y;mov edi, eax;lea eax, pK;mov eax, eaxCPoint.x;add eax, esi;mov edx, ebx;add edx, OFFSET3;lea edi, edxCPoint.x;mov edi, eax;lea eax, pK;mov eax, eaxCPoint.y;sub eax, ecx;add ebx, OFFSET3;lea edi, ebxCPoint.y;mov edi, eax;popadprintf(New
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 山西会展管理师考试题库及答案
- 青岛网约车人证考试题库及答案
- 安徽省计算机vb考试试题及答案
- 植被恢复生态补偿机制-洞察与解读
- PM心功能评估方法-洞察与解读
- 2025年病历管理制度与病历书写规范考试题(带答案)
- 2025年低碳节能减排知识竞赛题库(含答案)
- 社区农田种植共享协议
- 战略合作协议及业务资源整合
- 2025年事业单位招聘考试综合类职业能力倾向测验真题模拟试卷(考前模拟训练备考)
- 心力衰竭的全程管理
- DB4201∕T 630.1-2020 中小学生研学旅行 第1部分:服务机构评定与服务规范
- 学生文明上网班会课件
- 叮当快药大健康生态圈战略解析
- 数学评比活动方案
- TCPUMT 034-2025 工业数字孪生 数字模型与数据集成交换要求
- 曹植的故事课件小学生
- 【艾瑞咨询】2024年中国健康管理行业研究报告494mb
- 施工作业安全管理制度
- 2025年房地产经纪人考试题及答案
- 4.3禁止生物武器
评论
0/150
提交评论