[556] | 1 | /****************************************************************************
|
---|
| 2 | **
|
---|
[846] | 3 | ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
---|
[556] | 4 | ** All rights reserved.
|
---|
| 5 | ** Contact: Nokia Corporation ([email protected])
|
---|
| 6 | **
|
---|
| 7 | ** This file is part of the QtDeclarative module of the Qt Toolkit.
|
---|
| 8 | **
|
---|
| 9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
| 10 | ** Commercial Usage
|
---|
| 11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
| 12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
| 13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
| 14 | ** a written agreement between you and Nokia.
|
---|
| 15 | **
|
---|
| 16 | ** GNU Lesser General Public License Usage
|
---|
| 17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
| 18 | ** General Public License version 2.1 as published by the Free Software
|
---|
| 19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
| 20 | ** packaging of this file. Please review the following information to
|
---|
| 21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
| 22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
| 23 | **
|
---|
| 24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
| 25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
| 26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
| 27 | **
|
---|
| 28 | ** GNU General Public License Usage
|
---|
| 29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
| 30 | ** General Public License version 3.0 as published by the Free Software
|
---|
| 31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
| 32 | ** packaging of this file. Please review the following information to
|
---|
| 33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
| 34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
| 35 | **
|
---|
| 36 | ** If you have questions regarding the use of this file, please contact
|
---|
| 37 | ** Nokia at [email protected].
|
---|
| 38 | ** $QT_END_LICENSE$
|
---|
| 39 | **
|
---|
| 40 | ****************************************************************************/
|
---|
| 41 |
|
---|
| 42 | /*!
|
---|
| 43 | \class QGraphicsTransform
|
---|
| 44 | \brief The QGraphicsTransform class is an abstract base class for building
|
---|
| 45 | advanced transformations on QGraphicsItems.
|
---|
| 46 | \since 4.6
|
---|
| 47 | \ingroup graphicsview-api
|
---|
| 48 |
|
---|
| 49 | As an alternative to QGraphicsItem::transform, QGraphicsTransform lets you
|
---|
| 50 | create and control advanced transformations that can be configured
|
---|
| 51 | independently using specialized properties.
|
---|
| 52 |
|
---|
| 53 | QGraphicsItem allows you to assign any number of QGraphicsTransform
|
---|
| 54 | instances to one QGraphicsItem. Each QGraphicsTransform is applied in
|
---|
| 55 | order, one at a time, to the QGraphicsItem it's assigned to.
|
---|
| 56 |
|
---|
[846] | 57 | QGraphicsTransform is particularly useful for animations. Whereas
|
---|
[556] | 58 | QGraphicsItem::setTransform() lets you assign any transform directly to an
|
---|
| 59 | item, there is no direct way to interpolate between two different
|
---|
| 60 | transformations (e.g., when transitioning between two states, each for
|
---|
| 61 | which the item has a different arbitrary transform assigned). Using
|
---|
| 62 | QGraphicsTransform you can interpolate the property values of each
|
---|
| 63 | independent transformation. The resulting operation is then combined into a
|
---|
| 64 | single transform which is applied to QGraphicsItem.
|
---|
| 65 |
|
---|
| 66 | Transformations are computed in true 3D space using QMatrix4x4.
|
---|
| 67 | When the transformation is applied to a QGraphicsItem, it will be
|
---|
| 68 | projected back to a 2D QTransform. When multiple QGraphicsTransform
|
---|
| 69 | objects are applied to a QGraphicsItem, all of the transformations
|
---|
| 70 | are computed in true 3D space, with the projection back to 2D
|
---|
| 71 | only occurring after the last QGraphicsTransform is applied.
|
---|
| 72 | The exception to this is QGraphicsRotation, which projects back to
|
---|
| 73 | 2D after each rotation to preserve the perspective effect around
|
---|
| 74 | the X and Y axes.
|
---|
| 75 |
|
---|
| 76 | If you want to create your own configurable transformation, you can create
|
---|
| 77 | a subclass of QGraphicsTransform (or any or the existing subclasses), and
|
---|
| 78 | reimplement the pure virtual applyTo() function, which takes a pointer to a
|
---|
| 79 | QMatrix4x4. Each operation you would like to apply should be exposed as
|
---|
| 80 | properties (e.g., customTransform->setVerticalShear(2.5)). Inside you
|
---|
| 81 | reimplementation of applyTo(), you can modify the provided transform
|
---|
| 82 | respectively.
|
---|
| 83 |
|
---|
| 84 | QGraphicsTransform can be used together with QGraphicsItem::setTransform(),
|
---|
| 85 | QGraphicsItem::setRotation(), and QGraphicsItem::setScale().
|
---|
| 86 |
|
---|
| 87 | \sa QGraphicsItem::transform(), QGraphicsScale, QGraphicsRotation
|
---|
| 88 | */
|
---|
| 89 |
|
---|
| 90 | #include "qgraphicstransform.h"
|
---|
| 91 | #include "qgraphicsitem_p.h"
|
---|
| 92 | #include "qgraphicstransform_p.h"
|
---|
| 93 | #include <QDebug>
|
---|
| 94 | #include <QtCore/qmath.h>
|
---|
| 95 |
|
---|
| 96 | #ifndef QT_NO_GRAPHICSVIEW
|
---|
| 97 | QT_BEGIN_NAMESPACE
|
---|
| 98 | void QGraphicsTransformPrivate::setItem(QGraphicsItem *i)
|
---|
| 99 | {
|
---|
| 100 | if (item == i)
|
---|
| 101 | return;
|
---|
| 102 |
|
---|
| 103 | if (item) {
|
---|
| 104 | Q_Q(QGraphicsTransform);
|
---|
| 105 | QGraphicsItemPrivate *d_ptr = item->d_ptr.data();
|
---|
| 106 |
|
---|
| 107 | item->prepareGeometryChange();
|
---|
| 108 | Q_ASSERT(d_ptr->transformData);
|
---|
| 109 | d_ptr->transformData->graphicsTransforms.removeAll(q);
|
---|
| 110 | d_ptr->dirtySceneTransform = 1;
|
---|
| 111 | item = 0;
|
---|
| 112 | }
|
---|
| 113 |
|
---|
| 114 | item = i;
|
---|
| 115 | }
|
---|
| 116 |
|
---|
| 117 | void QGraphicsTransformPrivate::updateItem(QGraphicsItem *item)
|
---|
| 118 | {
|
---|
| 119 | item->prepareGeometryChange();
|
---|
| 120 | item->d_ptr->dirtySceneTransform = 1;
|
---|
| 121 | }
|
---|
| 122 |
|
---|
| 123 | /*!
|
---|
| 124 | Constructs a new QGraphicsTransform with the given \a parent.
|
---|
| 125 | */
|
---|
| 126 | QGraphicsTransform::QGraphicsTransform(QObject *parent)
|
---|
| 127 | : QObject(*new QGraphicsTransformPrivate, parent)
|
---|
| 128 | {
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | /*!
|
---|
| 132 | Destroys the graphics transform.
|
---|
| 133 | */
|
---|
| 134 | QGraphicsTransform::~QGraphicsTransform()
|
---|
| 135 | {
|
---|
| 136 | Q_D(QGraphicsTransform);
|
---|
| 137 | d->setItem(0);
|
---|
| 138 | }
|
---|
| 139 |
|
---|
| 140 | /*!
|
---|
| 141 | \internal
|
---|
| 142 | */
|
---|
| 143 | QGraphicsTransform::QGraphicsTransform(QGraphicsTransformPrivate &p, QObject *parent)
|
---|
| 144 | : QObject(p, parent)
|
---|
| 145 | {
|
---|
| 146 | }
|
---|
| 147 |
|
---|
| 148 | /*!
|
---|
| 149 | \fn void QGraphicsTransform::applyTo(QMatrix4x4 *matrix) const
|
---|
| 150 |
|
---|
| 151 | This pure virtual method has to be reimplemented in derived classes.
|
---|
| 152 |
|
---|
| 153 | It applies this transformation to \a matrix.
|
---|
| 154 |
|
---|
| 155 | \sa QGraphicsItem::transform(), QMatrix4x4::toTransform()
|
---|
| 156 | */
|
---|
| 157 |
|
---|
| 158 | /*!
|
---|
| 159 | Notifies that this transform operation has changed its parameters in such a
|
---|
| 160 | way that applyTo() will return a different result than before.
|
---|
| 161 |
|
---|
| 162 | When implementing you own custom graphics transform, you must call this
|
---|
| 163 | function every time you change a parameter, to let QGraphicsItem know that
|
---|
| 164 | its transformation needs to be updated.
|
---|
| 165 |
|
---|
| 166 | \sa applyTo()
|
---|
| 167 | */
|
---|
| 168 | void QGraphicsTransform::update()
|
---|
| 169 | {
|
---|
| 170 | Q_D(QGraphicsTransform);
|
---|
| 171 | if (d->item)
|
---|
| 172 | d->updateItem(d->item);
|
---|
| 173 | }
|
---|
| 174 |
|
---|
| 175 | /*!
|
---|
| 176 | \class QGraphicsScale
|
---|
| 177 | \brief The QGraphicsScale class provides a scale transformation.
|
---|
| 178 | \since 4.6
|
---|
| 179 |
|
---|
| 180 | QGraphicsScene provides certain parameters to help control how the scale
|
---|
| 181 | should be applied.
|
---|
| 182 |
|
---|
| 183 | The origin is the point that the item is scaled from (i.e., it stays fixed
|
---|
| 184 | relative to the parent as the rest of the item grows). By default the
|
---|
| 185 | origin is QPointF(0, 0).
|
---|
| 186 |
|
---|
| 187 | The parameters xScale, yScale, and zScale describe the scale factors to
|
---|
| 188 | apply in horizontal, vertical, and depth directions. They can take on any
|
---|
| 189 | value, including 0 (to collapse the item to a point) or negative value.
|
---|
| 190 | A negative xScale value will mirror the item horizontally. A negative yScale
|
---|
| 191 | value will flip the item vertically. A negative zScale will flip the
|
---|
| 192 | item end for end.
|
---|
| 193 |
|
---|
| 194 | \sa QGraphicsTransform, QGraphicsItem::setScale(), QTransform::scale()
|
---|
| 195 | */
|
---|
| 196 |
|
---|
| 197 | class QGraphicsScalePrivate : public QGraphicsTransformPrivate
|
---|
| 198 | {
|
---|
| 199 | public:
|
---|
| 200 | QGraphicsScalePrivate()
|
---|
| 201 | : xScale(1), yScale(1), zScale(1) {}
|
---|
| 202 | QVector3D origin;
|
---|
| 203 | qreal xScale;
|
---|
| 204 | qreal yScale;
|
---|
| 205 | qreal zScale;
|
---|
| 206 | };
|
---|
| 207 |
|
---|
| 208 | /*!
|
---|
| 209 | Constructs an empty QGraphicsScale object with the given \a parent.
|
---|
| 210 | */
|
---|
| 211 | QGraphicsScale::QGraphicsScale(QObject *parent)
|
---|
| 212 | : QGraphicsTransform(*new QGraphicsScalePrivate, parent)
|
---|
| 213 | {
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 | /*!
|
---|
| 217 | Destroys the graphics scale.
|
---|
| 218 | */
|
---|
| 219 | QGraphicsScale::~QGraphicsScale()
|
---|
| 220 | {
|
---|
| 221 | }
|
---|
| 222 |
|
---|
| 223 | /*!
|
---|
| 224 | \property QGraphicsScale::origin
|
---|
| 225 | \brief the origin of the scale in 3D space.
|
---|
| 226 |
|
---|
| 227 | All scaling will be done relative to this point (i.e., this point
|
---|
| 228 | will stay fixed, relative to the parent, when the item is scaled).
|
---|
| 229 |
|
---|
| 230 | \sa xScale, yScale, zScale
|
---|
| 231 | */
|
---|
| 232 | QVector3D QGraphicsScale::origin() const
|
---|
| 233 | {
|
---|
| 234 | Q_D(const QGraphicsScale);
|
---|
| 235 | return d->origin;
|
---|
| 236 | }
|
---|
| 237 | void QGraphicsScale::setOrigin(const QVector3D &point)
|
---|
| 238 | {
|
---|
| 239 | Q_D(QGraphicsScale);
|
---|
| 240 | if (d->origin == point)
|
---|
| 241 | return;
|
---|
| 242 | d->origin = point;
|
---|
| 243 | update();
|
---|
| 244 | emit originChanged();
|
---|
| 245 | }
|
---|
| 246 |
|
---|
| 247 | /*!
|
---|
| 248 | \property QGraphicsScale::xScale
|
---|
| 249 | \brief the horizontal scale factor.
|
---|
| 250 |
|
---|
| 251 | The scale factor can be any real number; the default value is 1.0. If you
|
---|
| 252 | set the factor to 0.0, the item will be collapsed to a single point. If you
|
---|
| 253 | provide a negative value, the item will be mirrored horizontally around its
|
---|
| 254 | origin.
|
---|
| 255 |
|
---|
| 256 | \sa yScale, zScale, origin
|
---|
| 257 | */
|
---|
| 258 | qreal QGraphicsScale::xScale() const
|
---|
| 259 | {
|
---|
| 260 | Q_D(const QGraphicsScale);
|
---|
| 261 | return d->xScale;
|
---|
| 262 | }
|
---|
| 263 | void QGraphicsScale::setXScale(qreal scale)
|
---|
| 264 | {
|
---|
| 265 | Q_D(QGraphicsScale);
|
---|
| 266 | if (d->xScale == scale)
|
---|
| 267 | return;
|
---|
| 268 | d->xScale = scale;
|
---|
| 269 | update();
|
---|
[846] | 270 | emit xScaleChanged();
|
---|
[556] | 271 | emit scaleChanged();
|
---|
| 272 | }
|
---|
| 273 |
|
---|
| 274 | /*!
|
---|
| 275 | \property QGraphicsScale::yScale
|
---|
| 276 | \brief the vertical scale factor.
|
---|
| 277 |
|
---|
| 278 | The scale factor can be any real number; the default value is 1.0. If you
|
---|
| 279 | set the factor to 0.0, the item will be collapsed to a single point. If you
|
---|
| 280 | provide a negative value, the item will be flipped vertically around its
|
---|
| 281 | origin.
|
---|
| 282 |
|
---|
| 283 | \sa xScale, zScale, origin
|
---|
| 284 | */
|
---|
| 285 | qreal QGraphicsScale::yScale() const
|
---|
| 286 | {
|
---|
| 287 | Q_D(const QGraphicsScale);
|
---|
| 288 | return d->yScale;
|
---|
| 289 | }
|
---|
| 290 | void QGraphicsScale::setYScale(qreal scale)
|
---|
| 291 | {
|
---|
| 292 | Q_D(QGraphicsScale);
|
---|
| 293 | if (d->yScale == scale)
|
---|
| 294 | return;
|
---|
| 295 | d->yScale = scale;
|
---|
| 296 | update();
|
---|
[846] | 297 | emit yScaleChanged();
|
---|
[556] | 298 | emit scaleChanged();
|
---|
| 299 | }
|
---|
| 300 |
|
---|
| 301 | /*!
|
---|
| 302 | \property QGraphicsScale::zScale
|
---|
| 303 | \brief the depth scale factor.
|
---|
| 304 |
|
---|
| 305 | The scale factor can be any real number; the default value is 1.0. If you
|
---|
| 306 | set the factor to 0.0, the item will be collapsed to a single point. If you
|
---|
| 307 | provide a negative value, the item will be flipped end for end around its
|
---|
| 308 | origin.
|
---|
| 309 |
|
---|
| 310 | \sa xScale, yScale, origin
|
---|
| 311 | */
|
---|
| 312 | qreal QGraphicsScale::zScale() const
|
---|
| 313 | {
|
---|
| 314 | Q_D(const QGraphicsScale);
|
---|
| 315 | return d->zScale;
|
---|
| 316 | }
|
---|
| 317 | void QGraphicsScale::setZScale(qreal scale)
|
---|
| 318 | {
|
---|
| 319 | Q_D(QGraphicsScale);
|
---|
| 320 | if (d->zScale == scale)
|
---|
| 321 | return;
|
---|
| 322 | d->zScale = scale;
|
---|
| 323 | update();
|
---|
[846] | 324 | emit zScaleChanged();
|
---|
[556] | 325 | emit scaleChanged();
|
---|
| 326 | }
|
---|
| 327 |
|
---|
| 328 | /*!
|
---|
| 329 | \reimp
|
---|
| 330 | */
|
---|
| 331 | void QGraphicsScale::applyTo(QMatrix4x4 *matrix) const
|
---|
| 332 | {
|
---|
| 333 | Q_D(const QGraphicsScale);
|
---|
| 334 | matrix->translate(d->origin);
|
---|
| 335 | matrix->scale(d->xScale, d->yScale, d->zScale);
|
---|
| 336 | matrix->translate(-d->origin);
|
---|
| 337 | }
|
---|
| 338 |
|
---|
| 339 | /*!
|
---|
| 340 | \fn QGraphicsScale::originChanged()
|
---|
| 341 |
|
---|
| 342 | QGraphicsScale emits this signal when its origin changes.
|
---|
| 343 |
|
---|
| 344 | \sa QGraphicsScale::origin
|
---|
| 345 | */
|
---|
| 346 |
|
---|
| 347 | /*!
|
---|
[846] | 348 | \fn QGraphicsScale::xScaleChanged()
|
---|
| 349 | \since 4.7
|
---|
| 350 |
|
---|
| 351 | This signal is emitted whenever the \l xScale property changes.
|
---|
| 352 | */
|
---|
| 353 |
|
---|
| 354 | /*!
|
---|
| 355 | \fn QGraphicsScale::yScaleChanged()
|
---|
| 356 | \since 4.7
|
---|
| 357 |
|
---|
| 358 | This signal is emitted whenever the \l yScale property changes.
|
---|
| 359 | */
|
---|
| 360 |
|
---|
| 361 | /*!
|
---|
| 362 | \fn QGraphicsScale::zScaleChanged()
|
---|
| 363 | \since 4.7
|
---|
| 364 |
|
---|
| 365 | This signal is emitted whenever the \l zScale property changes.
|
---|
| 366 | */
|
---|
| 367 |
|
---|
| 368 | /*!
|
---|
[556] | 369 | \fn QGraphicsScale::scaleChanged()
|
---|
| 370 |
|
---|
| 371 | This signal is emitted whenever the xScale, yScale, or zScale
|
---|
| 372 | of the object changes.
|
---|
| 373 |
|
---|
| 374 | \sa QGraphicsScale::xScale, QGraphicsScale::yScale
|
---|
| 375 | \sa QGraphicsScale::zScale
|
---|
| 376 | */
|
---|
| 377 |
|
---|
| 378 | /*!
|
---|
| 379 | \class QGraphicsRotation
|
---|
| 380 | \brief The QGraphicsRotation class provides a rotation transformation around
|
---|
| 381 | a given axis.
|
---|
| 382 | \since 4.6
|
---|
| 383 |
|
---|
| 384 | You can provide the desired axis by assigning a QVector3D to the axis property
|
---|
| 385 | or by passing a member if Qt::Axis to the setAxis convenience function.
|
---|
| 386 | By default the axis is (0, 0, 1) i.e., rotation around the Z axis.
|
---|
| 387 |
|
---|
| 388 | The angle property, which is provided by QGraphicsRotation, now
|
---|
| 389 | describes the number of degrees to rotate around this axis.
|
---|
| 390 |
|
---|
| 391 | QGraphicsRotation provides certain parameters to help control how the
|
---|
| 392 | rotation should be applied.
|
---|
| 393 |
|
---|
| 394 | The origin is the point that the item is rotated around (i.e., it stays
|
---|
| 395 | fixed relative to the parent as the rest of the item is rotated). By
|
---|
| 396 | default the origin is QPointF(0, 0).
|
---|
| 397 |
|
---|
| 398 | The angle property provides the number of degrees to rotate the item
|
---|
| 399 | clockwise around the origin. This value also be negative, indicating a
|
---|
| 400 | counter-clockwise rotation. For animation purposes it may also be useful to
|
---|
| 401 | provide rotation angles exceeding (-360, 360) degrees, for instance to
|
---|
| 402 | animate how an item rotates several times.
|
---|
| 403 |
|
---|
| 404 | Note: the final rotation is the combined effect of a rotation in
|
---|
| 405 | 3D space followed by a projection back to 2D. If several rotations
|
---|
| 406 | are performed in succession, they will not behave as expected unless
|
---|
| 407 | they were all around the Z axis.
|
---|
| 408 |
|
---|
| 409 | \sa QGraphicsTransform, QGraphicsItem::setRotation(), QTransform::rotate()
|
---|
| 410 | */
|
---|
| 411 |
|
---|
| 412 | class QGraphicsRotationPrivate : public QGraphicsTransformPrivate
|
---|
| 413 | {
|
---|
| 414 | public:
|
---|
| 415 | QGraphicsRotationPrivate()
|
---|
| 416 | : angle(0), axis(0, 0, 1) {}
|
---|
| 417 | QVector3D origin;
|
---|
| 418 | qreal angle;
|
---|
| 419 | QVector3D axis;
|
---|
| 420 | };
|
---|
| 421 |
|
---|
| 422 | /*!
|
---|
| 423 | Constructs a new QGraphicsRotation with the given \a parent.
|
---|
| 424 | */
|
---|
| 425 | QGraphicsRotation::QGraphicsRotation(QObject *parent)
|
---|
| 426 | : QGraphicsTransform(*new QGraphicsRotationPrivate, parent)
|
---|
| 427 | {
|
---|
| 428 | }
|
---|
| 429 |
|
---|
| 430 | /*!
|
---|
| 431 | Destroys the graphics rotation.
|
---|
| 432 | */
|
---|
| 433 | QGraphicsRotation::~QGraphicsRotation()
|
---|
| 434 | {
|
---|
| 435 | }
|
---|
| 436 |
|
---|
| 437 | /*!
|
---|
| 438 | \property QGraphicsRotation::origin
|
---|
| 439 | \brief the origin of the rotation in 3D space.
|
---|
| 440 |
|
---|
| 441 | All rotations will be done relative to this point (i.e., this point
|
---|
| 442 | will stay fixed, relative to the parent, when the item is rotated).
|
---|
| 443 |
|
---|
| 444 | \sa angle
|
---|
| 445 | */
|
---|
| 446 | QVector3D QGraphicsRotation::origin() const
|
---|
| 447 | {
|
---|
| 448 | Q_D(const QGraphicsRotation);
|
---|
| 449 | return d->origin;
|
---|
| 450 | }
|
---|
| 451 | void QGraphicsRotation::setOrigin(const QVector3D &point)
|
---|
| 452 | {
|
---|
| 453 | Q_D(QGraphicsRotation);
|
---|
| 454 | if (d->origin == point)
|
---|
| 455 | return;
|
---|
| 456 | d->origin = point;
|
---|
| 457 | update();
|
---|
| 458 | emit originChanged();
|
---|
| 459 | }
|
---|
| 460 |
|
---|
| 461 | /*!
|
---|
| 462 | \property QGraphicsRotation::angle
|
---|
| 463 | \brief the angle for clockwise rotation, in degrees.
|
---|
| 464 |
|
---|
| 465 | The angle can be any real number; the default value is 0.0. A value of 180
|
---|
| 466 | will rotate 180 degrees, clockwise. If you provide a negative number, the
|
---|
| 467 | item will be rotated counter-clockwise. Normally the rotation angle will be
|
---|
| 468 | in the range (-360, 360), but you can also provide numbers outside of this
|
---|
| 469 | range (e.g., a angle of 370 degrees gives the same result as 10 degrees).
|
---|
| 470 |
|
---|
| 471 | \sa origin
|
---|
| 472 | */
|
---|
| 473 | qreal QGraphicsRotation::angle() const
|
---|
| 474 | {
|
---|
| 475 | Q_D(const QGraphicsRotation);
|
---|
| 476 | return d->angle;
|
---|
| 477 | }
|
---|
| 478 | void QGraphicsRotation::setAngle(qreal angle)
|
---|
| 479 | {
|
---|
| 480 | Q_D(QGraphicsRotation);
|
---|
| 481 | if (d->angle == angle)
|
---|
| 482 | return;
|
---|
| 483 | d->angle = angle;
|
---|
| 484 | update();
|
---|
| 485 | emit angleChanged();
|
---|
| 486 | }
|
---|
| 487 |
|
---|
| 488 | /*!
|
---|
| 489 | \fn QGraphicsRotation::originChanged()
|
---|
| 490 |
|
---|
| 491 | This signal is emitted whenever the origin has changed.
|
---|
| 492 |
|
---|
| 493 | \sa QGraphicsRotation::origin
|
---|
| 494 | */
|
---|
| 495 |
|
---|
| 496 | /*!
|
---|
| 497 | \fn void QGraphicsRotation::angleChanged()
|
---|
| 498 |
|
---|
| 499 | This signal is emitted whenever the angle has changed.
|
---|
| 500 |
|
---|
| 501 | \sa QGraphicsRotation::angle
|
---|
| 502 | */
|
---|
| 503 |
|
---|
| 504 | /*!
|
---|
| 505 | \property QGraphicsRotation::axis
|
---|
| 506 | \brief a rotation axis, specified by a vector in 3D space.
|
---|
| 507 |
|
---|
| 508 | This can be any axis in 3D space. By default the axis is (0, 0, 1),
|
---|
| 509 | which is aligned with the Z axis. If you provide another axis,
|
---|
| 510 | QGraphicsRotation will provide a transformation that rotates
|
---|
| 511 | around this axis. For example, if you would like to rotate an item
|
---|
| 512 | around its X axis, you could pass (1, 0, 0) as the axis.
|
---|
| 513 |
|
---|
| 514 | \sa QTransform, QGraphicsRotation::angle
|
---|
| 515 | */
|
---|
| 516 | QVector3D QGraphicsRotation::axis() const
|
---|
| 517 | {
|
---|
| 518 | Q_D(const QGraphicsRotation);
|
---|
| 519 | return d->axis;
|
---|
| 520 | }
|
---|
| 521 | void QGraphicsRotation::setAxis(const QVector3D &axis)
|
---|
| 522 | {
|
---|
| 523 | Q_D(QGraphicsRotation);
|
---|
| 524 | if (d->axis == axis)
|
---|
| 525 | return;
|
---|
| 526 | d->axis = axis;
|
---|
| 527 | update();
|
---|
| 528 | emit axisChanged();
|
---|
| 529 | }
|
---|
| 530 |
|
---|
| 531 | /*!
|
---|
| 532 | \fn void QGraphicsRotation::setAxis(Qt::Axis axis)
|
---|
| 533 |
|
---|
| 534 | Convenience function to set the axis to \a axis.
|
---|
| 535 |
|
---|
| 536 | Note: the Qt::YAxis rotation for QTransform is inverted from the
|
---|
| 537 | correct mathematical rotation in 3D space. The QGraphicsRotation
|
---|
| 538 | class implements a correct mathematical rotation. The following
|
---|
| 539 | two sequences of code will perform the same transformation:
|
---|
| 540 |
|
---|
| 541 | \code
|
---|
| 542 | QTransform t;
|
---|
| 543 | t.rotate(45, Qt::YAxis);
|
---|
| 544 |
|
---|
| 545 | QGraphicsRotation r;
|
---|
| 546 | r.setAxis(Qt::YAxis);
|
---|
| 547 | r.setAngle(-45);
|
---|
| 548 | \endcode
|
---|
| 549 | */
|
---|
| 550 | void QGraphicsRotation::setAxis(Qt::Axis axis)
|
---|
| 551 | {
|
---|
| 552 | switch (axis)
|
---|
| 553 | {
|
---|
| 554 | case Qt::XAxis:
|
---|
| 555 | setAxis(QVector3D(1, 0, 0));
|
---|
| 556 | break;
|
---|
| 557 | case Qt::YAxis:
|
---|
| 558 | setAxis(QVector3D(0, 1, 0));
|
---|
| 559 | break;
|
---|
| 560 | case Qt::ZAxis:
|
---|
| 561 | setAxis(QVector3D(0, 0, 1));
|
---|
| 562 | break;
|
---|
| 563 | }
|
---|
| 564 | }
|
---|
| 565 |
|
---|
| 566 | /*!
|
---|
| 567 | \reimp
|
---|
| 568 | */
|
---|
| 569 | void QGraphicsRotation::applyTo(QMatrix4x4 *matrix) const
|
---|
| 570 | {
|
---|
| 571 | Q_D(const QGraphicsRotation);
|
---|
| 572 |
|
---|
| 573 | if (d->angle == 0. || d->axis.isNull())
|
---|
| 574 | return;
|
---|
| 575 |
|
---|
| 576 | matrix->translate(d->origin);
|
---|
| 577 | matrix->projectedRotate(d->angle, d->axis.x(), d->axis.y(), d->axis.z());
|
---|
| 578 | matrix->translate(-d->origin);
|
---|
| 579 | }
|
---|
| 580 |
|
---|
| 581 | /*!
|
---|
| 582 | \fn void QGraphicsRotation::axisChanged()
|
---|
| 583 |
|
---|
| 584 | This signal is emitted whenever the axis of the object changes.
|
---|
| 585 |
|
---|
| 586 | \sa QGraphicsRotation::axis
|
---|
| 587 | */
|
---|
| 588 |
|
---|
| 589 | #include "moc_qgraphicstransform.cpp"
|
---|
| 590 |
|
---|
| 591 | QT_END_NAMESPACE
|
---|
| 592 | #endif //QT_NO_GRAPHICSVIEW
|
---|