閆帥鵬 ,羅孟勤
(中國電子科技集團公司第二十九研究所,四川 成都 610036)
一幅完整的CAD圖形會包含圖層、線型、直線、多段線、圓弧、橢圓、樣條曲線等多種元素信息。為了更加完整且有條理地解析圖形原有的信息,并還原出最符合加工要求的圖形[1],本文將DXF文件讀入的流程分為幾個功能模塊,文件讀入流程如圖1所示。本文對于DXF文件中的圖形元素的解析分為五個模塊[2]:直線元素讀入模塊、多段線元素讀入模塊、橢圓(弧)元素讀入模塊、圓(?。┰刈x入模塊、樣條曲線元素讀入模塊。
圖1 DXF文件讀取流程圖
直線作為繪圖的基礎(chǔ),在近乎所有的CAD制圖中都會出現(xiàn)。因此,將直線的讀寫作為整個DXF文件解析的基礎(chǔ)是很具有代表性的。對于直線的關(guān)鍵數(shù)據(jù)就是其起始點的坐標(biāo)值[3]。根據(jù)DXF文件的編碼規(guī)則,直線數(shù)據(jù)段的結(jié)構(gòu)如下:直線關(guān)鍵字為“LINE”;“LINE”后面出現(xiàn)的組碼“10”的下方,代表示起點X坐標(biāo)值;“LINE”之后出現(xiàn)的組碼“20”的下方,代表起點Y坐標(biāo)值;“LINE”之后出現(xiàn)的組碼“11”的下方,代表終點X坐標(biāo)值;“LINE”之后出現(xiàn)的組碼“21”的下方,代表終點Y坐標(biāo)值。根據(jù)上述結(jié)構(gòu),分析得到直線數(shù)據(jù)段的讀取流程,如圖2所示。在直線數(shù)據(jù)段讀取的過程中,需要特別注意對于不同線型的區(qū)分,這樣做的目的有兩個:更加全面地讀取所有線型的數(shù)據(jù),完整還原CAD圖形;便于在進(jìn)行激光劃片的過程中把不需要進(jìn)行實際操作的虛線、點畫線等剔除掉。對于將直線還原到軟件界面上,有兩種方案可以選擇。一是將起始點的坐標(biāo)值提取出來,利用直線計算的公式便可直接計算出直線方程,然后將起始點的橫坐標(biāo)或者縱坐標(biāo)按照相當(dāng)小的差值進(jìn)行插值計算,得到整條直線的點坐標(biāo),最后通過描點的方式完成直線,其流程如圖3所示。二是利用編程軟件中自帶的直線繪制函數(shù)進(jìn)行繪制。
圖2 直線數(shù)據(jù)讀取流程圖
圖3 直線數(shù)據(jù)重新繪制流程圖
通過對比,方案1需要用戶自行編寫相應(yīng)算法,過程復(fù)雜;而方案2可以方便快捷地實現(xiàn)圖像的繪制。但是,在使用激光劃片機進(jìn)行操作時,對于運動終端的控制,仍需按照方案1的算法逐點進(jìn)行插補,完成對直線的激光劃片。直線繪制的關(guān)鍵點:直線的繪制中,按照斜率公式計算時,由于可能出現(xiàn)橫坐標(biāo)相等的分母為零的情況,所以分情況討論。一是分母不為零時,按公式求方程;二是分母為零時,只是Y方向的坐標(biāo)變化。在判斷分母時需要注意,由于DXF文件中讀出的相同坐標(biāo)值有可能在小數(shù)點后的3開始就不一樣,所以直接判斷分母是否為零會出現(xiàn)錯誤導(dǎo)致該直線基本沒有繪制的點出現(xiàn)(X坐標(biāo)基本相同,如果按公式求方程,則橫坐標(biāo)幾乎無法變化,循環(huán)就已經(jīng)結(jié)束了)。因此,在判斷分母為零時,不直接判斷是否等于0,而是加入一定的冗余量,只要ΔX<0.001時,就判斷其屬于分母等于零的情況。對于直線的繪制,通過判斷起始點與終止的上下以及左右的位置,來確定步長的正負(fù),以確保繪制的順序。
上文已經(jīng)詳細(xì)闡述了直線數(shù)據(jù)段的讀寫流程?;赩B.NET的特點,對軟件編制過程中所需的重難點進(jìn)行講解。對于圖元中包含的直線類數(shù)據(jù),可以定位一個類名為“Line”。這個類由以下屬性組成:StartX,表示原始起點的X坐標(biāo);StartY,表示原始起點的Y坐標(biāo);EndX,表示原始終點的X坐標(biāo);EndY,表示原始終點的Y坐標(biāo);LaserStartX,表示轉(zhuǎn)換后的起點X坐標(biāo);LaserStartY,表示轉(zhuǎn)換后的起點Y坐標(biāo);LaserEndX,表示轉(zhuǎn)換后的終點X坐標(biāo);LaserEndY,表示轉(zhuǎn)換后的終點Y坐標(biāo)。在讀取坐標(biāo)點數(shù)據(jù)時,由于DXF文件讀入時均是文本形式,也就是說讀入的數(shù)據(jù)全部是字符串,并不能夠參與數(shù)值運算。本軟件利用VB.NET所擁有的Csng函數(shù)功能,可以使Single類型的單精度浮點數(shù)由字符串轉(zhuǎn)換而得。同時,利用Round函數(shù),將數(shù)據(jù)精度控制在小數(shù)點后三位。舉例說明:Line.StartX=Math.Round(Csng(dxfmember(i)))
上式表示將dxfmember數(shù)組中的第i項讀出,然后利用Csng函數(shù)和Round函數(shù),將第i項所表示的字符串轉(zhuǎn)換為此時該條直線類的原始起點X坐標(biāo)值。
在對直線類進(jìn)行繪制時,可以采用Graphics的畫圖類在軟件界面進(jìn)行畫圖,其中Graphics是VB.NET自帶功能函數(shù)。該類的使用首先需要定義一個Graphics類的對象,名為Draw,其定義格式為:
Public Draw As Graphics
同時,還需要定義一個畫筆類的對象,名為ObjPen,其格式為:
Public objPen As New Pen(Color.DeepPink, 1)
其中“Color.DeepPink”表示畫筆顏色,后面的“1”表示畫筆的寬度為1個像素。在進(jìn)行繪制時,直接調(diào)用DrawLine模塊,輸入下列參數(shù):畫筆對象; 直線起點X坐標(biāo)值;直線起點Y坐標(biāo)值;直線終點X坐標(biāo)值;直線終點Y坐標(biāo)值。需要特別注意,由于VB.NET在繪制圖形時,其XOY坐標(biāo)系的定義是屏幕的左上角為(0,0)點,如圖4所示。
圖4 VB.NET繪制坐標(biāo)系
而CAD原圖形的XOY坐標(biāo)系定義是以左下角為(0,0)點,如圖5所示。
圖5 CAD原圖形的XOY坐標(biāo)系
通過對比圖4和圖5可以得知,對于任意的坐標(biāo)點在繪制時,其橫坐標(biāo)保持不變,但其縱坐標(biāo)的值需要由Y軸方向所設(shè)定的最大值與坐標(biāo)點縱坐標(biāo)的數(shù)值相減才能正確表達(dá)。也就是說,需要由所設(shè)定圖幅的高度值減去坐標(biāo)點縱坐標(biāo)值,從而得到繪圖所使用的縱坐標(biāo)值。綜上所述,完整的直線繪制命令如下:
Draw.DrawLine(objPen, Line.LaserStartX, Form1.PictureBox1.Height - Line.LaserStartY, Line.LaserEndX, Form1.PictureBox1.Height - Line.LaserEndY)
其中,objPen代表繪制所用的畫筆;LaserStartX表示轉(zhuǎn)換后的起點X坐標(biāo);LaserStartY表示轉(zhuǎn)換后的起點Y坐標(biāo);Form1.PictureBox1.Height表示繪圖界面的高度值;LaserEndX表示轉(zhuǎn)換后的終點X坐標(biāo);LaserEndY表示轉(zhuǎn)換后的終點Y坐標(biāo)。參照上面的命令,就可以將不同起始點的所有直線數(shù)據(jù)全部完整地繪制在軟件界面上。
本文根據(jù)實際應(yīng)用的需求,通過讀取DXF文件獲得了AUTOCAD文件中直線數(shù)據(jù)的幾何信息,提取了直線數(shù)據(jù)存儲數(shù)據(jù),并將其轉(zhuǎn)化,進(jìn)行重新繪制,基于VB軟件進(jìn)行編程。這可以在實際的加工生產(chǎn)中促進(jìn)加工效率的提升。