化工仿真中位图图形学编程旋转变换研究
2021-11-07何杰王大立
何杰 王大立
摘要:在化工仿真中,为了贴近真实,可以将实物图片贴于所绘化工单元设备、管道、框架、厂房等结构体表面。BMP图像可被用作纹理图。依据图像颜色点阵数据(WinHex),编写相关程序可对位图进行像素级编辑,实现如颜色拾取、图片移动、旋转、翻转、镜像、抠图等变换操作。作者编写了位图旋转变换操作程序 (Visual C++,OpenGL),为将计算机图形学编程用于化工仿真、虚拟现实进行了应用基础研究;在程序for循环主代码中,用“fread(&pixVal, sizeof(BYTE), 1, fp);”读数据,用“fwrite(&pixVal, sizeof(BYTE), 1, pFile);”写数据。其基本操作过程与手工刺绣或搭积木类似。让计算机程序组织那些像素点“对号入座”,有秩序地从原图像素网格中取出一个个像素单元格,再有秩序地放入变换后图像像素网格中,实现预想像素级图像变换操作。
关键词:图形学编程;位图旋转;像素读写;位图;化工仿真;虚拟现实
中图分类号:TN919.8 文献标识码:A
文章编号:1009-3044(2021)25-0004-03
在化工设计中,常用制图软件是AutoCAD, 3DS MAX, SOLIDWORKS, SketchUp等。这些软件基本共同使用方法是主要通过操作鼠标、键盘直接在电脑屏幕上绘制出各种图元,即点、线、面、体,再排列、组合,得到特定组合结构、形体、场景,所见即所得。另一区别制图方法是,编写、运行计算机制图程序,生成目标图形、场景。两者各有优劣。在虚拟现实中,需要展现真实感图形、场景、实现人机交互、动画、视图旋转、漫游、科学计算可视化、仿真实验等,后者对这些提供了可能,而且实现起来便捷、高效,程序运行流畅、稳定[1-6]。它在虚拟现实、化工仿真中独树一帜,不容小觑。可它目前并不为化工专业人员所普遍知晓,也很少被使用。
纹理映射允许把一个现实场景图贴于3D结构体表面,更逼真,在虚拟现实(VR)场景模拟中作用突出。使用OpenGL (Open Graphics Library) 编程接口,能够增强三维场景真实性。OpenGL提供了位图操作函数。它是被用于渲染2D、3D矢量图形、跨语言、跨平台的应用程序编程接口。实现用C++结合OpenGL制作出一个虚拟化工厂,类似使用AutoCAD Plant 3D,可以考慮先用C++结合OpenGL绘制出化工3D图形结构单元。然而,相比一般3D建模软件,OpenGL并非卓尔不群,自成一格。将OpenGL与一般3D建模软件结合起来,相辅相成,更行之有效。柳暗花明又一村,原来,由于OpenGL是图形底层图形库,没有提供几何实体图元,不能被直接用以描述场景。但是,通过一些转换程序,可以很方便地提取出自AutoCAD, 3DS MAX, SOLIDWORKS等的DXF, 3DS, OBJ, STL模型文件OpenGL顶点数组,进而对其再处理[7-9]。
宋叶未等[10]对BMP格式位图文件结构和内容进行了详细分析,给出了一种通用、易于移植的BMP格式位图文件显示算法。尹航等[11]讨论了在VS2005环境下借助OpenGL和第三方库CxImage,利用PNG图片进行纹理映射。CxImage类库是一个优秀图像操作类库,可以被用来快捷存取、显示、转换各种图像。薛兆井等[12]研究了基于OpenGL读取bmp图像实现纹理映射的一种新方法。韩姣[13]探讨了在VC++环境下BMP与GIF图像文件格式转换,编程实现了BMP图像读取、显示和保存等相关操作。本文作者用C++结合OpenGL编写了计算机程序,实现了位图旋转变换操作。
1 Bitmap-File解析
BMP文件由文件头 (bitmap-file header)、信息头 (bitmap-information header)、彩色表 (color table) 和位图数据 (bitmap data) 四部分组成。如图1a所示,点 (0,0) 和点 (514,0) 在其图像数据表中对应No. 267289 pixel, No. 267803 pixel。其间点数是(267803-267289)+1=515 points,与例图宽515 pixels吻合。在图像数据表末,自左向右“F6 F6F6”分别表示该像素颜色BGR值,对应原图10进制RGB分量, “246 246 246”,一致。如图1b所示,随意指定原图中一点 (45,194),检索到该点在图像数据表中相应位置。
2 4 Bytes对齐问题
BMP文件有个重要特性是对于图像数据区域,位图每一行像素所占Byte数必须被4整除,否则,在该位图每一行16进制码末尾补1至3 Bytes “00”。“补零”只针对位图宽检验。要行补位是因为32位Windows操作系统4-Bytes (32位) 处理速度较快。一个扫描行所占Byte数:(biwidth*biBitCount/8+3)/4*4或(biWidth*biBitCount+31)/32*4或((width*biBitCount+31) >> 5)<< 2。其中,如图1,其每行数据大小为515 pixels×3 Bytes/pixel = 1545 Bytes,不能被4整除,用“000000”补全,变为1548 Bytes ((515*24+31)/32*4=1548)。第515列为行补位列。同样,VC++程序读入BMP图像,必须把每行Byte数转换为4整数倍 (即以long为单位)。
biWidth 图像宽度,以pixel为单位。
biBitCount bits/pixel
biWidth*biBitCount 一行所占位数