FloatSize AffineTransform::mapSize(const FloatSize& size) const { double width2 = size.width() * xScale(); double height2 = size.height() * yScale(); return FloatSize(narrowPrecisionToFloat(width2), narrowPrecisionToFloat(height2)); }
IntSize AffineTransform::mapSize(const IntSize& size) const { double width2 = size.width() * xScale(); double height2 = size.height() * yScale(); return IntSize(lround(width2), lround(height2)); }
int QGraphicsScale::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QGraphicsTransform::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { if (_id < 5) qt_static_metacall(this, _c, _id, _a); _id -= 5; } #ifndef QT_NO_PROPERTIES else if (_c == QMetaObject::ReadProperty) { void *_v = _a[0]; switch (_id) { case 0: *reinterpret_cast< QVector3D*>(_v) = origin(); break; case 1: *reinterpret_cast< qreal*>(_v) = xScale(); break; case 2: *reinterpret_cast< qreal*>(_v) = yScale(); break; case 3: *reinterpret_cast< qreal*>(_v) = zScale(); break; } _id -= 4; } else if (_c == QMetaObject::WriteProperty) { void *_v = _a[0]; switch (_id) { case 0: setOrigin(*reinterpret_cast< QVector3D*>(_v)); break; case 1: setXScale(*reinterpret_cast< qreal*>(_v)); break; case 2: setYScale(*reinterpret_cast< qreal*>(_v)); break; case 3: setZScale(*reinterpret_cast< qreal*>(_v)); break; } _id -= 4; } else if (_c == QMetaObject::ResetProperty) { _id -= 4; } else if (_c == QMetaObject::QueryPropertyDesignable) { _id -= 4; } else if (_c == QMetaObject::QueryPropertyScriptable) { _id -= 4; } else if (_c == QMetaObject::QueryPropertyStored) { _id -= 4; } else if (_c == QMetaObject::QueryPropertyEditable) { _id -= 4; } else if (_c == QMetaObject::QueryPropertyUser) { _id -= 4; } #endif // QT_NO_PROPERTIES return _id; }
bool AffineTransform::decompose(DecomposedType& decomp) const { AffineTransform m(*this); // Compute scaling factors double sx = xScale(); double sy = yScale(); // Compute cross product of transformed unit vectors. If negative, // one axis was flipped. if (m.a() * m.d() - m.c() * m.b() < 0) { // Flip axis with minimum unit vector dot product if (m.a() < m.d()) sx = -sx; else sy = -sy; } // Remove scale from matrix m.scale(1 / sx, 1 / sy); // Compute rotation double angle = atan2(m.b(), m.a()); // Remove rotation from matrix m.rotateRadians(-angle); // Return results decomp.scaleX = sx; decomp.scaleY = sy; decomp.angle = angle; decomp.remainderA = m.a(); decomp.remainderB = m.b(); decomp.remainderC = m.c(); decomp.remainderD = m.d(); decomp.translateX = m.e(); decomp.translateY = m.f(); return true; }
void ViewingArea::update_projection_matrices() { // if the inset is asymmetric, shift the viewing volume accordingly GLfloat xShift((insetCenter_[X_INDEX]-centerAndRelative_[X_INDEX])/centerAndRelative_[X_INDEX]); GLfloat yShift((insetCenter_[Y_INDEX]-centerAndRelative_[Y_INDEX])/centerAndRelative_[Y_INDEX]); // if the inset is smaller than the window, rescale the viewing volume accordingly; GLfloat xScale((insetRelative_[X_INDEX]/centerAndRelative_[X_INDEX])); GLfloat yScale((insetRelative_[Y_INDEX]/centerAndRelative_[Y_INDEX])); // correct for the aspect ratio of the inset; GLfloat r(insetRelative_[X_INDEX]/insetRelative_[Y_INDEX]); if(r>1) xScale/=r; else yScale*=r; // check if we have orthogonal projection if(!(angle_>0)) { projectionMatrix_[X_INDEX+N_ROWS*X_INDEX]=xScale;inverseProjectionMatrix_[X_INDEX+N_ROWS*X_INDEX]=1/xScale; projectionMatrix_[Y_INDEX+N_ROWS*Y_INDEX]=yScale;inverseProjectionMatrix_[Y_INDEX+N_ROWS*Y_INDEX]=1/yScale; projectionMatrix_[Z_INDEX+N_ROWS*Z_INDEX]=-zScaleOrtho_;inverseProjectionMatrix_[Z_INDEX+N_ROWS*Z_INDEX]=-1/zScaleOrtho_; projectionMatrix_[X_INDEX+N_ROWS*N_SPATIAL_DIMENSIONS]=xShift;inverseProjectionMatrix_[X_INDEX+N_ROWS*N_SPATIAL_DIMENSIONS]=-xShift/xScale; projectionMatrix_[Y_INDEX+N_ROWS*N_SPATIAL_DIMENSIONS]=yShift;inverseProjectionMatrix_[Y_INDEX+N_ROWS*N_SPATIAL_DIMENSIONS]=-yShift/yScale; } else // perspective projection { /* The original (-1,-1,-1) - (1,1,1) viewing volume must be rescaled to fit into the window depending on its distance from the camera. */ xScale*=(zShift_+zCamera_); yScale*=(zShift_+zCamera_); // set near and far clipping planes (magic numbers right now -> find better way) GLfloat n(zShift_/10); GLfloat f(zShift_*10); /* put together the perspective projection everything together in this order: scale x, y and z in camera space, shift z in camera space, apply perspective transformation (as in gluPerspective, aspect ratio is already built into xScale and yScale) shift x and y in screen space (shifting in camera space would decenter the frustum) the projection matrix below is the product of all these transformations */ /* note that zShift_ is positive, with larger values equivalent to a larger distance from the viewer. In camera space, however, negative values are further away from the viewer. zShift_ enters the projection matrix below such that a large positive value of zShift_ will create a large negative shift in the z coordinate of the input vector. */ a_=(-(f+n)/(f-n)); b_=(-2.0f*(f*n)/(f-n)); // first column projectionMatrix_[X_INDEX+N_ROWS*X_INDEX]=xScale;inverseProjectionMatrix_[X_INDEX+N_ROWS*X_INDEX]=1/xScale; // second column projectionMatrix_[Y_INDEX+N_ROWS*Y_INDEX]=yScale;inverseProjectionMatrix_[Y_INDEX+N_ROWS*Y_INDEX]=1/yScale; // third column projectionMatrix_[N_ROWS*Z_INDEX+X_INDEX]=-xShift; projectionMatrix_[N_ROWS*Z_INDEX+Y_INDEX]=-yShift; projectionMatrix_[N_ROWS*Z_INDEX+Z_INDEX]=a_;inverseProjectionMatrix_[N_ROWS*Z_INDEX+Z_INDEX]=zShift_/b_; projectionMatrix_[N_ROWS*Z_INDEX+N_SPATIAL_DIMENSIONS]=-1;inverseProjectionMatrix_[N_ROWS*Z_INDEX+N_SPATIAL_DIMENSIONS]=1/b_; // fourth column projectionMatrix_[N_ROWS*N_SPATIAL_DIMENSIONS+X_INDEX]=zShift_*xShift;inverseProjectionMatrix_[N_ROWS*N_SPATIAL_DIMENSIONS+X_INDEX]=-xShift/xScale; projectionMatrix_[N_ROWS*N_SPATIAL_DIMENSIONS+Y_INDEX]=zShift_*yShift;inverseProjectionMatrix_[N_ROWS*N_SPATIAL_DIMENSIONS+Y_INDEX]=-yShift/yScale; projectionMatrix_[N_ROWS*N_SPATIAL_DIMENSIONS+Z_INDEX]=-a_*zShift_+b_;inverseProjectionMatrix_[N_ROWS*N_SPATIAL_DIMENSIONS+Z_INDEX]=a_*zShift_/b_-1; projectionMatrix_[N_ROWS*N_SPATIAL_DIMENSIONS+N_SPATIAL_DIMENSIONS]=zShift_;inverseProjectionMatrix_[N_ROWS*N_SPATIAL_DIMENSIONS+N_SPATIAL_DIMENSIONS]=a_/b_; } glContext_->update_global_uniform_4x4(GLContext::PROJECTION_MATRIX,projectionMatrix_); glContext_->update_global_uniform_4x4(GLContext::INVERSE_PROJECTION_MATRIX,inverseProjectionMatrix_); glContext_->request_redraw(); }