From bd0f3345a938b35ce6a12f6150373b0955b8dd12 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 10 Jul 2011 15:24:15 -0500 Subject: Add Qt3 development HEAD version --- doc/html/coordsys.html | 215 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 doc/html/coordsys.html (limited to 'doc/html/coordsys.html') diff --git a/doc/html/coordsys.html b/doc/html/coordsys.html new file mode 100644 index 0000000..ee84473 --- /dev/null +++ b/doc/html/coordsys.html @@ -0,0 +1,215 @@ + + + + + +The Coordinate System + + + + + + + +
+ +Home + | +All Classes + | +Main Classes + | +Annotated + | +Grouped Classes + | +Functions +

The Coordinate System

+ + + +

A paint device in Qt is a drawable 2D +surface. QWidget, QPixmap, QPicture and QPrinter are all +paint devices. A QPainter is an object which can draw on such +devices. +

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. +

An Example +

+

The illustration below shows a highly magnified portion of the top +left corner of a paint device. +

+

The rectangle and the line were drawn by this code (with the grid +added and colors touched up in the illustration): +

+    void MyWidget::paintEvent( QPaintEvent * )
+    {
+        QPainter p( this );
+        p.setPen( darkGray );
+        p.drawRect( 1,2, 5,4 );
+        p.setPen( lightGray );
+        p.drawLine( 9,2, 7,7 );
+    }
+
+ +

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 QPainter. +

Similarly, the drawLine() call draws both endpoints of the line, not +just one. +

Here are the classes that relate most closely to the coordinate +system: +

+
QPoint +A single 2D point in the coordinate system. Most functions in +Qt that deal with points can accept either a QPoint argument +or two ints, for example QPainter::drawPoint(). +
QSize +A single 2D vector. Internally, QPoint and QSize 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 QWidget::resize(). +
QRect +A 2D rectangle. Most functions accept either a QRect or four +ints, for example QWidget::setGeometry(). +
QRegion +An arbitrary set of points, including all the normal set +operations, e.g. QRegion::intersect(), and also a less +usual function to return a list of rectangles whose union is +equal to the region. QRegion is used e.g. by QPainter::setClipRegion(), QWidget::repaint() and QPaintEvent::region(). +
QPainter +The class that paints. It can paint on any device with the +same code. There are differences between devices, QPrinter::newPage() is a good example, but QPainter works the +same way on all devices. +
QPaintDevice +A device on which QPainter can paint. There are two internal +devices, both pixel-based, and two external devices, QPrinter and QPicture (which records QPainter commands to a +file or other QIODevice, and plays them back). Other +devices can be defined. +
+

Transformations +

+

Although Qt's default coordinate system works as described above, QPainter also supports arbitrary transformations. +

This transformation engine is a three-step pipeline, closely following +the model outlined in books such as +Foley & Van Dam and the +OpenGL Programming Guide. Refer to those for in-depth +coverage; here we give just a brief overview and an example. +

The first step uses the world transformation matrix. Use this matrix +to orient and position your objects in your model. Qt provides +methods such as QPainter::rotate(), QPainter::scale(), QPainter::translate() and so on to operate on this matrix. +

QPainter::save() and QPainter::restore() save and restore this +matrix. You can also use QWMatrix objects, QPainter::worldMatrix() and QPainter::setWorldMatrix() to store and +use named matrices. +

The second step uses the window. The window describes the view +boundaries in model coordinates. The matrix positions the objects +and QPainter::setWindow() positions the window, deciding what +coordinates will be visible. (If you have 3D experience, the window +is what's usually called projection in 3D.) +

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. +

On-screen, the default is the entire QWidget or QPixmap 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. +

So each object to be drawn is transformed into model +coordinates using QPainter::worldMatrix(), then positioned +on the drawing device using QPainter::window() and +QPainter::viewport(). +

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 QPainter::scale() makes perfect sense. If your goal is to use a +fixed-size coordinate system, QPainter::setWindow() is +ideal. And so on. +

Here is a short example that uses all three mechanisms: the function +that draws the clock face in the aclock/aclock.cpp example. We +recommend compiling and running the example before you read any +further. In particular, try resizing the window to different sizes. +

+ +

    void AnalogClock::drawClock( QPainter *paint )
+    {
+        paint->save();
+
+

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. +

        paint->setWindow( -500,-500, 1000,1000 );
+
+

We set the model coordinate system we want a 1000*1000 window where +0,0 is in the middle. +

        QRect v = paint->viewport();
+        int d = QMIN( v.width(), v.height() );
+
+

The device may not be square and we want the clock to be, so we find +its current viewport and compute its shortest side. +

        paint->setViewport( v.left() + (v.width()-d)/2,
+                            v.top() + (v.height()-d)/2, d, d );
+
+

Then we set a new square viewport, centered in the old one. +

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. +

Time to start drawing. +

        QPointArray pts;
+
+

pts is just a temporary variable to hold some points. +

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: +

        paint->save();
+        paint->rotate( 30*(time.hour()%12-3) + time.minute()/2 );
+
+

We save the painter and then rotate it so that one axis points along +the hour hand. +

        pts.setPoints( 4, -20,0,  0,-20, 300,0, 0,20 );
+        paint->drawConvexPolygon( pts );
+
+

We set pts 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. +

        paint->restore();
+
+

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: +

        paint->save();
+        paint->rotate( (time.minute()-15)*6 );
+        pts.setPoints( 4, -10,0, 0,-10, 400,0, 0,10 );
+        paint->drawConvexPolygon( pts );
+        paint->restore();
+
+

The only differences are how the rotation angle is computed and the +shape of the polygon. +

The last part to be drawn is the clock face itself. +

        for ( int i=0; i<12; i++ ) {
+            paint->drawLine( 440,0, 460,0 );
+            paint->rotate( 30 );
+        }
+
+

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. +

        paint->restore();
+    }
+
+

The final line of the function restores the painter, so that the +caller won't be affected by all the transformations we've done. +

+ +


+ +
Copyright © 2007 +TrolltechTrademarks +
Qt 3.3.8
+
+ -- cgit v1.2.3