1、 基礎知識
座標系統分為三類:全域性座標系統、頁面座標系統和裝置座標系統。頁面座標系與裝置座標系都是以裝置的左上角為座標原點,x水平向右為正,y垂直向下為正。頁面座標與裝置座標系的差異在於x,y的單位不同:頁面座標系中的x,y單位可以任意設定,如英吋、公釐等;而裝置座標系中,只有一種單位,那就是點或者畫素。
全域性座標系就是我們日常工作的座標系,預設情況下x軸正方向水平向右,y軸正方向垂直向下;我們可以將其進行旋轉、平移等操作。
頁面座標系是不能更改的,它是乙個參照標準,將全域性座標最終轉換為裝置座標。
裝置座標系跟具體的裝置有關,在顯示器中,基本的單位是畫素,在印表機中,基本單位是點(point)。
mygraphics.translatetransform(2, 0.5f)
mygraphics.setpageunit(unitinch);
mygraphics.drawline(&mypen, 0, 0, 2, 1)
全域性 (0, 0) 到 (2, 1)
頁 (2, 0.5) 到 (4, 1.5)
裝置 (192, 48) 到 (384, 144)
我們呼叫gdi+裡的graphics進行操作時,輸入的座標為在全域性座標系統中的座標,而在螢幕或者印表機上顯示的是裝置座標系統中的值。因此,從全域性座標系統中的座標到裝置座標系統中的座標需要經過全域性座標到頁面座標的全域性變形(world transformation),從頁面座標到裝置座標的頁面變形(page transformation)。全域性變形通過transform來實現;頁面變形通過setpageunit和setpagescale。setpageunit()指定繪圖單位,引數分別為
typedef enum unit;
對於不同的單位,可能轉換為裝置座標的時候就有不同的結果。但是頁面變形需要由setpageunit和setpagescale這兩個函式共同來決定。即
graphics.setpageunit(unitinch);//英吋
graphics.setpagescale(1.0f);
和
graphics.setpageunit(unitmillimeter );//公釐
graphics.setpagescale(25.4f);
這兩種設定方式的結果是一樣的。在這裡假定25.4公釐=1英吋
同理,其他幾種模式下(除unitworld外,在這種模式下沒有物理單位,預設情況下為該模式),裝置座標系的設定也是可以相互轉換的。
並且在同一函式段中可以隨時改變裝置座標設定。而不會相互影響,見下面程式段所示:
graphics graphics(hdc);
// set the page units to pixels, and draw a rectangle.
graphics.setpageunit(unitpixel);
pen blackpen(color(255, 0, 0, 0), 0.0f);
graphics.drawrectangle(&blackpen, 0, 0, 100, 100);
// set the page units to inches, and draw a rectangle.
graphics.setpageunit(unitinch);
pen bluepen(color(255, 0, 0, 255), 0.0f);
graphics.drawrectangle(&bluepen, 2, 0, 1, 1);
全域性變形:忽略單位,將座標值進行轉換,下一節詳細說明。
頁面變形:根據單位將座標值。頁面座標中,具體的單位是根據基本單位和比例來進行設定的,計算公式為:具體單位=基本單位*比例。
2、 全域性變形的換算關係
根據第一節的講解,我們對於這三種座標系有了乙個基本的認識。但對於實際程式開發工作是遠遠不夠的。下面就對所有的變形進行**。
(1) 基本變換:平移及旋轉
平移及旋轉變換是最基本的全域性變換,可以通過如下幾種方式進行實現:graphics::translatetransform,graphics::settransform
其中,translatetransform(int x,int y);如果x>0則表示正方向移動,反之,向反方向移動。
(2) 改變座標系,使y軸垂直向上為正
這種轉換,需要利用matrix來進行,稱為仿射變形。
matrix matrix(1.0f,0.0f,0.0f,-1.0f,x,y);
graphics.settransform(&matrix);//即可將y軸轉變成垂直向上為正
且平移(x,y)的距離。注,平移座標轉換是在新的全域性座標系下進行的,即操作的都是全域性座標系。
matrix matrix(1.0f,0.0f,0.0f,-1.0f,0.0f,0.0f);
graphics.settransform(&matrix);
graphics.translatetransform(0,-100.0f);//平移是在新的全域性座標系下進行的,平移的也是全域性座標系本身,與頁面座標系沒有關係
graphics.drawline(&pen1,0,0,100,100);
如果在matrix中指定的x的比例不是1.0f的話,那就是全域性座標系中,x軸的比例發生了變化,如果大於1,則進行了放大,即相同大小的數值表示的長度增長。反之,則縮小。
(3)縮放並平移與縮放後平移的效果是不一樣的,即此時的平移還是在原有的基礎上進行的,因此,還是向下為正,即100。
graphicscontainer container3=graphics.begincontainer();
//x方向放大2倍,並平移100個單位
matrix matrix(2.0f,0.0f,0.0f,-1.0f,100.0f,100.0f);
graphics.settransform(&matrix);
graphics.drawline(&pen1,0,0,100,0);
graphics.endcontainer(container3);
graphicscontainer container4=graphics.begincontainer();
//x方向放大2倍,然後再平移100個單位,這時,新的全域性座標系已經變為向上為正,所以向下為負,即-200。此時
matrix matrix1(2.0f,0.0f,0.0f,-1.0f,0.0f,0.0f);
graphics.settransform(&matrix1);
graphics.translatetransform(100,-200.0f);
graphics.drawline(&pen1,0,0,100,0);
graphics.endcontainer(container4);
輸出結果如下圖所示:
3、 滑鼠輸入座標到全域性座標的轉換
滑鼠輸入的座標都是裝置座標,要轉換為全域性座標,就是乙個從全域性座標轉換到裝置座標的逆向過程。即相當於point1*[matrix]=point2,其中[matix]為轉換矩形,在已知point2的情況下,來求point1。這也就是我們進行座標轉換的真正目的。
轉換方式為:
point1=point2*[matrix]-1
在實際的操作中,是這樣進行的:
matrix matrix(2.0f,0.0f,0.0f,-1.0f,100.0f,0.0f);//定義了乙個轉換矩陣,轉換座標系
graphics.settransform(&matrix);
matrix *pmatrix1=matrix.clone();
pmatrix1->invert();
pmatrix1->transformpoints(&m_pt);//m_pt是從螢幕上獲得的乙個值,經過轉換以後成為全域性座標系下的乙個值,在螢幕上與取值位置是相一致的。
delete pmatrix1;
graphics.drawline(&pen,0,0,m_pt.x,m_pt.y);
上述操作是在乙個預設條件下進行的,即頁面座標系與裝置座標系是同乙個座標系。當這兩個座標系不同裡,還需要從頁面座標系座標以裝置座標系座標的轉換,轉換過程中,根據設定的單位不同,但總的轉換關係為:
頁面座標*每單位包括的畫素點=裝置座標
注:別人總結的,上次繪圖時,光想著找回知識老,忘了在那兒看到的老——謝謝分享!
View事件分發和座標系統總結
view 座標分析 相對與父控制項 mtop mleft mbottom mright 絕對值 mheight mwidth 隱藏部分絕對值 mscrollx 上部隱藏部分 相對與mtop mscrolly 左邊隱藏部分 相對於mleft 以 mtop,mleft 為座標原點 x y 以螢幕左上角為...
座標系統變換
在檢視的drawrect 方法中常常借助座標系統變換來進行描畫。而在iphone os系統中,您還可以用它來實現檢視的某些視覺效果。舉例來說,uiview類中包含乙個transform屬性宣告 您可以通過它來對整個檢視實行各種型別的平移 比例縮放 和變焦縮放效果。預設情況下,這個屬性的值是乙個恒等變...
android座標系統
android 螢幕 view 座標系統 首先明確一下 android中的座標系統 螢幕的左上角是座標系統原點 0,0 原點向右延伸是x軸正方向,原點向下延伸是y軸正方向。一 view的座標 需要注意view的座標是相對父容器而言的,包括 gettop getbottom getleft getri...