You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
13 KiB
216 lines
13 KiB
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/coordsys.doc:36 -->
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>The Coordinate System</title>
|
|
<style type="text/css"><!--
|
|
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; }
|
|
--></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">Home</font></a>
|
|
| <a href="classes.html">
|
|
<font color="#004faf">All Classes</font></a>
|
|
| <a href="mainclasses.html">
|
|
<font color="#004faf">Main Classes</font></a>
|
|
| <a href="annotated.html">
|
|
<font color="#004faf">Annotated</font></a>
|
|
| <a href="groups.html">
|
|
<font color="#004faf">Grouped Classes</font></a>
|
|
| <a href="functions.html">
|
|
<font color="#004faf">Functions</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>The Coordinate System</h1>
|
|
|
|
|
|
|
|
<p> A <a href="qpaintdevice.html">paint device</a> in Qt is a drawable 2D
|
|
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
|
|
paint devices. A <a href="qpainter.html">QPainter</a> is an object which can draw on such
|
|
devices.
|
|
<p> The default coordinate system of a paint device has its origin at the
|
|
top left corner. X increases to the right and Y increases downwards.
|
|
The unit is one pixel on pixel-based devices and one point on
|
|
printers.
|
|
<p> <h2> An Example
|
|
</h2>
|
|
<a name="1"></a><p> The illustration below shows a highly magnified portion of the top
|
|
left corner of a paint device.
|
|
<p> <center><img src="coordsys.png"></center>
|
|
<p> The rectangle and the line were drawn by this code (with the grid
|
|
added and colors touched up in the illustration):
|
|
<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> Note that all of the pixels drawn by drawRect() are inside the size
|
|
specified (5*4 pixels). This is different from some toolkits; in Qt
|
|
the size you specify exactly encompasses the pixels drawn. This
|
|
applies to all the relevant functions in <a href="qpainter.html">QPainter</a>.
|
|
<p> Similarly, the drawLine() call draws both endpoints of the line, not
|
|
just one.
|
|
<p> Here are the classes that relate most closely to the coordinate
|
|
system:
|
|
<p> <center><table cellpadding="4" cellspacing="2" border="0">
|
|
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qpoint.html">QPoint</a>
|
|
<td valign="top">A single 2D point in the coordinate system. Most functions in
|
|
Qt that deal with points can accept either a <a href="qpoint.html">QPoint</a> argument
|
|
or two ints, for example <a href="qpainter.html#drawPoint">QPainter::drawPoint</a>().
|
|
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qsize.html">QSize</a>
|
|
<td valign="top">A single 2D vector. Internally, QPoint and <a href="qsize.html">QSize</a> are the same,
|
|
but a point is not the same as a size, so both classes exist.
|
|
Again, most functions accept either a QSize or two ints, for
|
|
example <a href="qwidget.html#resize">QWidget::resize</a>().
|
|
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qrect.html">QRect</a>
|
|
<td valign="top">A 2D rectangle. Most functions accept either a <a href="qrect.html">QRect</a> or four
|
|
ints, for example <a href="qwidget.html#setGeometry">QWidget::setGeometry</a>().
|
|
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qregion.html">QRegion</a>
|
|
<td valign="top">An arbitrary set of points, including all the normal set
|
|
operations, e.g. <a href="qregion.html#intersect">QRegion::intersect</a>(), and also a less
|
|
usual function to return a list of rectangles whose union is
|
|
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>().
|
|
<tr bgcolor="#f0f0f0"> <td valign="top"><a href="qpainter.html">QPainter</a>
|
|
<td valign="top">The class that paints. It can paint on any device with the
|
|
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
|
|
same way on all devices.
|
|
<tr bgcolor="#d0d0d0"> <td valign="top"><a href="qpaintdevice.html">QPaintDevice</a>
|
|
<td valign="top">A device on which QPainter can paint. There are two internal
|
|
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
|
|
file or other <a href="qiodevice.html">QIODevice</a>, and plays them back). Other
|
|
devices can be defined.
|
|
</table></center>
|
|
<p> <h2> Transformations
|
|
</h2>
|
|
<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.
|
|
<p> This transformation engine is a three-step pipeline, closely following
|
|
the model outlined in books such as
|
|
<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> Refer to those for in-depth
|
|
coverage; here we give just a brief overview and an example.
|
|
<p> The first step uses the world <a href="qwmatrix.html#TransformationMode">transformation matrix</a>. Use this matrix
|
|
to orient and position your objects in your model. Qt provides
|
|
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.
|
|
<p> <a href="qpainter.html#save">QPainter::save</a>() and <a href="qpainter.html#restore">QPainter::restore</a>() save and restore this
|
|
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
|
|
use named matrices.
|
|
<p> The second step uses the window. The window describes the view
|
|
boundaries in model coordinates. The matrix positions the <em>objects</em>
|
|
and <a href="qpainter.html#setWindow">QPainter::setWindow</a>() positions the <em>window</em>, deciding what
|
|
coordinates will be visible. (If you have 3D experience, the window
|
|
is what's usually called projection in 3D.)
|
|
<p> The third step uses the viewport. The viewport too, describes the view
|
|
boundaries, but in device coordinates. The viewport and the windows
|
|
describe the same rectangle, but in different coordinate systems.
|
|
<p> On-screen, the default is the entire <a href="qwidget.html">QWidget</a> or <a href="qpixmap.html">QPixmap</a> where
|
|
you are drawing, which is usually appropriate. For printing this
|
|
function is vital, since very few printers can print over the entire
|
|
physical page.
|
|
<p> So each object to be drawn is transformed into model
|
|
coordinates using <a href="qpainter.html#worldMatrix">QPainter::worldMatrix</a>(), then positioned
|
|
on the drawing device using <a href="qpainter.html#window">QPainter::window</a>() and
|
|
<a href="qpainter.html#viewport">QPainter::viewport</a>().
|
|
<p> It is perfectly possible to do without one or two of the stages. If,
|
|
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
|
|
fixed-size coordinate system, <a href="qpainter.html#setWindow">QPainter::setWindow</a>() is
|
|
ideal. And so on.
|
|
<p> Here is a short example that uses all three mechanisms: the function
|
|
that draws the clock face in the <a href="aclock-example.html">aclock/aclock.cpp</a> example. We
|
|
recommend compiling and running the example before you read any
|
|
further. In particular, try resizing the window to different sizes.
|
|
<p>
|
|
|
|
<pre> void AnalogClock::drawClock( <a href="qpainter.html">QPainter</a> *paint )
|
|
{
|
|
<a name="x2275"></a> paint-><a href="qpainter.html#save">save</a>();
|
|
</pre>
|
|
<p> Firstly, we save the painter's state, so that the calling function
|
|
is guaranteed not to be disturbed by the transformations we're going
|
|
to use.
|
|
<p> <pre> <a name="x2277"></a> paint-><a href="qpainter.html#setWindow">setWindow</a>( -500,-500, 1000,1000 );
|
|
</pre>
|
|
<p> We set the model coordinate system we want a 1000*1000 window where
|
|
0,0 is in the middle.
|
|
<p> <pre> <a name="x2278"></a> <a href="qrect.html">QRect</a> v = paint-><a href="qpainter.html#viewport">viewport</a>();
|
|
<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>() );
|
|
</pre>
|
|
<p> The device may not be square and we want the clock to be, so we find
|
|
its current viewport and compute its shortest side.
|
|
<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,
|
|
<a name="x2281"></a> v.<a href="qrect.html#top">top</a>() + (v.<a href="qrect.html#height">height</a>()-d)/2, d, d );
|
|
</pre>
|
|
<p> Then we set a new square viewport, centered in the old one.
|
|
<p> We're now done with our view. From this point on, when we draw in a
|
|
1000*1000 area around 0,0, what we draw will show up in the largest
|
|
possible square that'll fit in the output device.
|
|
<p> Time to start drawing.
|
|
<p> <pre> <a href="qpointarray.html">QPointArray</a> pts;
|
|
</pre>
|
|
<p> <em>pts</em> is just a temporary variable to hold some points.
|
|
<p> Next come three drawing blocks, one for the hour hand, one for the
|
|
minute hand and finally one for the clock face itself. First we draw
|
|
the hour hand:
|
|
<p> <pre> paint-><a href="qpainter.html#save">save</a>();
|
|
<a name="x2274"></a> paint-><a href="qpainter.html#rotate">rotate</a>( 30*(time.hour()%12-3) + time.minute()/2 );
|
|
</pre>
|
|
<p> We save the painter and then rotate it so that one axis points along
|
|
the hour hand.
|
|
<p> <pre> pts.setPoints( 4, -20,0, 0,-20, 300,0, 0,20 );
|
|
<a name="x2271"></a> paint-><a href="qpainter.html#drawConvexPolygon">drawConvexPolygon</a>( pts );
|
|
</pre>
|
|
<p> We set <em>pts</em> to a four-point polygon that looks like the hour hand at
|
|
three o'clock, and draw it. Because of the rotation, it's drawn
|
|
pointed in the right direction.
|
|
<p> <pre> <a name="x2273"></a> paint-><a href="qpainter.html#restore">restore</a>();
|
|
</pre>
|
|
<p> We restore the saved painter, undoing the rotation. We could also
|
|
call rotate( -30 ) but that might introduce rounding errors, so it's
|
|
better to use save() and restore(). Next, the minute hand, drawn
|
|
almost the same way:
|
|
<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> The only differences are how the rotation angle is computed and the
|
|
shape of the polygon.
|
|
<p> The last part to be drawn is the clock face itself.
|
|
<p> <pre> for ( int i=0; i<12; i++ ) {
|
|
<a name="x2272"></a> paint-><a href="qpainter.html#drawLine">drawLine</a>( 440,0, 460,0 );
|
|
paint-><a href="qpainter.html#rotate">rotate</a>( 30 );
|
|
}
|
|
</pre>
|
|
<p> Twelve short hour lines at thirty-degree intervals. At the end of
|
|
that, the painter is rotated in a way which isn't very useful, but
|
|
we're done with painting so that doesn't matter.
|
|
<p> <pre> paint-><a href="qpainter.html#restore">restore</a>();
|
|
}
|
|
</pre>
|
|
<p> The final line of the function restores the painter, so that the
|
|
caller won't be affected by all the transformations we've done.
|
|
<p>
|
|
<!-- eof -->
|
|
<p><address><hr><div align=center>
|
|
<table width=100% cellspacing=0 border=0><tr>
|
|
<td>Copyright © 2007
|
|
<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
|
|
<td align=right><div align=right>Qt 3.3.8</div>
|
|
</table></div></address></body>
|
|
</html>
|