1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
---|
2 | <!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/coordsys.doc:36 -->
|
---|
3 | <html>
|
---|
4 | <head>
|
---|
5 | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
---|
6 | <title>The Coordinate System</title>
|
---|
7 | <style type="text/css"><!--
|
---|
8 | fn { margin-left: 1cm; text-indent: -1cm; }
|
---|
9 | a:link { color: #004faf; text-decoration: none }
|
---|
10 | a:visited { color: #672967; text-decoration: none }
|
---|
11 | body { background: #ffffff; color: black; }
|
---|
12 | --></style>
|
---|
13 | </head>
|
---|
14 | <body>
|
---|
15 |
|
---|
16 | <table border="0" cellpadding="0" cellspacing="0" width="100%">
|
---|
17 | <tr bgcolor="#E5E5E5">
|
---|
18 | <td valign=center>
|
---|
19 | <a href="index.html">
|
---|
20 | <font color="#004faf">Home</font></a>
|
---|
21 | | <a href="classes.html">
|
---|
22 | <font color="#004faf">All Classes</font></a>
|
---|
23 | | <a href="mainclasses.html">
|
---|
24 | <font color="#004faf">Main Classes</font></a>
|
---|
25 | | <a href="annotated.html">
|
---|
26 | <font color="#004faf">Annotated</font></a>
|
---|
27 | | <a href="groups.html">
|
---|
28 | <font color="#004faf">Grouped Classes</font></a>
|
---|
29 | | <a href="functions.html">
|
---|
30 | <font color="#004faf">Functions</font></a>
|
---|
31 | </td>
|
---|
32 | <td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>The Coordinate System</h1>
|
---|
33 |
|
---|
34 |
|
---|
35 |
|
---|
36 | <p> A <a href="qpaintdevice.html">paint device</a> in Qt is a drawable 2D
|
---|
37 | surface. <a href="qwidget.html">QWidget</a>, <a href="qpixmap.html">QPixmap</a>, <a href="qpicture.html">QPicture</a> and <a href="qprinter.html">QPrinter</a> are all
|
---|
38 | paint devices. A <a href="qpainter.html">QPainter</a> is an object which can draw on such
|
---|
39 | devices.
|
---|
40 | <p> The default coordinate system of a paint device has its origin at the
|
---|
41 | top left corner. X increases to the right and Y increases downwards.
|
---|
42 | The unit is one pixel on pixel-based devices and one point on
|
---|
43 | printers.
|
---|
44 | <p> <h2> An Example
|
---|
45 | </h2>
|
---|
46 | <a name="1"></a><p> The illustration below shows a highly magnified portion of the top
|
---|
47 | left corner of a paint device.
|
---|
48 | <p> <center><img src="coordsys.png"></center>
|
---|
49 | <p> The rectangle and the line were drawn by this code (with the grid
|
---|
50 | added and colors touched up in the illustration):
|
---|
51 | <p> <pre>
|
---|
52 | void MyWidget::paintEvent( <a href="qpaintevent.html">QPaintEvent</a> * )
|
---|
53 | {
|
---|
54 | <a href="qpainter.html">QPainter</a> p( this );
|
---|
55 | p.<a href="qpainter.html#setPen">setPen</a>( darkGray );
|
---|
56 | p.<a href="qpainter.html#drawRect">drawRect</a>( 1,2, 5,4 );
|
---|
57 | p.<a href="qpainter.html#setPen">setPen</a>( lightGray );
|
---|
58 | p.<a href="qpainter.html#drawLine">drawLine</a>( 9,2, 7,7 );
|
---|
59 | }
|
---|
60 | </pre>
|
---|
61 |
|
---|
62 | <p> Note that all of the pixels drawn by drawRect() are inside the size
|
---|
63 | specified (5*4 pixels). This is different from some toolkits; in Qt
|
---|
64 | the size you specify exactly encompasses the pixels drawn. This
|
---|
65 | applies to all the relevant functions in <a href="qpainter.html">QPainter</a>.
|
---|
66 | <p> Similarly, the drawLine() call draws both endpoints of the line, not
|
---|
67 | just one.
|
---|
68 | <p> Here are the classes that relate most closely to the coordinate
|
---|
69 | system:
|
---|
70 | <p> <center><table cellpadding="4" cellspacing="2" border="0">
|
---|
71 | <tr bgcolor="#f0f0f0"> <td valign="top"><a href="qpoint.html">QPoint</a>
|
---|
72 | <td valign="top">A single 2D point in the coordinate system. Most functions in
|
---|
73 | Qt that deal with points can accept either a <a href="qpoint.html">QPoint</a> argument
|
---|
74 | or two ints, for example <a href="qpainter.html#drawPoint">QPainter::drawPoint</a>().
|
---|
75 | <tr bgcolor="#d0d0d0"> <td valign="top"><a href="qsize.html">QSize</a>
|
---|
76 | <td valign="top">A single 2D vector. Internally, QPoint and <a href="qsize.html">QSize</a> are the same,
|
---|
77 | but a point is not the same as a size, so both classes exist.
|
---|
78 | Again, most functions accept either a QSize or two ints, for
|
---|
79 | example <a href="qwidget.html#resize">QWidget::resize</a>().
|
---|
80 | <tr bgcolor="#f0f0f0"> <td valign="top"><a href="qrect.html">QRect</a>
|
---|
81 | <td valign="top">A 2D rectangle. Most functions accept either a <a href="qrect.html">QRect</a> or four
|
---|
82 | ints, for example <a href="qwidget.html#setGeometry">QWidget::setGeometry</a>().
|
---|
83 | <tr bgcolor="#d0d0d0"> <td valign="top"><a href="qregion.html">QRegion</a>
|
---|
84 | <td valign="top">An arbitrary set of points, including all the normal set
|
---|
85 | operations, e.g. <a href="qregion.html#intersect">QRegion::intersect</a>(), and also a less
|
---|
86 | usual function to return a list of rectangles whose union is
|
---|
87 | equal to the region. <a href="qregion.html">QRegion</a> is used e.g. by <a href="qpainter.html#setClipRegion">QPainter::setClipRegion</a>(), <a href="qwidget.html#repaint">QWidget::repaint</a>() and <a href="qpaintevent.html#region">QPaintEvent::region</a>().
|
---|
88 | <tr bgcolor="#f0f0f0"> <td valign="top"><a href="qpainter.html">QPainter</a>
|
---|
89 | <td valign="top">The class that paints. It can paint on any device with the
|
---|
90 | same code. There are differences between devices, <a href="qprinter.html#newPage">QPrinter::newPage</a>() is a good example, but <a href="qpainter.html">QPainter</a> works the
|
---|
91 | same way on all devices.
|
---|
92 | <tr bgcolor="#d0d0d0"> <td valign="top"><a href="qpaintdevice.html">QPaintDevice</a>
|
---|
93 | <td valign="top">A device on which QPainter can paint. There are two internal
|
---|
94 | devices, both pixel-based, and two external devices, <a href="qprinter.html">QPrinter</a> and <a href="qpicture.html">QPicture</a> (which records QPainter commands to a
|
---|
95 | file or other <a href="qiodevice.html">QIODevice</a>, and plays them back). Other
|
---|
96 | devices can be defined.
|
---|
97 | </table></center>
|
---|
98 | <p> <h2> Transformations
|
---|
99 | </h2>
|
---|
100 | <a name="2"></a><p> Although Qt's default coordinate system works as described above, <a href="qpainter.html">QPainter</a> also supports arbitrary transformations.
|
---|
101 | <p> This transformation engine is a three-step pipeline, closely following
|
---|
102 | the model outlined in books such as
|
---|
103 | <a href="http://www.amazon.com/exec/obidos/ASIN/0201848406/trolltech/t">Foley & Van Dam</a> and the
|
---|
104 | <a href="http://www.amazon.com/exec/obidos/ASIN/0201604582/trolltech/t">OpenGL Programming Guide.</a> Refer to those for in-depth
|
---|
105 | coverage; here we give just a brief overview and an example.
|
---|
106 | <p> The first step uses the world <a href="qwmatrix.html#TransformationMode">transformation matrix</a>. Use this matrix
|
---|
107 | to orient and position your objects in your model. Qt provides
|
---|
108 | methods such as <a href="qpainter.html#rotate">QPainter::rotate</a>(), <a href="qpainter.html#scale">QPainter::scale</a>(), <a href="qpainter.html#translate">QPainter::translate</a>() and so on to operate on this matrix.
|
---|
109 | <p> <a href="qpainter.html#save">QPainter::save</a>() and <a href="qpainter.html#restore">QPainter::restore</a>() save and restore this
|
---|
110 | matrix. You can also use <a href="qwmatrix.html">QWMatrix</a> objects, <a href="qpainter.html#worldMatrix">QPainter::worldMatrix</a>() and <a href="qpainter.html#setWorldMatrix">QPainter::setWorldMatrix</a>() to store and
|
---|
111 | use named matrices.
|
---|
112 | <p> The second step uses the window. The window describes the view
|
---|
113 | boundaries in model coordinates. The matrix positions the <em>objects</em>
|
---|
114 | and <a href="qpainter.html#setWindow">QPainter::setWindow</a>() positions the <em>window</em>, deciding what
|
---|
115 | coordinates will be visible. (If you have 3D experience, the window
|
---|
116 | is what's usually called projection in 3D.)
|
---|
117 | <p> The third step uses the viewport. The viewport too, describes the view
|
---|
118 | boundaries, but in device coordinates. The viewport and the windows
|
---|
119 | describe the same rectangle, but in different coordinate systems.
|
---|
120 | <p> On-screen, the default is the entire <a href="qwidget.html">QWidget</a> or <a href="qpixmap.html">QPixmap</a> where
|
---|
121 | you are drawing, which is usually appropriate. For printing this
|
---|
122 | function is vital, since very few printers can print over the entire
|
---|
123 | physical page.
|
---|
124 | <p> So each object to be drawn is transformed into model
|
---|
125 | coordinates using <a href="qpainter.html#worldMatrix">QPainter::worldMatrix</a>(), then positioned
|
---|
126 | on the drawing device using <a href="qpainter.html#window">QPainter::window</a>() and
|
---|
127 | <a href="qpainter.html#viewport">QPainter::viewport</a>().
|
---|
128 | <p> It is perfectly possible to do without one or two of the stages. If,
|
---|
129 | for example, your goal is to draw something scaled, then just using <a href="qpainter.html#scale">QPainter::scale</a>() makes perfect sense. If your goal is to use a
|
---|
130 | fixed-size coordinate system, <a href="qpainter.html#setWindow">QPainter::setWindow</a>() is
|
---|
131 | ideal. And so on.
|
---|
132 | <p> Here is a short example that uses all three mechanisms: the function
|
---|
133 | that draws the clock face in the <a href="aclock-example.html">aclock/aclock.cpp</a> example. We
|
---|
134 | recommend compiling and running the example before you read any
|
---|
135 | further. In particular, try resizing the window to different sizes.
|
---|
136 | <p>
|
---|
137 |
|
---|
138 | <pre> void AnalogClock::drawClock( <a href="qpainter.html">QPainter</a> *paint )
|
---|
139 | {
|
---|
140 | <a name="x2275"></a> paint-><a href="qpainter.html#save">save</a>();
|
---|
141 | </pre>
|
---|
142 | <p> Firstly, we save the painter's state, so that the calling function
|
---|
143 | is guaranteed not to be disturbed by the transformations we're going
|
---|
144 | to use.
|
---|
145 | <p> <pre> <a name="x2277"></a> paint-><a href="qpainter.html#setWindow">setWindow</a>( -500,-500, 1000,1000 );
|
---|
146 | </pre>
|
---|
147 | <p> We set the model coordinate system we want a 1000*1000 window where
|
---|
148 | 0,0 is in the middle.
|
---|
149 | <p> <pre> <a name="x2278"></a> <a href="qrect.html">QRect</a> v = paint-><a href="qpainter.html#viewport">viewport</a>();
|
---|
150 | <a name="x2282"></a><a name="x2279"></a> int d = QMIN( v.<a href="qrect.html#width">width</a>(), v.<a href="qrect.html#height">height</a>() );
|
---|
151 | </pre>
|
---|
152 | <p> The device may not be square and we want the clock to be, so we find
|
---|
153 | its current viewport and compute its shortest side.
|
---|
154 | <p> <pre> <a name="x2280"></a><a name="x2276"></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,
|
---|
155 | <a name="x2281"></a> v.<a href="qrect.html#top">top</a>() + (v.<a href="qrect.html#height">height</a>()-d)/2, d, d );
|
---|
156 | </pre>
|
---|
157 | <p> Then we set a new square viewport, centered in the old one.
|
---|
158 | <p> We're now done with our view. From this point on, when we draw in a
|
---|
159 | 1000*1000 area around 0,0, what we draw will show up in the largest
|
---|
160 | possible square that'll fit in the output device.
|
---|
161 | <p> Time to start drawing.
|
---|
162 | <p> <pre> <a href="qpointarray.html">QPointArray</a> pts;
|
---|
163 | </pre>
|
---|
164 | <p> <em>pts</em> is just a temporary variable to hold some points.
|
---|
165 | <p> Next come three drawing blocks, one for the hour hand, one for the
|
---|
166 | minute hand and finally one for the clock face itself. First we draw
|
---|
167 | the hour hand:
|
---|
168 | <p> <pre> paint-><a href="qpainter.html#save">save</a>();
|
---|
169 | <a name="x2274"></a> paint-><a href="qpainter.html#rotate">rotate</a>( 30*(time.hour()%12-3) + time.minute()/2 );
|
---|
170 | </pre>
|
---|
171 | <p> We save the painter and then rotate it so that one axis points along
|
---|
172 | the hour hand.
|
---|
173 | <p> <pre> pts.setPoints( 4, -20,0, 0,-20, 300,0, 0,20 );
|
---|
174 | <a name="x2271"></a> paint-><a href="qpainter.html#drawConvexPolygon">drawConvexPolygon</a>( pts );
|
---|
175 | </pre>
|
---|
176 | <p> We set <em>pts</em> to a four-point polygon that looks like the hour hand at
|
---|
177 | three o'clock, and draw it. Because of the rotation, it's drawn
|
---|
178 | pointed in the right direction.
|
---|
179 | <p> <pre> <a name="x2273"></a> paint-><a href="qpainter.html#restore">restore</a>();
|
---|
180 | </pre>
|
---|
181 | <p> We restore the saved painter, undoing the rotation. We could also
|
---|
182 | call rotate( -30 ) but that might introduce rounding errors, so it's
|
---|
183 | better to use save() and restore(). Next, the minute hand, drawn
|
---|
184 | almost the same way:
|
---|
185 | <p> <pre> paint-><a href="qpainter.html#save">save</a>();
|
---|
186 | paint-><a href="qpainter.html#rotate">rotate</a>( (time.minute()-15)*6 );
|
---|
187 | pts.setPoints( 4, -10,0, 0,-10, 400,0, 0,10 );
|
---|
188 | paint-><a href="qpainter.html#drawConvexPolygon">drawConvexPolygon</a>( pts );
|
---|
189 | paint-><a href="qpainter.html#restore">restore</a>();
|
---|
190 | </pre>
|
---|
191 | <p> The only differences are how the rotation angle is computed and the
|
---|
192 | shape of the polygon.
|
---|
193 | <p> The last part to be drawn is the clock face itself.
|
---|
194 | <p> <pre> for ( int i=0; i<12; i++ ) {
|
---|
195 | <a name="x2272"></a> paint-><a href="qpainter.html#drawLine">drawLine</a>( 440,0, 460,0 );
|
---|
196 | paint-><a href="qpainter.html#rotate">rotate</a>( 30 );
|
---|
197 | }
|
---|
198 | </pre>
|
---|
199 | <p> Twelve short hour lines at thirty-degree intervals. At the end of
|
---|
200 | that, the painter is rotated in a way which isn't very useful, but
|
---|
201 | we're done with painting so that doesn't matter.
|
---|
202 | <p> <pre> paint-><a href="qpainter.html#restore">restore</a>();
|
---|
203 | }
|
---|
204 | </pre>
|
---|
205 | <p> The final line of the function restores the painter, so that the
|
---|
206 | caller won't be affected by all the transformations we've done.
|
---|
207 | <p>
|
---|
208 | <!-- eof -->
|
---|
209 | <p><address><hr><div align=center>
|
---|
210 | <table width=100% cellspacing=0 border=0><tr>
|
---|
211 | <td>Copyright © 2007
|
---|
212 | <a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
|
---|
213 | <td align=right><div align=right>Qt 3.3.8</div>
|
---|
214 | </table></div></address></body>
|
---|
215 | </html>
|
---|