?? coordsys.html
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- /home/reggie/tmp/qt-3.0-reggie-5401/qt-win-commercial-3.0.5/doc/coordsys.doc:36 -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="Translator" content="Cavendish">
<meta name="Qt zh_CN Documents Website" content="http://www.qiliang.net/qt">
<title>坐標系統</title>
<style type="text/css"><!--
h3.fn,span.fn { margin-left: 1cm; text-indent: -1cm; }
a:link { color: #004faf; text-decoration: none }
a:visited { color: #672967; text-decoration: none }
body { background: #ffffff; color: black; font-family: "Times New Roman" }
--></style>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr bgcolor="#E5E5E5">
<td valign=center>
<a href="index.html">
<font color="#004faf">主頁</font></a>
| <a href="classes.html">
<font color="#004faf">所有的類</font></a>
| <a href="mainclasses.html">
<font color="#004faf">主要的類</font></a>
| <a href="annotated.html">
<font color="#004faf">注釋的類</font></a>
| <a href="groups.html">
<font color="#004faf">分組的類</font></a>
| <a href="functions.html">
<font color="#004faf">函數</font></a>
</td>
<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table>
<h1 align=center>坐標系統</h1>
<p> 在Qt中的一個<a href="qpaintdevice.html">繪畫設備</a>是一個可畫的二維平面。<a href="qwidget.html">QWidget</a>、<a href="qpixmap.html">QPixmap</a>、<a href="qpicture.html">QPicture</a>和<a href="qprinter.html">QPrinter</a>都是繪畫設備。<a href="qpainter.html">QPainter</a>是一個可以在上面畫的對象。
<p> 一個繪畫設備的默認坐標系統的原點在左上角。X軸由左向右增加,Y軸由上向下增加。對于基于像素的設備單位是像素,對于打印機是點。
<p> <h2> 一個例子
</h2>
<a name="1"></a><p> 下面這個圖顯示了一個繪畫設備的左上角的高度放大的部分。
<p> <center><img src="coordsys.png"></center>
<p> 這個矩形和線段是由下面的代碼畫出來的(在這個圖中添加了網格):
<p> <pre>
void MyWidget::paintEvent( <a href="qpaintevent.html">QPaintEvent</a> * )
{
<a href="qpainter.html">QPainter</a> p( this );
p.<a href="qpainter.html#setPen">setPen</a>( darkGray );
p.<a href="qpainter.html#drawRect">drawRect</a>( 1,2, 5,4 );
p.<a href="qpainter.html#setPen">setPen</a>( lightGray );
p.<a href="qpainter.html#drawLine">drawLine</a>( 9,2, 7,7 );
}
</pre>
<p> applies to all the relevant functions in <a href="qpainter.html">QPainter</a>.
請注意drawRect()所畫的所有像素是在指定的大小之內(5*4像素)。這一點和其它工具包不同;Qt中你指定的大小包括你所要畫的像素。這一點適用于所有<a href="qpainter.html">QPainter</a>中相關的函數。
<p> 相似的,drawLine()調用畫了這個線段的兩個端點,而不僅僅是一個。
<p> 這里是一些和坐標系統關系很近的類:
<p> <ul>
<p> <li> <a href="qpoint.html">QPoint</a>是坐標系統中的單個二維點。Qt中處理點的絕大多數函數都可以接受<a href="qpoint.html">QPoint</a>參數或者兩個整數參數,比如<a href="qpainter.html#drawPoint">QPainter::drawPoint</a>()。
<p> <li> <a href="qsize.html">QSize</a>是單個二維矢量。在內部,QPoint和<a href="qsize.html">QSize</a>是一樣的,但是一個點和一個大小不同,所以這兩個類都存在。同樣,絕大多數函數都可以接受一個QSize或者兩個整數,比如<a href="qwidget.html#resize">QWidget::resize</a>()。
<p> <li> <a href="qrect.html">QRect</a>是一個二維的矩形。絕大多數函數都可以接受一個<a href="qrect.html">QRect</a>或者四個整數,比如<a href="qwidget.html#setGeometry">QWidget::setGeometry</a>()。
<p> <li> <a href="qregion.html">QRegion</a>是點的一個任意組合,包括所有通常的組合操作,例如<a href="qregion.html#intersect">QRegion::intersect</a>(),并且一些常用的函數返回一個矩形的列表,這個矩形的列表的集合等于一個區域。<a href="qregion.html">QRegion</a>被例如<a href="qpainter.html#setClipRegion">QPainter::setClipRegion</a>()、<a href="qwidget.html#repaint">QWidget::repaint</a>()和<a href="qpaintevent.html#region">QPaintEvent::region</a>()使用。
<p> <li> <a href="qpainter.html">QPainter</a>是一個繪圖的類。它可以用同樣的代碼在任何一個設備上繪畫。設備中是存在差異的,<a href="qprinter.html#newPage">QPrinter::newPage</a>()是一個很好的例子,但<a href="qpainter.html">QPainter</a>可以對所有的設備按同一種方式工作。
<p> <li> <a href="qpaintdevice.html">QPaintDevice</a>是一個QPainter可以在上面繪畫的設備。這里有兩種都基于像素的內部的設備,和兩種外部設備,<a href="qprinter.html">QPrinter</a>和<a href="qpicture.html">QPicture</a>(它把QPainter的命令都記錄在一個文件或者其它的<a href="qiodevice.html">QIODevice</a>,然后再運行它們)。其它的設備都可以被定義。
<p> </ul>
<p> <h2> 變換
</h2>
<a name="2"></a><p> 盡管Qt默認的坐標系統像我們上面描述的那樣工作,<a href="qpainter.html">QPainter</a>也支持任意的變換。
<p> 這個變換引擎是一個三步的管道,和下面的<a href="http://www.amazon.com/exec/obidos/ASIN/0201848406/trolltech/t">Foley & Van Dam</a> and the
<a href="http://www.amazon.com/exec/obidos/ASIN/0201604582/trolltech/t">OpenGL Programming Guide</a>兩本書中的模型非常接近。參考那些深度的內容,這里我們給出了一個簡單的概述和一個例子。
<p> 第一步使用通用變換矩陣。使用這個矩陣來定位你的模型中的對象。Qt提供了像<a href="qpainter.html#rotate">QPainter::rotate</a>()、<a href="qpainter.html#scale">QPainter::scale</a>()、<a href="qpainter.html#translate">QPainter::translate</a>()等等方法來操作這個矩陣。
<p> <a href="qpainter.html#save">QPainter::save</a>()和<a href="qpainter.html#restore">QPainter::restore</a>()存儲和恢復這個矩陣。你也可以使用<a href="qwmatrix.html">QWMatrix</a>對象、<a href="qpainter.html#worldMatrix">QPainter::worldMatrix</a>()和<a href="qpainter.html#setWorldMatrix">QPainter::setWorldMatrix</a>()來存儲和使用指定的矩陣。
<p> 第二步使用窗口。這個窗口在模式坐標上說明視圖的邊界。矩陣定位<em>對象</em>并且<a href="qpainter.html#setWindow">QPainter::setWindow</a>()定位這個<em>窗口</em>,決定哪個坐標系統是可見的。(如果你有三維的經驗,這個窗口通常是被三維投影出來的。)
<p> 第三步使用視口。視口也描述視圖的邊界,但是是在設備坐標上。視口和窗口描述的是同一個矩形,但是在不同的坐標系統中。
<p> 在屏幕上,默認的是你所畫的通常合適的整個<a href="qwidget.html">QWidget</a>或者<a href="qpixmap.html">QPixmap</a>。對于打印這個功能是非常重要的,因為只有很少的打印機可以在真個物理頁面上打印。
<p> 所以每一個要畫的對象被使用<a href="qpainter.html#worldMatrix">QPainter::worldMatrix</a>()變換到模式坐標中,然后被<a href="qpainter.html#window">QPainter::window</a>()剪輯,最后被使用<a href="qpainter.html#viewport">QPainter::viewport</a>()定位到所畫的設備上。
<p> 沒有上述一個或兩個步驟也是可能做到的。舉例來說,比如你的目標是畫一些按比例縮放的東西,然后使用<a href="qpainter.html#scale">QPainter::scale</a>()來達到理想的效果。如果你使用一個大小固定的坐標系統,<a href="qpainter.html#setWindow">QPainter::setWindow</a>()是最好的。等等。
<p> 這里是一個使用所有這三個機制的一個簡單的例子:這個函數在<a href="aclock-example.html">aclock/aclock.cpp</a>例子中畫了一個鐘表面板。我們建議你在讀任何代碼之前先編譯和運行這個例子。尤其是,試著把這個窗口改變成不同的形狀。
<p>
<pre> void AnalogClock::drawClock( <a href="qpainter.html">QPainter</a> *paint )
{
<a name="x2379"></a> paint-><a href="qpainter.html#save">save</a>();
</pre>
<p> 首先,我們保存繪畫工具的狀態,這樣的調用函數就保證了不會將要使用的變換干擾。
<p> <pre> <a name="x2381"></a> paint-><a href="qpainter.html#setWindow">setWindow</a>( -500,-500, 1000,1000 );
</pre>
<p> 我們設置一個1000*1000、原點(0,0)在中間的窗口的模式坐標系統。
<p> <pre> <a name="x2382"></a> <a href="qrect.html">QRect</a> v = paint-><a href="qpainter.html#viewport">viewport</a>();
<a name="x2386"></a><a name="x2383"></a> int d = QMIN( v.<a href="qrect.html#width">width</a>(), v.<a href="qrect.html#height">height</a>() );
</pre>
<p> 這個設備也許不是正方形的,但我們希望鐘表是正方形的,所以我們找到它當前的視口并計算它最短的邊。
<p> <pre> <a name="x2384"></a><a name="x2380"></a> paint-><a href="qpainter.html#setViewport">setViewport</a>( v.<a href="qrect.html#left">left</a>() + (v.<a href="qrect.html#width">width</a>()-d)/2,
<a name="x2385"></a> v.<a href="qrect.html#top">top</a>() + (v.<a href="qrect.html#height">height</a>()-d)/2, d, d );
</pre>
<p> 然后我們設置一個新的正方形視口,把它放在原來的中間。
<p> 現在我們做完了我們的視圖。從這點上來看,當我們在(0,0)點周圍畫一個1000*1000的區域,我們所畫的東西將會在適合輸出設備的最大可能的正方形區域中顯示出來。
<p> 是我們開始繪圖的時候了。
<p> <pre> <a name="x2387"></a> // time = QTime::<a href="qtime.html#currentTime">currentTime</a>();
<a href="qpointarray.html">QPointArray</a> pts;
</pre>
<p> 因為我們在畫一個鐘表,所以我們需要知道時間。<em>pts</em>剛好是一個用來存儲一些點的有用的變量。
<p> 接下來我們畫三個塊,一個是時針,一個是分針,最后一個是鐘表面板自己。首先我們來畫時針:
<p> <pre> paint-><a href="qpainter.html#save">save</a>();
<a name="x2378"></a> paint-><a href="qpainter.html#rotate">rotate</a>( 30*(time.hour()%12-3) + time.minute()/2 );
</pre>
<p> 我們保存繪畫工具,然后根據時針轉動的方向旋轉它。
<p> <pre> pts.setPoints( 4, -20,0, 0,-20, 300,0, 0,20 );
<a name="x2375"></a> paint-><a href="qpainter.html#drawConvexPolygon">drawConvexPolygon</a>( pts );
</pre>
<p> 我們把<em>pts</em>設置為一個四點的多邊形,好像時針就在三點鐘,然后畫上它。因為這個旋轉,時針被畫到正確的位置。
<p> <pre> <a name="x2377"></a> paint-><a href="qpainter.html#restore">restore</a>();
</pre>
<p> 我們恢復被存儲哦繪圖工具,取消旋轉。我們也可以通過調用rotate( -30 ),但是那樣也許會導致旋轉錯誤,所以使用save()和restore()是更好的方法。接下來,按大致相同哦方式畫分針:
<p> <pre> paint-><a href="qpainter.html#save">save</a>();
paint-><a href="qpainter.html#rotate">rotate</a>( (time.minute()-15)*6 );
pts.setPoints( 4, -10,0, 0,-10, 400,0, 0,10 );
paint-><a href="qpainter.html#drawConvexPolygon">drawConvexPolygon</a>( pts );
paint-><a href="qpainter.html#restore">restore</a>();
</pre>
<p> 唯一的不同是如何計算要旋轉的角度和多邊形的形狀。
<p> 要畫的最后一部分就是鐘表面板自己。
<p> <pre> for ( int i=0; i<12; i++ ) {
<a name="x2376"></a> paint-><a href="qpainter.html#drawLine">drawLine</a>( 440,0, 460,0 );
paint-><a href="qpainter.html#rotate">rotate</a>( 30 );
}
</pre>
<p> 十二個短的時針刻度之間的間隔是三十度。最后,繪圖工具被旋轉不是一個非常有用的方法,但是我們已經畫完了,所以這也沒什么。
<p> <pre> paint-><a href="qpainter.html#restore">restore</a>();
}
</pre>
<p> 最后一行的函數是恢復繪圖工具,這樣繪圖工具的調用者就不用擔心我們所做的所有變換會影響它。
<p>
<!-- eof -->
<p><address><hr><div align=center>
<table width=100% cellspacing=0 border=0><tr>
<td>Copyright © 2002
<a href="http://www.trolltech.com">Trolltech</a>
<td><a href="http://www.trolltech.com/trademarks.html">Trademarks</a>
<td><a href="zh_CN.html">譯者:Cavendish</a>
<td align=right><div align=right>Qt 3.0.5版</div>
</table></div></address></body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -