




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
學(xué)科分類號0812本科學(xué)生畢業(yè)論文〔設(shè)計(jì)〕基于VC的根本矢量圖形系統(tǒng)的開發(fā)與實(shí)現(xiàn)DevelopmentandImplementationofBasicVectorGraphicsSystemUnderVC學(xué)號院〔系〕計(jì)算機(jī)與通信工程系計(jì)算機(jī)科學(xué)與技術(shù)2007級指導(dǎo)教師目錄第一章緒論11.1選題背景及意義11.2國內(nèi)外研究現(xiàn)狀11.3論文內(nèi)容及結(jié)構(gòu)安排21.4本章小結(jié)3第二章矢量圖形系統(tǒng)的分析與設(shè)計(jì)42.1開發(fā)思路42.2開發(fā)模式42.3功能分析52.4功能模塊設(shè)計(jì)62.5本章小結(jié)6第三章矢量圖形系統(tǒng)的坐標(biāo)轉(zhuǎn)換73.1Windows環(huán)境下的坐標(biāo)系73.1.1設(shè)備坐標(biāo)73.1.2邏輯坐標(biāo)73.2設(shè)備坐標(biāo)與邏輯坐標(biāo)83.2.1設(shè)備坐標(biāo)與邏輯坐標(biāo)的關(guān)系83.2.1設(shè)備坐標(biāo)及邏輯坐標(biāo)的轉(zhuǎn)換83.3窗口與視口93.4本章小結(jié)9第四章實(shí)現(xiàn)矢量圖形系統(tǒng)的文檔和視圖104.1矢量圖形系統(tǒng)的圖形元素類104.1.1圖形元素基類104.1.2直線類104.1.3連續(xù)直線或封閉多邊形類104.1.4圓類104.1.5圓弧類114.1.6標(biāo)注文本類114.1.7圖形參數(shù)類114.2矢量圖形系統(tǒng)的文檔114.2.1面向?qū)ο蟮奈臋n管理機(jī)制114.2.2創(chuàng)立圖形元素對象指針114.2.3矢量圖形系統(tǒng)的文檔124.2.4實(shí)現(xiàn)文檔的管理功能124.3矢量圖形系統(tǒng)的視圖134.3.1建立坐標(biāo)系134.3.2實(shí)現(xiàn)各類圖形元素的繪制功能144.3.3實(shí)現(xiàn)視圖的繪制144.4鼠標(biāo)交互繪圖154.4.1要解決的主要問題154.4.2交互繪制各類圖形元素154.5本章小結(jié)17第五章矢量圖形系統(tǒng)的操作功能185.1圖形操作菜單管理185.1.1增加菜單資源185.1.2添加消息處理函數(shù)185.2圖形操作的具體實(shí)現(xiàn)195.2.1圖形重畫195.2.2圖形放大和移動205.2.3重畫上屏和重畫首屏225.2.4顯示全圖245.2.5圖形重畫速度的提升255.3圖形的點(diǎn)選與撤銷275.3.1鼠標(biāo)點(diǎn)選圖形元素275.3.2各種圖形元素的點(diǎn)選判斷函數(shù)285.3.3實(shí)現(xiàn)點(diǎn)選圖形元素功能295.3.4選中圖形元素的特殊顯示315.3.5撤銷選中的圖形元素325.4圖形元素的刪除325.5本章小結(jié)35第六章總結(jié)與展望366.1總結(jié)366.2展望36參考文獻(xiàn)37致謝38基于VC的根本矢量圖形系統(tǒng)的開發(fā)與實(shí)現(xiàn)摘要矢量圖形系統(tǒng)作為GIS系統(tǒng)組成的一局部,隨著GIS系統(tǒng)用戶的不同,對于矢量圖形系統(tǒng)的要求也不同,現(xiàn)有GIS矢量圖形繪制系統(tǒng)功能全面,但是針對性差,所以有針對性的從底層自主開發(fā)符合自己需要的矢量圖形系統(tǒng)是十分必要的。論文利用面向?qū)ο蟮某绦蛟O(shè)計(jì)和C++類的組織方法,在VC6.0下實(shí)現(xiàn)了一個根本的矢量圖形系統(tǒng),能夠?qū)崿F(xiàn)鼠標(biāo)繪制直線、圓、圓弧、圓形區(qū)域等功能。通過對矢量圖形系統(tǒng)坐標(biāo)系的建立及其與Windows坐標(biāo)系之間的轉(zhuǎn)換關(guān)系的探討,實(shí)現(xiàn)了圖形的無級縮放、漫游、全圖顯示等操作功能。通過對點(diǎn)選圖形元素的原理的研究,實(shí)現(xiàn)了圖形的選中、圖形刪除、放棄選中等功能。此外,就矢量圖形的顯示速度等問題進(jìn)行了探討,并提出了加快圖形顯示速度的根本方法:在顯示一個圖形元素前,對這個圖形元素進(jìn)行判斷,判斷這個圖形元素是否在視圖屏幕中,如果這個圖形元素不在當(dāng)前的視圖屏幕中,就不用對這個圖形元素進(jìn)行繪制,以此節(jié)省繪制時間。 系統(tǒng)具有比擬完善的圖形繪制功能,可應(yīng)用于城市信息管理系統(tǒng)中。【關(guān)鍵詞】矢量圖形;鼠標(biāo)繪圖;無極縮放DevelopmentandImplementationofBasicVectorGraphicsSystemUnderVCAbstractVectorgraphicssystemasacomponentpartoftheGISsystem,GISsystemuserswithdifferentrequirementsforthevectorgraphicssystemisdifferent,andtheexistingfull-featuredGISgraphicsrenderingsystem,buttargetedpoor,ittargetedindependentfromtheunderlyingdevelopmentinlinewiththeirvectorgraphicssystemneedsisessential.Byusingobject-orientedprogrammingandC++classmethodoforganization,theorganizationimplementsabasicvectorgraphicssystemthatenablesthemousetodrawastraightline,circle,arc,circleandsoon.VectorgraphicssystemthroughtheestablishmentofthecoordinatesystemanditsWindowscoordinatesystemconversionrelationshipbetweenstudyandrealizethesteplesszoomgraphics,roaming,fullmapdisplayandotheroperationsfunctions.Clickthroughontheprinciplesofgraphicelementstoachievetheselectedgraphic,graphics,remove,abandonselectedfunctions.Inaddition,vectorgraphicsdisplayspeedoftheotherissuesdiscussed,Andproposedtoacceleratethespeedofthebasicmethodofgraphicaldisplay,whichisagraphicalelementinthedisplaybeforethejudgeonthegraphicelementstodeterminewhetherthegraphicelementsintheviewscreen,ifthegraphicelementisnotthecurrentviewofthescreen,theydonotdrawonthegraphicelementsinordertosaverenderingtime.Systemhasarelativelycompletegraphicsrenderingcapabilities,mainlyusedforurbaninformationmanagementsystem.【Keywords】vectorgraphic;Mousedrawing;PromiseZoom第一章緒論1.1選題背景及意義一個根本的GIS系統(tǒng)包括管理空間坐標(biāo)數(shù)據(jù)的矢量圖形系統(tǒng)和管理屬性信息的數(shù)據(jù)庫管理系統(tǒng),以及實(shí)現(xiàn)矢量圖形系統(tǒng)與數(shù)據(jù)庫管理系統(tǒng)雙向連接的連接系統(tǒng)三個局部1]。 矢量圖形系統(tǒng)面向地理對象,是地理實(shí)體抽象和完整表達(dá)的主要方式,因而是GIS系統(tǒng)中重要的組成局部,也是開發(fā)一個GIS系統(tǒng)的重點(diǎn)所在2]。 一些專業(yè)的商品化GIS軟件都提供了比擬完善的圖形系統(tǒng)的功能,利用這些專業(yè)的工具軟件進(jìn)行開發(fā),雖然開發(fā)難度不高,簡單易學(xué),但也普遍存在著一些弊端3]:⑴不易擴(kuò)展。專業(yè)的GIS工具軟件提供的接口復(fù)雜,難于修改,不能夠很好的擴(kuò)展;⑵軟硬件要求高。專業(yè)的GIS軟件開發(fā)工具通常比擬龐大,對系統(tǒng)軟硬件的要求高;⑶軟件不易升級。利用GIS專業(yè)軟件工具所進(jìn)行的圖形系統(tǒng)的開發(fā),實(shí)質(zhì)上只是在這些專業(yè)軟件根底上做一些簡單的應(yīng)用開發(fā),開發(fā)完成的產(chǎn)品同樣需要這些專業(yè)軟件工具的支撐,因此,軟件的升級就要受到制約;⑷代價高。商品化的GIS軟件要面向最廣的用戶,所以軟件和系統(tǒng)還是作為一個整體而存在,開發(fā)者必須要購置整個的GIS軟件,代價較高,而且購置的平臺中真正需要的功能可能只是很少的一局部,造成了軟件資源的浪費(fèi)。 此外,在實(shí)際的應(yīng)用中,我們對系統(tǒng)的需求往往主要集中在某些特定功能上,如本論文結(jié)合信息平臺的需求,所需要的功能主要是圖形的繪制、顯示、查詢、縮放等。然而,商品化的GIS軟件致力于提供解決方案,它提供了全面的GIS功能,因此,面向?qū)嶋H應(yīng)用的針對性必然要差一些。 綜合以上分析,對于有特定需求的用戶來說,有針對性的從底層自主開發(fā)符合自己需要的矢量圖形系統(tǒng)是十分必要的。1.2國內(nèi)外研究現(xiàn)狀 矢量圖形系統(tǒng)作為GIS系統(tǒng)最重要的組成局部,應(yīng)用領(lǐng)域也不斷擴(kuò)大,已進(jìn)入了普通管理信息系統(tǒng)(MIS)[4],GIS矢量圖形系統(tǒng)與普通管理信息系統(tǒng)相結(jié)合,克服了MIS系統(tǒng)的局限性,大大提高了系統(tǒng)的直觀性和可操作性,同時提高了MIS系統(tǒng)所不能解決的如空間信息統(tǒng)計(jì)、屬性信息計(jì)算等功能。 專業(yè)的GIS軟件大都提供了較為完善的矢量圖形的開發(fā)功能。借助這些專業(yè)的開發(fā)工具軟件,出現(xiàn)了大量GIS系統(tǒng)的研究和開發(fā)成果。 文獻(xiàn)[5]提出了一種小型GIS矢量圖形系統(tǒng)的設(shè)計(jì)方案,利用GIS、面向?qū)ο蠹皵?shù)據(jù)庫等技術(shù),以VC++6.0開發(fā)平臺,底層開發(fā)實(shí)現(xiàn)了一個具有圖形編輯功能,且有與第三方GIS軟件數(shù)據(jù)接口功能的GIS矢量圖形系統(tǒng),并已在生產(chǎn)中得到了應(yīng)用。 文獻(xiàn)[6]提出了一種基于MFC的動態(tài)交互的矢量圖形系統(tǒng)的快速開發(fā)方法,設(shè)計(jì)實(shí)現(xiàn)的矢量圖形系統(tǒng)已成功應(yīng)用于測繪數(shù)據(jù)處理等專門問題的解決中。 文獻(xiàn)[7]同樣利用VC++6.0,基于面向?qū)ο蠹夹g(shù)的軟件工程思想開發(fā)實(shí)現(xiàn)了一個用于煤礦平安分析可視化研究的矢量圖形系統(tǒng)。 綜上所述,從底層開發(fā)實(shí)現(xiàn)的GIS矢量圖形系統(tǒng)以其較好的靈活性和可操作性已經(jīng)在很多領(lǐng)域得到了推廣應(yīng)用。1.3論文內(nèi)容及結(jié)構(gòu)安排本文主要研究如何基于VC++從底層開發(fā)實(shí)現(xiàn)一個能夠滿足信息平臺需求的矢量圖形系統(tǒng)。主要對圖形元素的組織和存儲、圖形對象的繪制、圖形的操作、圖形與屬性的雙向查詢、圖層管理等方面進(jìn)行研究,具體包括以下幾個方面的工作:⑴采用面向?qū)ο蟮姆椒ㄍ瓿墒噶繄D形數(shù)據(jù)對象類的組織和存儲,實(shí)現(xiàn)包括圓形,直線,點(diǎn),標(biāo)注文本等圖形元素的繪制;⑵能夠?qū)崿F(xiàn)鼠標(biāo)交互繪圖的功能;⑶研究矢量圖形系統(tǒng)坐標(biāo)系的建立及坐標(biāo)轉(zhuǎn)換關(guān)系,并在此根底上實(shí)現(xiàn)圖形的無級縮放、移動、全圖顯示等操作功能;⑷能夠?qū)D形進(jìn)行選中、刪除等功能。論文的結(jié)構(gòu)安排: 第一章是緒論,主要對課題的研究背景、矢量圖形系統(tǒng)開發(fā)研究的現(xiàn)狀進(jìn)行了探討,并簡要介紹了本文的研究內(nèi)容; 第二章是對本系統(tǒng)的分析與設(shè)計(jì),主要介紹系統(tǒng)的開發(fā)思路、開發(fā)模式的選擇、系統(tǒng)功能模塊設(shè)計(jì)等內(nèi)容; 第三章是矢量圖形系統(tǒng)坐標(biāo)系的設(shè)計(jì)。介紹和分析了Windows環(huán)境下的邏輯坐標(biāo)系和設(shè)備坐標(biāo)系,在此根底上建立了系統(tǒng)的實(shí)際坐標(biāo)系以及三種坐標(biāo)之間的轉(zhuǎn)換關(guān)系; 第四章是實(shí)現(xiàn)圖形系統(tǒng)的文檔和視圖,這一章主要是真對在系統(tǒng)實(shí)現(xiàn)過程中所用到的一些文檔與視圖的管理; 第五章矢量圖形系統(tǒng)的操作功能,這一章是論文的重點(diǎn),主要對系統(tǒng)各功能模塊的實(shí)現(xiàn)技術(shù)、實(shí)現(xiàn)過程進(jìn)行了詳細(xì)的研究和闡述; 第六章主要是對全文進(jìn)行的一個總結(jié)。1.4本章小結(jié) 本章主要是對GIS系統(tǒng)的研究背景、研究現(xiàn)狀進(jìn)行了簡單的描述,從而表達(dá)出選題的意義及其目的,在確定了系統(tǒng)需要的功能后,對整個系統(tǒng)的功能進(jìn)行了簡單的描述,并對系統(tǒng)預(yù)期實(shí)現(xiàn)的功能進(jìn)行了分析,最后列出了整篇論文的根本構(gòu)架。第二章矢量圖形系統(tǒng)的分析與設(shè)計(jì)2.1開發(fā)思路 一個根本的矢量圖形系統(tǒng)包含兩個局部:矢量圖形元素以及對圖形元素的各種操作。基于這兩個組成局部,本文將從以下兩方面組織確立系統(tǒng)的開發(fā)思路。 開發(fā)工具的選擇:從底層開發(fā)GIS矢量圖形系統(tǒng)的首要問題是要選擇適宜的可視化編程語言9]。適用的有Delphi,VC++等。目前比擬流行的GIS專業(yè)軟件平臺多是用C++開發(fā)完成的。在Windows下VC++是一個很好的底層開發(fā)工具。VC++通過微軟根底類MFC〔MicrosoftFoundationClass〕把WIN32API封裝起來,使得在MFC根底上用C++編寫Windows平臺下面的程序更為方便。此外,VC++的MFC提供了很多與圖形操作有關(guān)的類,使得VC++結(jié)合GDI對象可以簡單的實(shí)現(xiàn)圖形圖像的顯示。因此使用VC++開發(fā)圖形系統(tǒng),具有開發(fā)靈活、功能強(qiáng)等特點(diǎn)。最重要的一點(diǎn)是MFC在簡化編程的同時,并沒有限制對系統(tǒng)的控制,設(shè)計(jì)出的程序也穩(wěn)定、高效。所以兩者的結(jié)合有利于矢量圖形系統(tǒng)的開發(fā)。因此,系統(tǒng)選用MicrosoftVisualC++6.0〔簡稱VC6.0〕作為開發(fā)平臺,VC++作為程序設(shè)計(jì)語言。2.2開發(fā)模式 當(dāng)前的軟件開發(fā)模式有面向過程和面向?qū)ο髢煞N。面向過程的方法 面向過程的方法也就是傳統(tǒng)的結(jié)構(gòu)化方法10],包括結(jié)構(gòu)化系統(tǒng)分析、系統(tǒng)設(shè)計(jì)及程序設(shè)計(jì)方法,是以系統(tǒng)中的數(shù)據(jù)及對數(shù)據(jù)進(jìn)行處理的過程為研究中心的。面向過程的方法構(gòu)建一個系統(tǒng)的流程是:從需求出發(fā),制定方案,編寫代碼,測試代碼,維護(hù)系統(tǒng)。面向?qū)ο蟮姆椒?面向?qū)ο蟮姆椒ā睴bject-OrientedParadigm,簡稱O-O方法〕是目前軟件開發(fā)的主流方法11]。面向?qū)ο蟮姆椒ㄒ詫ο鬄橹行模瑢ο笫菍傩浴矓?shù)據(jù)〕和操作〔處理數(shù)據(jù)的函數(shù)〕的封裝體。面向?qū)ο蠓椒ㄓ腥缦氯筇匦?2]:⑴封裝性:封裝性(Encapsulation)是指對象將其屬性的實(shí)現(xiàn)細(xì)節(jié)隱藏在內(nèi)部,外界只有通過函數(shù)才能對其訪問和利用。因此保證了面向?qū)ο筌浖目蓸?gòu)造性和易維護(hù)性;⑵繼承性:繼承性(Inheritance)是指下層對象能夠擁有上層對象的特征〔屬性和操作〕的能力。繼承性是面向?qū)ο蠓椒ㄖ凶钪匾臋C(jī)制,可以通過繼承機(jī)制擴(kuò)充和完善舊的程序設(shè)計(jì)以適應(yīng)新的需求;⑶多態(tài)性:多態(tài)性(Polymorphism)是指發(fā)出同樣的消息被不同類型的對象接收時導(dǎo)致完全不同的行為。這里所說的消息主要是指對對象函數(shù)的調(diào)用,而不同的行為是指不同的實(shí)現(xiàn)。多態(tài)性表達(dá)了對象行為的擴(kuò)充能力,使程序的動態(tài)鏈接方便易行。面向?qū)ο蠓椒ǖ倪@三大特性是相互關(guān)聯(lián)的,封裝性是根底,繼承性是關(guān)鍵,多態(tài)性是補(bǔ)充,而多態(tài)性又必須存在于繼承的環(huán)境中。兩種開發(fā)模式的比擬 應(yīng)用于不同領(lǐng)域的GIS系統(tǒng),對矢量圖形系統(tǒng)功能的要求是有差異的12]。用戶的需求也可能是逐步提出的,如果考慮系統(tǒng)的所有功能,那么在構(gòu)建時會很困難。而面向過程的方法在做需求分析、制定方案階段都需要用戶的參與,開發(fā)人員對這些需求的理解也會存在差異,這就導(dǎo)致開發(fā)人員將不斷地修改這些面向過程的代碼,陷入代碼的泥潭。面向?qū)ο蠹夹g(shù)很好地解決了這種問題。在需求分析階段,如果用戶對需求不十分清楚,正如在此系統(tǒng)中,那么開發(fā)人員無須考慮將要構(gòu)建的矢量圖形系統(tǒng)會應(yīng)用于哪一類實(shí)際應(yīng)用,可以先從一般的需求出發(fā),構(gòu)造實(shí)現(xiàn)這種需求的對象,把系統(tǒng)看做是一組相對獨(dú)立的對象的集合,規(guī)定其操作13],由多個對象抽象為類,由類構(gòu)造派生類,由這些類派生出實(shí)例,逐步構(gòu)造系統(tǒng)。由于對象的數(shù)據(jù)與其操作〔處理數(shù)據(jù)的函數(shù)〕是封裝的,并通過函數(shù)與外部進(jìn)行聯(lián)系,這是一種自下向上的開發(fā)方法,在對某個對象修改時只涉及該對象、該類的細(xì)節(jié),不影響整個系統(tǒng)。這使建立一個根本圖形系統(tǒng)來滿足不同圖形應(yīng)用系統(tǒng)開發(fā)的需要具有了可行性。將面向?qū)ο蠹夹g(shù)應(yīng)用于矢量圖形系統(tǒng)的設(shè)計(jì)當(dāng)中,可以根據(jù)應(yīng)用系統(tǒng)本身的需求來實(shí)現(xiàn)功能,使軟件易于擴(kuò)充。面向?qū)ο蟮姆椒ㄔ贕IS中的應(yīng)用,己經(jīng)成為GIS開展的方向。這是因?yàn)榭臻g信息較之傳統(tǒng)數(shù)據(jù)庫處理的一維信息更為復(fù)雜、繁瑣,面向?qū)ο蟮姆椒槊枋鰪?fù)雜的空間信息提供了一條直觀、結(jié)構(gòu)清晰、組織有序的方法。 基于以上分析,確定本系統(tǒng)的開發(fā)思路是:在Windows下選用VC6.0作為開發(fā)平臺,VC++作為程序設(shè)計(jì)語言,采用面向?qū)ο蟮能浖_發(fā)模式,從底層開發(fā)獨(dú)立于其他任何專業(yè)GIS開發(fā)平臺的軟件產(chǎn)品。2.3功能分析 一個根本的GIS矢量圖形系統(tǒng),一般應(yīng)具備如下根本功能10]:⑴比擬完善的圖形元素。具備處理點(diǎn)、線、面等根本圖形元素的能力;⑵比擬完善的圖形繪制功能,能夠繪制圖形系統(tǒng)的各種圖形元素;⑶比擬完善的圖形操作功能。具備圖形的放縮、漫游、全屏等功能;⑷圖層管理功能。根據(jù)圖形元素的屬性不同,分圖層進(jìn)行管理;⑸具有顏色、線型、線寬、填充色等參數(shù)的設(shè)置功能;⑹圖形對象的各種選取功能。根據(jù)需要選定圖形對象,如點(diǎn)選、框選等。 但不同的行業(yè)對GIS矢量圖形系統(tǒng)的需求是有差異的[14]。建立一個城市信息管理系統(tǒng),要求矢量圖形系統(tǒng)具有豐富的圖形元素、豐富的線型、巨大的存儲容量、完整的輸入和輸出、強(qiáng)大的地圖編輯功能等;而建立一個地圖查詢系統(tǒng),那么只需要地圖顯示和操作的根本功能。根據(jù)以上功能分析,本系統(tǒng)將以矢量圖形系統(tǒng)所應(yīng)具備的根本功能為根底,從城市信息管理系統(tǒng)的需求出發(fā)進(jìn)行系統(tǒng)功能的設(shè)計(jì)。2.4功能模塊設(shè)計(jì) 本系統(tǒng)對功能結(jié)構(gòu)的設(shè)計(jì)采用的是完全面向?qū)ο蟮哪K化方式,“模塊化的設(shè)計(jì)方式,使得系統(tǒng)能夠易于維護(hù)和擴(kuò)展。系統(tǒng)主要包含以下能模塊:圖形繪制模塊、圖形操作模塊、查詢模塊、矢量數(shù)據(jù)的輸入及輸出模塊。下面分別對各模塊功能作簡要說明。圖形繪制模塊 該模塊主要實(shí)現(xiàn)對根本圖形元素類〔點(diǎn)、線、圓、圓形區(qū)域、標(biāo)注文本等〕的繪制功能。2.圖形操作模塊 該模塊要實(shí)現(xiàn)的主要操作功能有:⑴圖形無級縮放:圖形能夠以任意比例尺放大縮小;⑵漫游:通過調(diào)整視圖屏幕來顯示圖形的其他局部進(jìn)行瀏覽;⑶全圖顯示:在視圖屏幕中顯示所有圖形元素;⑷點(diǎn)選:通過鼠標(biāo)點(diǎn)擊選取當(dāng)前視圖屏幕中的圖形元素并查詢其屬性數(shù)據(jù)。2.5本章小結(jié) 本章主要對系統(tǒng)開發(fā)的思路進(jìn)行了簡單的闡述,包括矢量圖形系統(tǒng)的構(gòu)成、開發(fā)工具的選擇等方面;開發(fā)模式的選擇,包括對兩種開發(fā)模式的簡單介紹,并對兩種開發(fā)模式進(jìn)行了比擬,選出了適合本系統(tǒng)的開發(fā)模式,即面向?qū)ο箝_發(fā)模式;闡述了組本錢系統(tǒng)的幾個模塊,并對各個模塊的功能進(jìn)行了分析與介紹。第三章矢量圖形系統(tǒng)的坐標(biāo)轉(zhuǎn)換3.1Windows環(huán)境下的坐標(biāo)系3.1.1設(shè)備坐標(biāo) 設(shè)備坐標(biāo)是指在Windows環(huán)境下的各種輸出設(shè)備所使用的坐標(biāo)4,5]。它所對應(yīng)的對象是具體的設(shè)備,如:鍵盤、顯示器及打印機(jī)等。設(shè)備坐標(biāo)是建立在笛卡爾直角坐標(biāo)系上的,以像素為單位。一個實(shí)際物理屏幕就是由像素組成的,如平常所說的分辨率1024*768指的就是顯示器屏幕的實(shí)際寬度和高度的像素?cái)?shù)目。由于不同的設(shè)備分辨率不同,相同坐標(biāo)值的物理位置就可能不同。邏輯坐標(biāo) 邏輯坐標(biāo)也是建立在笛卡爾坐標(biāo)系上的,即是指Windows系統(tǒng)各種映射模式下的坐標(biāo)。Windows系統(tǒng)為了方便程序開發(fā),為我們提供了如表3.1所示的8種映像模式:表3.1Windows映像模式映射模式映射識別碼邏輯單元X和Y軸正向MM_TEXT1Pixel右下MM_LOMETRIC20.1mm右上MM_HIMETRIC30,01mm右上MM_LONGLISH40.1inch右上MM_HIENGLISH50.01inch右上MM_TWIPS61/440inch右上MM_ISOTROPIC7Variable變化的MM_ANISOTROPIC8Variable變化的 其中MM_TEXT方式宇DOS文本方式很相似,MM_Text方式允許應(yīng)用程序利用設(shè)備像素工作,而DOS是在字符狀態(tài)下操作。在此模式下,窗口〔屏幕〕的原點(diǎn)是在坐上角,X的正方向?yàn)橄蛴?,Y的正方向?yàn)橄蛳隆?而MM_LOMETRIC、MM_LONGLISH、MM_HIENGLISH、MM_HIMETRIC四種映像方式默認(rèn)的原點(diǎn)即是窗口的左上角,X的正方向?yàn)橄蛴?,Y的正方向?yàn)橄蛏?。坐?biāo)用英尺(inch)或毫米(mm)表示,對于繪圖程序來說很方便,不用進(jìn)行坐標(biāo)轉(zhuǎn)換。MM_ISOTROPIC與MM_ANISOTROPIC映像方式都是用笛卡爾坐標(biāo),且提供可變的邏輯單位和可變的原點(diǎn)。在MM_ISOTROPIC方式下,X軸和Y軸坐標(biāo)的刻度是相同的,而MM_ANISOTROPIC方式下X軸和Y軸坐標(biāo)的刻度是可以設(shè)置為不同的。 MM_TWRIPS方式下,TWIPS是對“一個點(diǎn)的1/20”3.2設(shè)備坐標(biāo)與邏輯坐標(biāo)設(shè)備坐標(biāo)與邏輯坐標(biāo)的關(guān)系邏輯坐標(biāo)不同于設(shè)備坐標(biāo),它不需要考慮具體的設(shè)備類型,其中面向的對象是設(shè)備環(huán)境,在內(nèi)存中建立的一種虛擬坐標(biāo)系。雖然邏輯坐標(biāo)的取值同設(shè)備坐標(biāo)一樣都是整數(shù),但是采用的坐標(biāo)單位是不同的,而且坐標(biāo)軸的方向也是隨著映射模式的改變而不同。在矢量圖形系統(tǒng)中,應(yīng)根據(jù)實(shí)際需要使用特定的邏輯坐標(biāo)系。 邏輯坐標(biāo)和設(shè)備坐標(biāo)一起為Windows提供了設(shè)備無關(guān)性,設(shè)備無關(guān)性指的是只要設(shè)定了映射模式,不管是在何種輸出設(shè)備上,一個圖形顯示出同樣的效果。但對于MM_TEXT映射模式來說,因?yàn)槠渥鴺?biāo)單位是像素,而一個像素所占的實(shí)際長度隨著設(shè)備的不同而不同,長度是不固定的,所以在不同的輸出設(shè)備上不能保證所顯示圖形的大小相同。 設(shè)備坐標(biāo)系和邏輯坐標(biāo)系均是由Windows系統(tǒng)定義的,因此統(tǒng)稱為Windows坐標(biāo)系3]。Windows下列圖形的繪制是在邏輯坐標(biāo)系中進(jìn)行的,用戶在各種繪圖設(shè)備上的繪制操作使用的是邏輯坐標(biāo)值,然后Windows再根據(jù)所設(shè)定的映射模式,將邏輯坐標(biāo)值轉(zhuǎn)換成設(shè)備坐標(biāo)值,最后將圖形輸出到實(shí)際的顯示設(shè)備或打印設(shè)備上。設(shè)備坐標(biāo)及邏輯坐標(biāo)的轉(zhuǎn)換Windows下的繪圖是在邏輯坐標(biāo)系中進(jìn)行的,而任何圖形的顯示和輸出都必須在一定的設(shè)備上實(shí)現(xiàn),因此,在圖形系統(tǒng)的開發(fā)中,邏輯坐標(biāo)到設(shè)備坐標(biāo)的轉(zhuǎn)換常被大量用到。另外,當(dāng)系統(tǒng)和用戶之間進(jìn)行交互時,系統(tǒng)需要知道用戶輸入焦點(diǎn)的位置坐標(biāo),而這個坐標(biāo)是設(shè)備坐標(biāo),必須將其轉(zhuǎn)換為邏輯坐標(biāo)后才能進(jìn)行識別和操作。 邏輯坐標(biāo)與設(shè)備坐標(biāo)轉(zhuǎn)換之前,首先要對映射模式進(jìn)行設(shè)置,也就是要確立系統(tǒng)開發(fā)所采用的邏輯坐標(biāo)系。在MFC中,不同的映射模式其對應(yīng)的邏輯坐標(biāo)單位是不同的,設(shè)定了映射模式,就規(guī)定了邏輯單位的大小和增量的方式。所以實(shí)現(xiàn)邏輯坐標(biāo)與設(shè)備坐標(biāo)轉(zhuǎn)換的第一步就是確定系統(tǒng)所使用的映射模式14]。 在MFC應(yīng)用程序中可以通過調(diào)用CDC類的函數(shù)SetMapMode(intnMapMode)來設(shè)置,其中參數(shù)nMapMode代表的即是表1中的映射模式識別碼,用來指定新的映射模式,可以取Windows八種映射模式中的任意一種。 本系統(tǒng)在視圖類CMapView的OnDraw函數(shù)中設(shè)置映射模式如下:pDC->SetMapMode(MM_TEXT); 為了完成Windows各種映射模式下從邏輯坐標(biāo)到設(shè)備坐標(biāo)的轉(zhuǎn)換,VC++提供了兩個轉(zhuǎn)換功能函數(shù):DPtoLP(LPPOINTlpPoints)//從設(shè)備坐標(biāo)到邏輯坐標(biāo)的轉(zhuǎn)換LPtoDP(LPPOINTlpPoints)//從邏輯坐標(biāo)到設(shè)備坐標(biāo)的轉(zhuǎn)換3.3窗口與視口 窗口是虛擬存在的一個屏幕視口〔也稱視圖〕是設(shè)備坐標(biāo)系〔通常屏幕〕中定義的一個矩形區(qū)域,就是在屏幕上看到的視圖客戶區(qū),即繪圖的區(qū)域,用來確定顯示內(nèi)容,窗口是圖形的可見局部。窗口的坐標(biāo)是邏輯坐標(biāo),與設(shè)備無關(guān)5]。視口是與設(shè)備相關(guān)的一個矩形區(qū)域,坐標(biāo)單位是與設(shè)備相關(guān)的。視口決定了窗口中的圖形顯示在屏幕上的位置和大小。窗口坐標(biāo)的原點(diǎn)與視口坐標(biāo)的原點(diǎn)始終對應(yīng)于同一點(diǎn)。 窗口和視口的劃分與Windows下列圖形繪制的機(jī)制有關(guān)。Windows下的繪圖并不是把圖形直接繪制到設(shè)備屏幕上,而是先在Windows預(yù)先定義好的坐標(biāo)系統(tǒng)〔映射模式〕中選擇一個作為繪圖參考系,在此映射模式下將圖形繪制到虛擬的內(nèi)存窗口中去。然后再將窗口中的圖形映射到視口中。如果映射到屏幕上就實(shí)現(xiàn)了圖形的顯示;如果映射到打印機(jī)等輸出設(shè)備上就實(shí)現(xiàn)了圖形的打印輸出。 窗口原點(diǎn)和視口原點(diǎn)指的是同一點(diǎn)分別在窗口坐標(biāo)系和視口坐標(biāo)系中的坐標(biāo)值,它們決定了圖形由窗口映射到視口時的相對位置。3.4本章小結(jié)要實(shí)現(xiàn)矢量圖形的繪制、顯示及無級縮放等功能,首先要確立和實(shí)現(xiàn)矢量圖形系統(tǒng)所采用的坐標(biāo)系,坐標(biāo)系是整個圖形系統(tǒng)開發(fā)的根底。本系統(tǒng)建立了自己的圖形坐標(biāo)系,稱之為實(shí)際坐標(biāo)系,來維護(hù)矢量數(shù)據(jù)的地理坐標(biāo),并實(shí)現(xiàn)了實(shí)際坐標(biāo)與Windows坐標(biāo)——邏輯坐標(biāo)和設(shè)備坐標(biāo)的相互轉(zhuǎn)換。因此本章對矢量圖形系統(tǒng)坐標(biāo)系的建立過程及其與Windows坐標(biāo)系的相互關(guān)系進(jìn)行了介紹,并對設(shè)備坐標(biāo)與實(shí)際坐標(biāo)的轉(zhuǎn)換方法進(jìn)行了闡述,最后還簡單的介紹了窗口與視口及其他們之間的關(guān)系。第四章實(shí)現(xiàn)矢量圖形系統(tǒng)的文檔和視圖4.1矢量圖形系統(tǒng)的圖形元素類 面向?qū)ο蟮某绦蛟O(shè)計(jì),是目前程序設(shè)計(jì)的主流方法,在本設(shè)計(jì)中,將利用面向?qū)ο蟮某绦蛟O(shè)計(jì)和C++類的組織方法,組織建立一個根本矢量圖形的圖形元素類。組織實(shí)現(xiàn)的矢量圖形系統(tǒng),能夠處理點(diǎn)類、線類、面類等類別的圖形元素,其中點(diǎn)類圖形元素有包括直線,圓,圓弧,標(biāo)注文本等圖形元素,針對每類圖形元素組織建立起對其進(jìn)行管理的C++類,并把每個圖形元素作為一個獨(dú)立的對象來管理。圖形元素基類對各類圖形元素進(jìn)行分析,可以發(fā)現(xiàn)各類圖形元素具有一些相同的屬性和操作功能,如圖形元素的顏色、線型線寬所在層等屬性和得到一個圖形元素是否做了刪除標(biāo)志等操作。把這些圖形元素中共性的東西〔屬性和操作〕,組織存放在一個圖形元素基類(CDraw)中,具體的圖形元素由這個基類來派生。直線類直線類Cline是從CDraw派生而來,在直線類的構(gòu)造函數(shù)中,共有包括11個參數(shù),并利用前7個參數(shù)從CDraw派生而來,并在構(gòu)造函數(shù)中對其余的四個參數(shù)〔直線的起點(diǎn)與終點(diǎn)〕進(jìn)行了初始化。用來標(biāo)識直線類的特殊屬性,也在類中進(jìn)行了定義。連續(xù)直線或封閉多邊形類連續(xù)直線除了具有圖形元素基類所具有的屬性外,從圖形的幾何特征上,連續(xù)直線是由很多頂點(diǎn)組成的,而且頂點(diǎn)數(shù)目是不確定的。一條連續(xù)直線可能只有兩個頂點(diǎn),也可能有幾千個頂點(diǎn)。所以,需要定義一個結(jié)構(gòu)來存儲連續(xù)直線的一個頂點(diǎn)坐標(biāo)。定義一個成員變量m_Numble用來記錄點(diǎn)的個數(shù),定義一個b_Fill來標(biāo)識是連續(xù)直線還是封閉多邊形。圓類 對圓類CCircle的創(chuàng)立方法與直線類CLine類似,圓除了具有圖形元素的根本特征外,還有自身的幾何特性。在CCircle類中定義了m_CircleX,m_CircleY,m_CircleR用來記錄圓心與圓的半徑,并定義了b_Fill用來標(biāo)識此圖形元素是圓還是圓形區(qū)域。圓弧類圓是圓弧的一個特例,當(dāng)圓弧的弧度等于2時就是圓。所以可以從一個圓類派生得到一個圓弧類。在圓弧類中定義了m_Angle1,m_Angle2用來表示圓弧的起始弧度與終點(diǎn)的弧度。標(biāo)注文本類矢量圖形中可以有大量的標(biāo)注文本,標(biāo)注文本除了具有圖形元素的根本特性外,還具有位置、字體及標(biāo)注內(nèi)容等自身的信息。CText類也有兩個構(gòu)造函數(shù),第二個構(gòu)造參數(shù)有多個參數(shù),并利用多個參數(shù)對類的成員變量進(jìn)行初始化。在構(gòu)造函數(shù)中,調(diào)用了基類CDraw的構(gòu)造函數(shù)對基類CDraw的成員變量進(jìn)行初始化。圖形參數(shù)類在矢量圖形系統(tǒng)中,圖形參數(shù)是集中存儲的。在圖形元素基類中成員變量m_ColorPen,m_ColorBrush分別用來存儲畫筆的顏色與畫刷的顏色序號,m_Layer中存儲的是在圖層列表中的序列號。用m_ColorList,m_LayerList兩個數(shù)組來分別存儲顏色和涂層,并在構(gòu)造函數(shù)中進(jìn)行初始化。4.2矢量圖形系統(tǒng)的文檔面向?qū)ο蟮奈臋n管理機(jī)制管理矢量圖形系統(tǒng)圖形數(shù)據(jù)的方法即文檔管理機(jī)制。在本設(shè)計(jì)的開發(fā)中,采用一套完全面向?qū)ο蟮奈臋n組織機(jī)制。這種機(jī)制就是通過圖形元素類創(chuàng)立很多圖形元素對象,每個圖形元素對象作為一個整體來組織存儲空間的分配、存取等各種管理功能。然后通過建立一種存儲機(jī)制,來管理指向所有圖形元素對象的指針,到達(dá)管理所有圖形元素對象的目的。這種文檔管理機(jī)制具有組織簡單結(jié)構(gòu)化和移植性好,以及比擬容易利用VC++程序設(shè)計(jì)語言的開發(fā)功能等優(yōu)點(diǎn)。缺點(diǎn)是需要較大的內(nèi)存空間。創(chuàng)立圖形元素對象指針管理一個矢量圖形系統(tǒng)文檔的思路是:每個圖形元素是圖形元素類創(chuàng)立的一個對象,在創(chuàng)立這個對象時得到指向這個對象的指針,建立一個對象指針數(shù)組來管理這些指針,以到達(dá)管理所有圖形元素對象的目的。 在VC++下可以較容易地實(shí)現(xiàn)對指向圖形元素對象的指針的組織和管理。在MFC中有一個類模板CTypedPtrArray,可以用它來創(chuàng)立一個管理類指針的對象。例如,可以定義一個管理CLine類指針的對象如下:CTypedPtrArray<CObArray,Cline*>m_LineArray;矢量圖形系統(tǒng)的文檔在應(yīng)用程序Draw中,可以派生幾個CObArray對象來分別管理基類圖形元素。在文檔類CDrawDoc中創(chuàng)立用來管理各類圖形元素的對象指針,創(chuàng)立的CObArray對象如下: private: CTypedPtrArray<CObArray,CLine*>m_LineArray; //管理直線對象指針的對象 CTypedPtrArray<CObArray,CPline*>m_PLineArray;//管理連續(xù)直線對象指針對象 CTypedPtrArray<CObArray,CCircle*>m_CircleArray;//管理圓對象指針的對象 CTypedPtrArray<CObArray,CArc*>m_ArcArray; //管理圓弧對象指針的對象 CTypedPtrArray<CObArray,CText*>m_TextArray; //管理文字對象指針的對象實(shí)現(xiàn)文檔的管理功能⑴增加圖形元素。在應(yīng)用程序Draw中增加一個圖形元素對象〔如一條直線〕時,需要進(jìn)行以下兩個步驟的操作:首先需要創(chuàng)立一個圖形元素對象,并用圖形元素的實(shí)際數(shù)據(jù)初始化這個圖形元素對象。如增加一條直線時,需要創(chuàng)立一個CLine對象,并用這條直線的實(shí)際數(shù)據(jù)〔起終點(diǎn)、所在圖層、顏色等〕初始化這個CLine對象的成員變量。然后需要把指向新創(chuàng)立的圖形元素對象的指針,增加到文檔類中管理圖形元素對象指針的對象中。如增加一條CLine對象后,需要把指向這個CLine對象的指針增加到文檔類的m_LineArray對象中。 為了實(shí)現(xiàn)增加各類圖形元素的功能,在文檔類CDrawDoc中定義幾個函數(shù),分別來完成增加各類圖形元素的操作功能 CLine*AddLine(shortColorPen,shortColorBrush,floatLineWide,shortLineType,shortLayer,intid_only,floatX1,floatY1,floatX2,floatY2); CCircle*AddCircle(shortColorPen,shortColorBrush,floatLineWide,shortLineType,shortLayer,intid_only,floatCircleX,floatCircleY,floatCircleR,BOOLbFill); CArc*AddArc(shortColorPen,shortColorBrush,floatLineWide,shortLineType,shortLayer,intid_only,floatCircleX,floatCircleY,floatCircleR,floatAngle1,floatAngle2); CText*AddText(shortColorPen,shortColorBrush,floatLineWide,shortLineType,shortLayer,intid_only,floatStartX,floatStartY,floatAngle1,floatAngle2,floatTextHeight,floatTextWide,floatOffWide,unsignedcharTextFont,intTextLong,CStringText); CTag*AddTag(shortColorPen,intLayer,floatxInsert,floatyInsert,floatxScale,floatyScale,floatangle,intonly_id,intidBlock); CPline*AddPLine(shortColorPen,shortColorBrush,floatLineWide,shortLineType,shortLayer,intid_only,intNumble,PointStruct*PointList); 這6個函數(shù)分別用來實(shí)現(xiàn)增加一條直線、一個圓、一個圓弧、一個標(biāo)注文本、一條連續(xù)直線或一個多邊形區(qū)域的功能。函數(shù)返回指向新增圖形元素對象的指針。⑵實(shí)現(xiàn)對圖形元素的操作。為了實(shí)現(xiàn)對圖形元素的操作,為此,在文檔類CDrawDoc中定義一些Public成員函數(shù),并在實(shí)現(xiàn)文件drawdoc.cpp中,參加函數(shù)的具體實(shí)現(xiàn)代碼。函數(shù)具體定義如下:CDraw*GetGraph(shortLb,intindex);//得到指向圖形元素對象的指針VoidDeleteGraph(shortLb,intindex);//刪除圖形元素對象IntGetGraphNumb(shortLb);//各類圖形元素的數(shù)目IntGetGraphUpperBound(shortLb);//存儲各類圖形元素CObArray對象數(shù)組的最大下標(biāo)IntGetGraphIndex(shortLb,intID);//某個識別號的圖形元素對象指針在CObArray數(shù)組中的存放位置4.3矢量圖形系統(tǒng)的視圖建立坐標(biāo)系⑴建立坐標(biāo)系 該坐標(biāo)系取屏幕的左下角點(diǎn)作為圖形屏幕的基點(diǎn)。客戶區(qū)的左下角的坐標(biāo)定義為(m_xStart,m_yStart),并確定一個變量blc作為邏輯坐標(biāo)和實(shí)際坐標(biāo)的比例關(guān)系。⑵實(shí)際坐標(biāo)與邏輯坐標(biāo)的轉(zhuǎn)換 為了實(shí)現(xiàn)實(shí)際坐標(biāo)與邏輯坐標(biāo)的轉(zhuǎn)換,在視圖類CDrawDoc中定義如下的四個轉(zhuǎn)換函數(shù): Public: VoidDPtoVP(floatx,floaty,int*X,int*Y); VoidVPtoDP(intx,inty,float*X,float*Y); IntDLtoVL(floatl); FloatVLtoDL(intl); 函數(shù)VPtoDP用來將邏輯坐標(biāo)轉(zhuǎn)換成實(shí)際坐標(biāo),參數(shù)(x,y)是一個點(diǎn)的邏輯坐標(biāo),參數(shù)(*X,*Y)返回轉(zhuǎn)換后的實(shí)際坐標(biāo)值。 函數(shù)DLtoVL用來將實(shí)際坐標(biāo)長度轉(zhuǎn)換成邏輯坐標(biāo)長度,參數(shù)l是一個實(shí)際坐標(biāo)長度,函數(shù)返回邏輯坐標(biāo)表示的長度值。 四個轉(zhuǎn)換函數(shù)中用到的成員變量,在視圖類CDrawView中定義: Privated: Floatm_xStart,m_yStart,blc; Intm_wScreen,m_hScreen; 為了在應(yīng)用程序Draw的其他類中能夠使用四個坐標(biāo)轉(zhuǎn)換函數(shù),可以將四個轉(zhuǎn)換函數(shù)定義成四個全局函數(shù)來實(shí)現(xiàn)轉(zhuǎn)換操作功能,在實(shí)現(xiàn)文件drawview.cpp中,定義四個全局函數(shù)。且四個全局函數(shù)利用視圖類指針p_View調(diào)用視圖類的四個坐標(biāo)轉(zhuǎn)換函數(shù),來完成坐標(biāo)和長度的轉(zhuǎn)換功能,p_View指向當(dāng)前激活的視圖對象。如果在某個實(shí)現(xiàn)文件中使用這四個全局轉(zhuǎn)換函數(shù),只需在這個實(shí)現(xiàn)文件中的開始處參加全局函數(shù)的外部引用。實(shí)現(xiàn)各類圖形元素的繪制功能利用虛函數(shù)實(shí)現(xiàn)各種圖形元素的繪制功能。在圖形元素基類CDraw中,抽象定義一個進(jìn)行繪制操作的虛函數(shù)。因?yàn)樵趹?yīng)用程序Draw中,不用CDraw類直接來創(chuàng)立對象,所以可以將虛函數(shù)定義成純虛函數(shù): VirtualvoidDraw(CDC*pDC,intm_DrawMode,intm_DrawModel,shortBackColor)=0;在各種圖形元素類CLineCCircleCArcCTextCTagCPlineCPlineRgnCLinkNet中,重載虛函數(shù)Draw:virtualvoidDraw(CDC*pDC,intm_DrawMode,intm_DrawModel,shortBackColor);實(shí)現(xiàn)視圖的繪制 為了實(shí)現(xiàn)應(yīng)用程序Draw的圖形繪制工作,在文檔類CDrawDoc中定義Draw函數(shù)如下: voidDraw(CDC*pDC,intm_DrawMode,intm_DrawModel,shortBackColor);4.4鼠標(biāo)交互繪圖要解決的主要問題⑴捕獲鼠標(biāo)操作消息 VC++提供了足夠的窗口消息和已經(jīng)保護(hù)的消息處理函數(shù)解決這個問題.在應(yīng)用程序Draw中實(shí)現(xiàn)鼠標(biāo)交互繪制圖形元素時,將主要用到以下三個鼠標(biāo)操作: OnMouseMove(UINTnFlags,CPointpoint)WM_MOUSEMOVE//鼠標(biāo)移動 OnRButtonDown(UINTnFlags.CPointpoint)WM_RBUTTONDOWN//按下右鍵 OnLButtonDown(UINTnFlags.CPointpoint)WM_LBUTTONDOWN//按下左鍵⑵捕捉所有的鼠標(biāo)輸入 在用鼠標(biāo)交互繪制一個圖形元素時,在已經(jīng)開始繪圖的情況下,不希望還能進(jìn)行別的操作,以防止造成系統(tǒng)流程和變量初始化等方面的錯誤.VC++提供了兩個成員函數(shù)來滿足以上的功能需求: CWnd::SetCapture(); CWnd::ReleaseCapture();⑶在屏幕上拖動圖形 在用鼠標(biāo)交互繪制圖形元素時,為了直觀的看到所繪制的圖形,一般采用拖動圖形的方法;⑷保存圖形數(shù)據(jù)到文檔 用鼠標(biāo)在屏幕上交互繪制的圖形元素,要創(chuàng)立一個圖形元素對象并將指向這個圖形元素對象的指針保存起來;⑸將圖形以實(shí)際的形態(tài)重畫 用鼠標(biāo)交互繪制一個圖形元素后,要在屏幕上馬上顯示出這個圖形元素的實(shí)際形態(tài),必須將圖形元素以實(shí)際的形態(tài)重畫。在矢量圖形系統(tǒng)設(shè)計(jì)中,一般采用CClientDC對象,在交互繪制圖形元素操作完成后,即時在視圖中重畫這個新增的圖形元素。交互繪制各類圖形元素本設(shè)計(jì)主要實(shí)現(xiàn)交互繪制直線、圓、填充圓、圓弧、標(biāo)注文本、連續(xù)直線、多邊形區(qū)域的實(shí)現(xiàn)過程.⑴增加菜單資源. 在應(yīng)用程序Draw的菜單資源中,增加一個菜單〞鼠標(biāo)繪圖〞,.在這個菜單中包含直線、圓、填充圓、圓弧、標(biāo)注文本、連續(xù)直線及多邊形區(qū)域菜單項(xiàng)。參加的菜單如圖4-1所示:圖4-1鼠標(biāo)繪圖菜單⑵為每個操作添加消息處理函數(shù) 選中其中的一個菜單項(xiàng),單擊鼠標(biāo)右鍵,選擇“建立類向?qū)А?,在Classname中選擇CDrawView,在Messages中選擇COMMAND,點(diǎn)擊AddFunction,即可為菜單先增加一個響應(yīng)函數(shù)。點(diǎn)擊Edit即可在實(shí)現(xiàn)文件drawview.cpp中增加消息處理函數(shù)的實(shí)現(xiàn)代碼.操作界面如圖4-2所示:圖4-2MFCClassWisard獲得圖形元素的唯一識別號: 在一個矢量圖形系統(tǒng)中,對于任何一個圖形元素,必須有一個能夠與其他圖形元素區(qū)分開來的屬性,因此,在此系統(tǒng)中,在Draw類中為每類圖形元素創(chuàng)立一個惟一識別號變量m_id_only.為了得到每類圖形元素的識別號,在CDrawDoc中定義一個成員函數(shù)GetGraphID來實(shí)現(xiàn)。具體函數(shù)定義如下: intGetGraphID(shortLb).其中參數(shù)Lb用來表示圖形類別,具體的實(shí)現(xiàn)代碼在drawdoc.cpp文件中。當(dāng)單擊標(biāo)注文本時出現(xiàn)文本對話框如圖4-3:圖4-3標(biāo)注信息窗口當(dāng)單擊字體參數(shù)時出現(xiàn)的對話框如圖4-4:圖4-4標(biāo)注字體參數(shù)4.5本章小結(jié)本章主要是對直線、連續(xù)直線及封閉多邊形區(qū)域、圓、圓弧、標(biāo)注文本等根本的圖形元素的數(shù)據(jù)組織和繪制方法做了簡單的介紹,并對具體的實(shí)現(xiàn)過程也做了簡要的概述。對于鼠標(biāo)繪圖操作的完成提供了有效的方法。第五章矢量圖形系統(tǒng)的操作功能5.1圖形操作菜單管理增加菜單資源 在應(yīng)用程序Draw的菜單資源中,增加“圖形操作〞及“圖形選中〞兩個菜單,.并分別在兩個菜單下參加菜單項(xiàng)如圖5-1與圖5-2所示:圖5-1圖形操作菜單圖5-2圖形選中菜單添加消息處理函數(shù)按照4.3節(jié)中介紹的方法為兩個菜單下的所有菜單項(xiàng)添加消息處理函數(shù)。添加后,可以在視圖類CDrawView中找到如下定義:afx_msgvoidOnGraphRedraw();afx_msgvoidOnGraphZoom(); afx_msgvoidOnGraphSmall();afx_msgvoidOnGraphPan();afx_msgvoidOnGraphUp();afx_msgvoidOnGraphFirst();afx_msgvoidOnGraphAll();可以在視圖類drawView.cpp中找到如下定義: ON_COMMAND(ID_GRAPH_REDRAW,OnGraphRedraw) //圖形重畫 ON_COMMAND(ID_GRAPH_ZOOM,OnGraphZoom) //圖形放大 ON_COMMAND(ID_GRAPH_SMALL,OnGraphSmall)//圖形縮小 ON_COMMAND(ID_GRAPH_PAN,OnGraphPan) //圖形搖動 ON_COMMAND(ID_GRAPH_UP,OnGraphUp) //重畫上屏 ON_COMMAND(ID_GRAPH_FIRST,OnGraphFirst) //重畫首屏 ON_COMMAND(ID_GRAPH_ALL,OnGraphAll) //重畫全屏 ON_COMMAND(ID_SELECT_MOUSE,OnSelectMouse)//圖形選中 ON_COMMAND(ID_SELECT_CLEAR,OnSelectClear) //放棄選中 ON_COMMAND(ID_SELECT_DELETE,OnSelectDelete)//刪除選中圖形5.2圖形操作的具體實(shí)現(xiàn)圖形重畫所謂圖形重畫,就是把當(dāng)前視圖屏幕重新繪制一次,實(shí)際上也就是讓視圖類的函數(shù)OnDraw(CDC*pDC)重新執(zhí)行一次。根據(jù)需要重畫區(qū)域的不同,圖形重畫可以分為全屏重畫和局部重畫。⑴全屏重畫 在有些情況下,需要將當(dāng)前視圖屏幕全屏重畫。全屏重畫有兩種方法,一種是使用函數(shù)UpdateAllViews,使屬于當(dāng)前文檔對象的所有視圖重畫。另外一種方法即是用函數(shù)Invalidate,使當(dāng)前視圖屏幕的客戶區(qū)失效,從而激活圖形重畫。兩種方法的不同點(diǎn)為:Invalidate函數(shù)它只能使當(dāng)前視圖重畫,而與其同文檔的其他視圖并不重畫。對視圖類CDrawView的OnGraphRedraw函數(shù)進(jìn)行修改。具體代碼如下:VoidCDrawView::OnGraphRedraw() { CDrawDoc*pDoc=GetDocument(); pDoc->UpdateAllViews(this); Invalidate(); } OnGraphRedraw函數(shù)首先得到指向當(dāng)前文檔對象的指針,然后調(diào)用UpdateAllViews函數(shù)重畫此文檔對象所有的視圖,參數(shù)this是指向當(dāng)前視圖對象的指針。⑵局部重畫 如果只希望將當(dāng)前視圖屏幕的一局部區(qū)域重畫,即進(jìn)行局部重畫。在VC++中,Invalidate與RectInvalidateRgn兩個函數(shù)可以完成此功能。兩個函數(shù)的定義如下:VoidInvalidateRect(LPCRECTlpRect,BOOLbErase=TRUE); //lpRect中存儲著視圖中需要重畫的區(qū)域,參數(shù)bErase用于指定當(dāng)區(qū)域重畫時,背景是否擦除voidInvalidateRgn(CRgn*pRgn,BOOLbErase=TRUE);圖形放大和移動1.圖形放大 圖形放大指的是通過調(diào)整視圖屏幕,使當(dāng)前視圖屏幕中的一局部區(qū)域放大顯示到整個視圖屏幕中15]。矢量圖形系統(tǒng)應(yīng)具有無級放縮的功能。所謂“無級〞,指的是圖形能以任何的比例進(jìn)行顯示。在應(yīng)用程序Draw已經(jīng)建立的坐標(biāo)系根底上,可以很容易實(shí)現(xiàn)圖形的無級放大。實(shí)現(xiàn)圖形放大的操作方法很多:如可以進(jìn)行固定比例的圖形放大;再如可以通過窗口放大。本設(shè)計(jì)將涉及到用窗口放大圖形的操作方法和具體實(shí)現(xiàn)步驟。在此根底上,可以輕而易舉的實(shí)現(xiàn)其他方法的圖形放大操作功能。實(shí)現(xiàn)圖形放大、移動后的效果圖分別如圖5-3、圖5-4所示:圖5-3圖形繪制〔放大前〕圖5-4圖形繪制〔放大后〕2.圖形移動 圖形移動指的是將圖形元素在橫向和縱向上移動一定的偏移量,得到移動后圖形元素的坐標(biāo)。圖形移動操作功能的機(jī)理非常簡單,只需將各類圖形元素的特征點(diǎn)做相應(yīng)的坐標(biāo)移動即可。⑴各類圖形元素的移動操作 為了實(shí)現(xiàn)圖形元素的移動功能,同樣需要在圖形元素基類CDraw中定義一個純虛函數(shù):virtualvoidMove(floatx_Move,floaty_Move)=0; 在各個圖形元素類中增加這個虛函數(shù)的重載定義,在各個圖形元素類的實(shí)現(xiàn)文件中,參加這個重載函數(shù)的實(shí)現(xiàn)代碼。⑵實(shí)現(xiàn)圖形移動操作功能 圖形移動功能的操作步驟如下:首先用“鼠標(biāo)點(diǎn)中〞操作選中要移動的圖形元素,按下鼠標(biāo)左鍵點(diǎn)中移動操作的基點(diǎn),再按下鼠標(biāo)左鍵點(diǎn)中移動操作的目標(biāo)點(diǎn),各個圖形元素將以這兩個點(diǎn)為根底進(jìn)行相對移動。在OnEditMove函數(shù)中,對圖形移動操作進(jìn)行了標(biāo)識,為了實(shí)現(xiàn)具體的移動操作,需要對各個鼠標(biāo)消息處理函數(shù)進(jìn)行修改。在實(shí)現(xiàn)文件drawview.cpp的消息處理函數(shù)OnLButtonDow、OnMouseMoven、OnRButtonDown中參加相應(yīng)的實(shí)現(xiàn)代碼。圖形移動的效果圖如圖5-5、圖5-6所示:圖5-5圖形繪制〔移動前〕圖5-6圖形繪制〔移動后〕重畫上屏和重畫首屏圖形經(jīng)過放大、移動操作后,還要有把圖形屏幕再恢復(fù)到前一屏幕〔重畫上屏〕或者直接使圖形回到第一屏〔重畫首屏〕的功能。要實(shí)現(xiàn)重畫上屏和重畫首屏的功能,就需要記錄下每一屏幕的狀態(tài),并時刻跟蹤著當(dāng)前的狀態(tài)。記錄屏幕狀態(tài): 一個圖形屏幕是由三個參數(shù)來確定的:屏幕左下角原點(diǎn)的坐標(biāo)m_xStart、m_yStart和顯示比例blc,在文檔類CDrawDoc中定義一個結(jié)構(gòu)數(shù)組來存儲歷史圖形屏幕。在CDrawDoc類中定義以下幾個變量:Public: intm_CurrentScreen;//當(dāng)前屏幕的序號 intm_MaxScreen;//最多能存儲的屏幕數(shù) ScreenStruct*m_Screen;//記錄屏幕參數(shù)的結(jié)構(gòu)數(shù)組結(jié)構(gòu)ScreenStruct在頭文件drawdoc.h中CDrawDoc類定義前定義:Typedefstruct {Floatblc;//顯示比例Floatsx;//屏幕左下角橫坐標(biāo)Floatsy;//屏幕左下角縱坐標(biāo) }ScreenStruct;在文檔類CDrawDoc中定義一個函數(shù),來完成存儲一個圖形屏幕狀態(tài)的操作功能:Public:VoidAddScreen(floatStartX,floatStartY,floatblc); 在實(shí)現(xiàn)文件drawdoc.cpp中,參加函數(shù)的實(shí)現(xiàn)代碼。⑴重畫上屏 要實(shí)現(xiàn)重畫上屏操作功能,只需把m_CurrentScreen的值減去1,從結(jié)構(gòu)數(shù)組m_Screen中取出屏幕參數(shù)重畫圖形即可。在實(shí)現(xiàn)文件drawview.cpp中,將“重畫上屏〞菜單項(xiàng)的消息處理函數(shù)OnGraphUp的實(shí)現(xiàn)代碼修改如下:voidCDrawView::OnGraphUp(){CDrawDoc*pDoc=(CDrawDoc*)GetDocument();if(pDoc->m_CurrentScreen>0)//如果當(dāng)前不是首屏,當(dāng)前圖形屏幕序號減1pDoc->m_CurrentScreen--;//得到上一屏幕的圖形參數(shù)并重畫圖形m_xStart=p_Screen[pDoc->m_CurrentScreen].sx;m_yStart=p_Screen[pDoc->m_CurrentScreen].sy;blc=p_Screen[pDoc->m_CurrentScreen].blc;Invalidate();//重畫圖形}p_Screen是CDrawView類中定義的指向文檔對象中的結(jié)構(gòu)數(shù)組m_Screen的指針,它在 視圖類CDrawView中定義ScreenStruct*p_Screen; 在實(shí)現(xiàn)文件drawview.cpp中,在重載的虛函數(shù)OnActiveView中對p_Screen進(jìn)行初始化,將它指向當(dāng)前文檔對象中的結(jié)構(gòu)數(shù)組m_Screen:voidCDrawView::OnActivateView(BOOLbActivate,CView*pActivateView,CView*pDeactiveView){p_View=this;CDrawDoc*pDoc=(CDrawDoc*)GetDocument();p_Screen=pDoc->m_Screen;CView::OnActivateView(bActivate,pActivateView,pDeactiveView);}⑵重畫首屏 對于重畫首屏功能來說,只要取出存儲在結(jié)構(gòu)數(shù)組m_Screen中的首屏參數(shù),并對視圖重畫即可。修改實(shí)現(xiàn)文件drawview.cpp中的消息處理函數(shù)OnGraphFirst,得到實(shí)現(xiàn)代碼如下:voidCDrawView::OnGraphFirst()//重畫首屏{//TODO:AddyourcommandhandlercodehereCDrawDoc*pDoc=GetDocument();if(pDoc->m_CurrentScreen==0)return;m_xStart=p_Screen[0].sx;m_yStart=p_Screen[0].sy;blc=p_Screen[0].blc;pDoc->AddScreen(m_xStart,m_yStart,blc);Invalidate();}顯示全圖在矢量圖形系統(tǒng)中,隨著一些圖形元素通過外部接口或者系統(tǒng)本身的繪制功能的參加,圖形首屏可能包含不了所有的圖形元素;還有一種情況是,圖形中所有的圖形元素都在視圖屏幕的一個角上,只占圖幅的一小局部。這是就需要一個操作功能,調(diào)整視圖屏幕左下角原點(diǎn)的實(shí)際坐標(biāo)(m_xStart,m_yStart)和顯示比例blc,使所有的圖形元素正好能夠繪制到視圖屏幕中〔在屏幕上留有一局部邊界區(qū)域〕,顯示全圖功能就是為完成此功能而設(shè)置的。實(shí)現(xiàn)顯示全圖功能的思路是,通過得到每一類圖形元素〔如直線、連續(xù)直線〕的邊界矩形,然后根據(jù)視圖屏幕的大小〔邏輯坐標(biāo)〕進(jìn)行計(jì)算,得到屏幕的參數(shù)m_xStart,m_yStart,blc.所以,解決問題的關(guān)鍵在于得到各類圖形元素的邊界矩形。各類圖形元素的邊界矩形計(jì)算: 在圖形元素基類CDraw中定義一個純虛函數(shù):VirtualvoidGetRect(float*minx,float*minY,float*maxX,float*maxY)=0; 函數(shù)GetRect用來計(jì)算圖形元素的邊界矩形,〔*minX,*minY〕和〔*maxX,*maxY〕這四個指針參數(shù)用來返回邊界矩形的最小和最大坐標(biāo)。 在由CDraw類派生的各個圖形元素類中重載虛函數(shù)GetRect,即在各個類中參加以下定義代碼:VirtualvoidGetRect(float*minx,float*minY,float*maxX,float*maxY);并在各個圖形元素類中實(shí)現(xiàn)代碼,以完成計(jì)算各類圖形元素邊界矩形的功能。實(shí)現(xiàn)顯示全圖功能:⑴得到所有圖形元素的邊界矩形 把所有圖形元素的邊界矩形坐標(biāo)進(jìn)行比擬,就可以得到所有圖形元素的邊界矩形。為了實(shí)現(xiàn)這個功能,在文檔類CDrawDoc中定義一個Public函數(shù):BOOLGetRect(float*m_Xmin,float*m_Ymin,float*m_Xmax,float*m_Ymax); 指針參數(shù)用來返回邊界矩形的最小和最大坐標(biāo),當(dāng)能計(jì)算得到邊界矩形時,函數(shù)返回TRUE,否那么,函數(shù)返回FALSE.在實(shí)現(xiàn)文件drawdoc.cpp中,參加這個函數(shù)的實(shí)現(xiàn)代碼在函數(shù)GetRect中,首先對記錄最小值和最大值的變量初始化,然后對所有的直線連續(xù)直線圓圓弧標(biāo)注文本多邊形區(qū)域網(wǎng)絡(luò)點(diǎn)等類圖形元素進(jìn)行循環(huán),得到每個圖形元素的邊界矩形,并比擬運(yùn)算得到所有圖形元素的邊界矩形。當(dāng)至少有一個圖形元素時,函數(shù)返回TRUE,沒有任何圖形元素時,函數(shù)返回FALSE.⑵實(shí)現(xiàn)顯示全圖功能 在得到所有圖形元素的邊界矩形后,就可以調(diào)整視圖屏幕的基點(diǎn)和比例,使當(dāng)前視圖正好能夠繪制下所有的圖形元素。在實(shí)現(xiàn)文件drawview.cpp中,對菜單項(xiàng)“重畫全屏〞的消息處理函數(shù)OnGraphAll進(jìn)行修改:voidCDrawView::OnGraphAll(){//TODO:Addyourcommandhandlercodeherefloatminx,miny,maxx,maxy,bl1;CDrawDoc*pDoc=GetDocument();SetCapture();SetCursor(LoadCursor(NULL,IDC_WAIT));BOOLpb=pDoc->GetRect(&minx,&miny,&maxx,&maxy);SetCursor(LoadCursor(NULL,IDC_ARROW));ReleaseCapture();if(!pb)return;bl1=(maxx-minx)/(m_wScreen-20);blc=(maxy-miny)/(m_hScreen-20);if(bl1>blc)blc=bl1;m_xStart=minx-10*blc;m_yStart=miny-10*blc;p_Screen[0].sx=m_xStart;p_Screen[0].sy=m_yStart;p_Screen[0].blc=blc;pDoc->m_CurrentScreen=0;Invalidate();}圖形重畫速度的提升⑴提高圖形重畫速度的方法 一個根本的方法就是在顯示一個圖形元素前,對這個圖形元素進(jìn)行判斷,判斷這個圖形元素是否在視圖屏幕中,如果這個圖形元素不在當(dāng)前的視圖屏幕中,就不用對這個圖形元素進(jìn)行繪制,以此節(jié)省繪制時間。 我們采用的計(jì)算方法應(yīng)該是計(jì)算簡單且允許不太嚴(yán)密。這里所謂的不太嚴(yán)密,指的是用這種方法判斷是在視圖屏幕中的圖形元素,實(shí)際也可能不在視圖屏幕中,而經(jīng)過判斷不在視圖屏幕中的圖形元素一定不在視圖屏幕中。這種判斷一般采用這個圖形元素的邊界矩形和屏幕邊界矩形是否相交的方法。 在提高圖形重畫速度時,首先要得到視圖屏幕即客戶區(qū)的大小。在應(yīng)用程序Draw中,在視圖類CDrawView中有兩個變量m_hScreen和m_wScreen分別用來存儲當(dāng)前視圖的高度和寬度〔邏輯坐標(biāo)〕。在進(jìn)行圖形繪制前,把視圖屏幕矩形有邏輯坐標(biāo)轉(zhuǎn)換成實(shí)際坐標(biāo)。定義以下四個全局變量,用來傳遞要繪制視圖的左下角和右上角的實(shí)際坐標(biāo)。在實(shí)現(xiàn)文件drawdoc.cpp中,增加全局變量的定義:FloatxMinScreen,yMinScreen,xMaxScreen,yMaxScreen;為了在實(shí)現(xiàn)文件drawview.cpp中使用這些變量,在實(shí)現(xiàn)文件drawview.cpp中增加對這些全局變量的引用:ExternfloatxMinScreen,yMinScreen,xMaxScreen,yMaxScreen這四個全局變量在每次調(diào)用OnDraw函數(shù)實(shí)現(xiàn)視圖的繪制功能前被初始化。在實(shí)現(xiàn)文件drawview.cpp中的繪制函數(shù)CDrawView::OnDraw(CDC*pDC)中參加代碼,實(shí)現(xiàn)在每次繪制前得到視圖屏幕邊界的實(shí)際坐標(biāo):voidCDrawView::OnDraw(CDC*pDC){CDrawDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);//TODO:adddrawcodefornativedataherexMinScreen=m_xStart;yMinScreen=m_yStart;xMaxScreen=xMinScreen+blc*m_wScreen;yMaxScreen=yMinScreen+blc*m_hScreen;DrawBack(pDC);pDoc->Draw(pDC,0,0,m_bColor);m_MapMode=pDC->SetMapMode(1);}這樣在以當(dāng)前的屏幕參數(shù)〔m_xStart,m_yStart,blc〕繪制圖形前,把視圖屏幕的左下角和右上角的實(shí)際坐標(biāo)計(jì)算出來。 為判斷一個矩形區(qū)域與視圖屏幕矩形是否相交,在drawdoc.cpp中定義一個全局函數(shù):BOOLIsRectCross(floatminx,floatminy,floatmaxx,floatmaxy);函數(shù)的實(shí)現(xiàn)代碼如下:BOOLIsRectCross(floatminx,floatminy,floatmaxx,floatmaxy){if(minx>xMaxScreen||maxx<xMinScreen||miny>yMaxScreen||maxy<yMinScreen) returnFALSE;//如兩個矩形不相交else returnTRUE;}IsRectCross函數(shù)在一個矩形區(qū)域與視圖屏幕區(qū)域相交時返回TRUE,否那么返回FALSE.⑵提高圖形元素的繪制速度 對各類圖形元素的繪制函數(shù)Draw進(jìn)行修改,使其能夠先判斷圖形元素的邊界矩形是否與圖形屏幕區(qū)域相交,來決定是否需要對圖形元素進(jìn)行繪制。在直線類CLine的繪制函數(shù)Draw中,參加完整實(shí)現(xiàn)代碼,對于CCircle、CArc、CText、CPline、CPlineRgn、CTag、CLinkNet等圖形元素類,同樣也需要在其繪制函數(shù)Draw中參加相同的代碼。5.3圖形的點(diǎn)選與撤銷鼠標(biāo)點(diǎn)選圖形元素為了實(shí)現(xiàn)圖形的刪除和恢復(fù)等操作功能,首先應(yīng)該在矢量圖形系統(tǒng)中實(shí)現(xiàn)圖形的選中操作。對于一個矢量圖形系統(tǒng)來說,不但要能夠?qū)崿F(xiàn)交互圖形繪制、放縮操作等,還應(yīng)有一項(xiàng)根本的功能,就是能夠選中圖形元素。選中圖形元素是對圖形進(jìn)行修改刪除直接從圖形上得到信息〔在GIS中〕,以及在GIS中實(shí)現(xiàn)空間統(tǒng)計(jì)和分析功能等操作的根底。各種圖形元素的選中區(qū)域:⑴直線和連續(xù)直線 因?yàn)橹本€是沒有寬度的,所以,這種選中判斷實(shí)際上是要判斷一個點(diǎn)與一條直線的距離是否在一定的距離范圍之內(nèi)。問題的實(shí)質(zhì)就是,如何確定這個判斷選中的距離范圍和怎樣計(jì)算一個點(diǎn)與一條直線的距離。點(diǎn)與直線距離的計(jì)算方法 為了完成計(jì)算點(diǎn)到直線距離的功能,需要定義一個函數(shù),為了在直線和連續(xù)直線類中都能夠使用這個函數(shù),在圖形元素基類CDraw中定義一個Public函數(shù):floatPointLine(floatxx,floatyy,floatx1,floaty1,floatx2,floaty2);函數(shù)的參數(shù)分別是選中點(diǎn)與直線兩個頂點(diǎn)的實(shí)際坐標(biāo),函數(shù)返回計(jì)算得到的距離值。在實(shí)現(xiàn)文件draw.cpp中,參加函數(shù)實(shí)現(xiàn)代碼。在上述函數(shù)中,調(diào)用了一個在CDraw類中定義的計(jì)算兩點(diǎn)距離的函數(shù)CalDisp,:FloatCalDisp(floatx1,floaty1,floatx2,floaty2);⑵圓和填充圓 圓的選中區(qū)域非常簡單,如果有效距離為j1,計(jì)算得到的鼠標(biāo)按中點(diǎn)到圓心的距離為jl1;選中區(qū)域就是: |jl1-circle.r|<jl;即按中點(diǎn)到圓的距離小于jl.對于填充圓,選中區(qū)域那么是:Jl1<=jl;⑶圓弧 圓弧的選中區(qū)域同圓類似,首先要確定按中點(diǎn)是否在圓弧所在的圓上。即按中點(diǎn)到圓心的距離jl1符合: |jl1-circle.r|<jl;因?yàn)閳A弧不是封閉的,還要確定按中點(diǎn)相對于圓心的弧度是否在圓弧的弧度范圍內(nèi),可以通過CArc類中的成員函數(shù)IsInArc函數(shù)來確定。⑷多邊形區(qū)域 圖形元素多邊形區(qū)域和標(biāo)注文本〔四邊形〕都屬于這種情況。最簡單的多邊形區(qū)域就是沒有旋轉(zhuǎn)的矩形〔如水平標(biāo)注的文本就是這種情況〕,判斷一個點(diǎn)是否在這種矩形中的算法非常簡單。VC++的CRgn類提供了一個成員函數(shù)來實(shí)現(xiàn)這個操作功能。CRgn類封裝了一些進(jìn)行區(qū)域操作的函數(shù),可以直接解決按中點(diǎn)是否在多邊形區(qū)域中的問題。以下是操作步驟:首先定義一個CRgn對象;把CRgn初始化成一個具有n個頂點(diǎn)的多邊形區(qū)域;建立一個多邊形區(qū)域后,調(diào)用PtInRegion函數(shù)來判斷一個點(diǎn)是否在區(qū)域內(nèi)。函數(shù)PtInRegion是CRgn類的成員函數(shù),它可以判斷點(diǎn)是否在初始化區(qū)域內(nèi)。在CDraw類中建立一個函數(shù)完成這個操作:Public: BOOLPointRgn(floatx,floaty,intNumble,PointStruct*PointList,floatblc); //判斷點(diǎn)是否在初的區(qū)域內(nèi)在實(shí)現(xiàn)文件draw.cpp中,參加函數(shù)的實(shí)現(xiàn)代碼各種圖形元素的點(diǎn)選判斷函數(shù)首先,在圖形基類CDraw中定義一個純虛函數(shù):Public:VirtualBOOLIsPoint(floatx,floaty,floatjl,floatblc)=0; 在各個圖形元素類CLineCCircleCArcCTextCPlineCPlineRgnCLinkNet中重載虛函數(shù)IsPoint,即在這些類中參加這個函數(shù)的重載定義:Pubic:VirtualBOOLIsPoint(floatx,floaty,floatjl,floatblc);然后實(shí)現(xiàn)各個圖形元素類重載的IsPoint函數(shù)的實(shí)現(xiàn)代碼,實(shí)現(xiàn)各個圖形元素類的點(diǎn)選判斷功能。實(shí)現(xiàn)點(diǎn)選圖形元素功能⑴增加一個菜單及消息處理函數(shù)⑵保存選中的圖形元素 要實(shí)現(xiàn)數(shù)據(jù)保存,就需要建立數(shù)據(jù)結(jié)構(gòu)來存儲選中的圖形元素。在文檔類CDrawDoc中,定義一個結(jié)構(gòu)數(shù)組和一個變量:Protected: GraphSelectStruct*GraphSelect;//存儲選中的圖形元素Intn_GraphSelect;//選中圖形元素的數(shù)目結(jié)構(gòu)GraphSelectStruct在頭文件drawdoc.h中〔CDrawDoc類前〕定義為:Typedefstruct{ShortintLb;IntIndex;Intid_only;}GraphSelectStruct; 將選中的圖形元素存儲在結(jié)構(gòu)數(shù)組GraphSelect中,成員變量Lb存儲選中圖形元素的類別;成員變量Index存儲圖形元素的序列號,即圖形元素在指針數(shù)組中的下標(biāo);成員變量id_only存儲這個圖形元素惟一的識別號,即圖形元素中的成員變量m_id_only。在實(shí)現(xiàn)文件drawdoc.cpp中,在CDrawDoc文檔類的構(gòu)造函數(shù)內(nèi)動態(tài)分配結(jié)構(gòu)數(shù)組GraphSelect: CDrawDoc::CDrawDoc() { GraphSelect=newGraphSelectStruct[10000]; }在CDrawDo類的析構(gòu)函數(shù)中,刪除動態(tài)分配的結(jié)構(gòu)數(shù)組: CDrawDoc::~CDrawDoc() {DeleteGraphSelect; } 為了將一個選中的圖形元素存儲到結(jié)構(gòu)數(shù)組GraphSelect中,在文檔類CDrawDoc中定義一個函數(shù):Public: BOOLAddSelectList(intLb,intindex,intid_only); 函數(shù)AddSelectList實(shí)現(xiàn)在結(jié)構(gòu)數(shù)組GraphSelect中增加一個選中的圖形元素,增加成功是返回TRUE,否那么函數(shù)返回FALSE.函數(shù)的實(shí)現(xiàn)代碼如下:BOOLCDrawDoc::AddSelectList(intLb,intindex,intid_only){for(inti=0;i<n_G
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 IEC 60335-2-74:2021+AMD1:2024 CSV EN Household and similar electrical appliances - Safety - Part 2-74: Particular requirements for portable immersion heaters
- 【正版授權(quán)】 IEC 60076-11:2004 EN-D Power transformers - Part 11: Dry-type transformers
- 個人如何做家庭教育
- 電子行業(yè)非標(biāo)產(chǎn)線
- 2025年少年宮活動方案
- 出鏡記者與主持人實(shí)務(wù) 課件 第五章 現(xiàn)場隨機(jī)采訪
- 湘教版開花和結(jié)果
- 校園元旦晚會活動方案策劃書2025年
- 幼兒園自理能力主題教育課件
- 伺服系統(tǒng)與工業(yè)機(jī)器人課件第11章 工業(yè)機(jī)器人系統(tǒng)
- 《人工智能技術(shù)基礎(chǔ)》課件-第六章 知識圖譜
- 2025年山東省濟(jì)南市市中區(qū)中考物理一模試卷(無答案)
- 2024-2030年中國驅(qū)蚊用品行業(yè)市場深度分析及投資策略研究報(bào)告
- 廣東省深圳市寶安區(qū)10校聯(lián)考2023-2024學(xué)年八年級下學(xué)期4月期中物理試題(含答案)
- 商業(yè)秘密保護(hù):內(nèi)外勾結(jié)型侵犯行為的司法認(rèn)定分析
- 2024年遼寧沈陽地鐵集團(tuán)有限公司所屬公司招聘筆試真題
- 2025年全國中小學(xué)生安全教育日專題
- 2025年電子設(shè)備裝接工崗位職業(yè)技能資格證考試題(附答案)
- 2025年河南航空港發(fā)展投資集團(tuán)有限公司社會招聘45人筆試參考題庫附帶答案詳解
- 2025太陽能光熱發(fā)電站熔融鹽儲熱系統(tǒng)技術(shù)
- 2024年中國移動招聘筆試真題
評論
0/150
提交評論