Пример #1
0
void ShadowEffect::draw(QPainter *painter)
{
    if (m_blurRadius < 0 && qFuzzyIsNull(m_xOffset) && qFuzzyIsNull(m_yOffset)) {
        drawSource(painter);
        return;
    }

    PixmapPadMode mode = PadToEffectiveBoundingRect;
    if (painter->paintEngine()->type() == QPaintEngine::OpenGL2) {
        mode = NoPad;
    }

    // Draw pixmap in device coordinates to avoid pixmap scaling.
    QPoint offset;
    const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode);
    if (pixmap.isNull()) {
        return;
    }

    QTransform restoreTransform = painter->worldTransform();
    painter->setWorldTransform(QTransform());
    if (m_shadow.isNull()) {
        m_shadow = generateShadow(pixmap);
    }
    // Draw shadow (draw it twice to darken it)
    painter->drawImage(offset, m_shadow);
    painter->drawImage(offset, m_shadow);
    // Draw the actual pixmap
    painter->drawPixmap(offset, pixmap);
    painter->setWorldTransform(restoreTransform);
}
Пример #2
0
void CameraController::update( double t )
{
    if ( !m_camera )
        return;

    // Store the time
    const float dt = t - m_time;
    m_time = t;

    // Update the camera position and orientation
    Camera::CameraTranslationOption option = m_viewCenterFixed
                                         ? Camera::DontTranslateViewCenter
                                         : Camera::TranslateViewCenter;
    m_camera->translate( dt * QVector3D( m_vx, m_vy, m_vz ), option );

    if ( !qFuzzyIsNull( m_panAngle ) )
    {
        m_camera->pan( m_panAngle );
        m_panAngle = 0.0f;
    }

    if ( !qFuzzyIsNull( m_tiltAngle ) )
    {
        m_camera->tilt( m_tiltAngle );
        m_tiltAngle = 0.0f;
    }
}
Пример #3
0
/*!
    \since 5.5

    Extracts a 3D axis (\a x, \a y, \a z) and a rotating angle \a angle (in degrees)
    that corresponds to this quaternion.

    \sa fromAxisAndAngle()
*/
void QQuaternion::getAxisAndAngle(float *x, float *y, float *z, float *angle) const
{
    Q_ASSERT(x && y && z && angle);

    // The quaternion representing the rotation is
    //   q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)

    float length = xp * xp + yp * yp + zp * zp;
    if (!qFuzzyIsNull(length)) {
        *x = xp;
        *y = yp;
        *z = zp;
        if (!qFuzzyIsNull(length - 1.0f)) {
            length = std::sqrt(length);
            *x /= length;
            *y /= length;
            *z /= length;
        }
        *angle = 2.0f * std::acos(wp);
    } else {
        // angle is 0 (mod 2*pi), so any axis will fit
        *x = *y = *z = *angle = 0.0f;
    }

    *angle = qRadiansToDegrees(*angle);
}
Пример #4
0
bool QgsGeometryUtils::segmentIntersection( const QgsPointV2 &p1, const QgsPointV2 &p2, const QgsPointV2 &q1, const QgsPointV2 &q2, QgsPointV2 &inter, double tolerance )
{
  QgsVector v( p2.x() - p1.x(), p2.y() - p1.y() );
  QgsVector w( q2.x() - q1.x(), q2.y() - q1.y() );
  double vl = v.length();
  double wl = w.length();

  if ( qFuzzyIsNull( vl ) || qFuzzyIsNull( wl ) )
  {
    return false;
  }
  v = v / vl;
  w = w / wl;

  if ( !QgsGeometryUtils::lineIntersection( p1, v, q1, w, inter ) )
    return false;

  double lambdav = QgsVector( inter.x() - p1.x(), inter.y() - p1.y() ) *  v;
  if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
    return false;

  double lambdaw = QgsVector( inter.x() - q1.x(), inter.y() - q1.y() ) * w;
  if ( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance )
    return false;

  return true;
}
void GenerationWidget::paintEvent(QPaintEvent*)
{
    QPainter p(this);
    p.fillRect(rect(), Qt::black);
    if (mImage.isNull() || qFuzzyIsNull(mImageAspectRatio) || qFuzzyIsNull(mImageAspectRatio))
        return;
    if (mWindowAspectRatio < mImageAspectRatio) {
        const int h = int(width() / mImageAspectRatio);
        mDestRect = QRect(0, (height()-h)/2, width(), h);
    }
    else {
        const int w = int(height() * mImageAspectRatio);
        mDestRect = QRect((width()-w)/2, 0, w, height());
    }
    p.drawImage(mDestRect, mImage);
    const qreal invScale = 1 / qSqrt(mDestRect.width() * mDestRect.height());
    p.translate(mDestRect.x(), mDestRect.y());
    p.scale(mDestRect.width(), mDestRect.height());
    p.setBrush(Qt::transparent);
    p.setRenderHint(QPainter::Antialiasing);
    if (mSplicedGene.color().isValid() && !mSplices.empty()) {
        p.setPen(QPen(Qt::green, 1.2 * invScale));
        for (QVector<Gene>::const_iterator g = mSplices.constBegin(); g != mSplices.constEnd(); ++g)
            p.drawPolygon(g->polygon());
        p.setPen(QPen(Qt::red, 1.3 * invScale));
        p.drawPolygon(mSplicedGene.polygon());
        mSplicedGene = Gene();
        mSplices.clear();
    }
    if (!mHighlighted.isEmpty()) {
        p.setPen(QPen(QColor(255, 0, 200), 1.3 * invScale));
        p.setBrush(Qt::transparent);
        p.drawPolygon(mHighlighted);
    }
}
Пример #6
0
void NormalMapScene::update( float t )
{
    QMutexLocker locker( &m_mutex );

    // Nothing to do here
    Q_UNUSED( t );

    // Rotate the cube
    if ( m_rotate )
    {
        m_theta += m_rotationSpeed;
        if ( m_theta > 360.0f )
            m_theta -= 360.0f;
    }
    m_modelMatrix.setToIdentity();
    m_modelMatrix.rotate( m_theta, 0.0f, 1.0f, 0.0f );

    // Update the camera position and orientation
    Camera::CameraTranslationOption option = m_viewCenterFixed
                                           ? Camera::DontTranslateViewCenter
                                           : Camera::TranslateViewCenter;
    m_camera->translate( QVector3D( m_vx, m_vy, m_vz ), option );

    if ( !qFuzzyIsNull( m_panAngle ) )
    {
        m_camera->pan( m_panAngle );
        m_panAngle = 0.0f;
    }

    if ( !qFuzzyIsNull( m_tiltAngle ) )
    {
        m_camera->tilt( m_tiltAngle );
        m_tiltAngle = 0.0f;
    }
}
Пример #7
0
void NoiseScene::update( float t )
{
    // Store the time to pass into the shader
    m_time = t;

    // Rotate the cube
    if ( m_rotate )
    {
        m_theta += 0.5f;
        if ( m_theta > 360.0f )
            m_theta -= 360.0f;
    }
    m_modelMatrix.setToIdentity();
    m_modelMatrix.rotate( m_theta, 0.0f, 1.0f, 0.0f );

    // Update the camera position and orientation
    Camera::CameraTranslationOption option = m_viewCenterFixed
                                           ? Camera::DontTranslateViewCenter
                                           : Camera::TranslateViewCenter;
    m_camera->translate( QVector3D( m_vx, m_vy, m_vz ), option );

    if ( !qFuzzyIsNull( m_panAngle ) )
    {
        m_camera->pan( m_panAngle );
        m_panAngle = 0.0f;
    }

    if ( !qFuzzyIsNull( m_tiltAngle ) )
    {
        m_camera->tilt( m_tiltAngle );
        m_tiltAngle = 0.0f;
    }
}
Пример #8
0
static inline int quadraticRoots(qreal a, qreal b, qreal c,
                                 qreal *x1, qreal *x2)
{
    if (qFuzzyIsNull(a)) {
        if (qFuzzyIsNull(b))
            return 0;
        *x1 = *x2 = (-c / b);
        return 1;
    } else {
        const qreal det = b * b - 4 * a * c;
        if (qFuzzyIsNull(det)) {
            *x1 = *x2 = -b / (2 * a);
            return 1;
        }
        if (det > 0) {
            if (qFuzzyIsNull(b)) {
                *x2 = qSqrt(-c / a);
                *x1 = -(*x2);
                return 2;
            }
            const qreal stableA = b / (2 * a);
            const qreal stableB = c / (a * stableA * stableA);
            const qreal stableC = -1 - qSqrt(1 - stableB);
            *x2 = stableA * stableC;
            *x1 = (stableA * stableB) / stableC;
            return 2;
        } else
            return 0;
    }
}
Пример #9
0
/*!
    \since 5.5

    Returns the shortest arc quaternion to rotate from the direction described by the vector \a from
    to the direction described by the vector \a to.

    \sa fromDirection()
*/
QQuaternion QQuaternion::rotationTo(const QVector3D &from, const QVector3D &to)
{
    // Based on Stan Melax's article in Game Programming Gems

    const QVector3D v0(from.normalized());
    const QVector3D v1(to.normalized());

    float d = QVector3D::dotProduct(v0, v1) + 1.0f;

    // if dest vector is close to the inverse of source vector, ANY axis of rotation is valid
    if (qFuzzyIsNull(d)) {
        QVector3D axis = QVector3D::crossProduct(QVector3D(1.0f, 0.0f, 0.0f), v0);
        if (qFuzzyIsNull(axis.lengthSquared()))
            axis = QVector3D::crossProduct(QVector3D(0.0f, 1.0f, 0.0f), v0);
        axis.normalize();

        // same as QQuaternion::fromAxisAndAngle(axis, 180.0f)
        return QQuaternion(0.0f, axis.x(), axis.y(), axis.z());
    }

    d = std::sqrt(2.0f * d);
    const QVector3D axis(QVector3D::crossProduct(v0, v1) / d);

    return QQuaternion(d * 0.5f, axis).normalized();
}
Пример #10
0
void Camera::setMotionAdjustment(const QVector3D& vector)
{
    Q_D(Camera);
    if (d->motionAdjustment != vector) {
        d->motionAdjustment = vector;
        if (vector.x() == 0.0f && vector.y() == 0.0f) {
            // If the vector is centered, then don't perform any rotations.
            d->motionQuaternion = QQuaternion();
        } else {
            // Determine the pan and tilt angles from the vector.
            QVector3D view = -vector.normalized();
            if (view.z() < 0.0f)
                view = -view;
            qreal xangle = asin(view.x()) * 180.0f / M_PI;
            qreal yangle = asin(-view.y()) * 180.0f / M_PI;

            // Construct the pan and tilt quaternions.
            if (qFuzzyIsNull(xangle))
                d->motionQuaternion = tilt(yangle);
            else if (qFuzzyIsNull(yangle))
                d->motionQuaternion = pan(xangle);
            else
                d->motionQuaternion = tilt(yangle) * pan(xangle);
        }
        emit viewChanged();
    }
}
void ptFilter_WaveletDenoise::doRunFilter(ptImage *AImage) {
  AImage->toLab();

  const double LStrength = FConfig.value(CLStrength).toDouble();
  const double AStrength = FConfig.value(CAStrength).toDouble();
  const double BStrength = FConfig.value(CBStrength).toDouble();
  const double strengthDiv = (log(TheProcessor->m_ScaleFactor)/log(0.5)) + 1.0;

  if (!qFuzzyIsNull(LStrength)) {
    AImage->WaveletDenoise(
          ChMask_L,
          LStrength / strengthDiv,
          FConfig.value(CLSoftness).toDouble(),
          true,
          FConfig.value(CSharpness).toDouble(),
          FConfig.value(CAnisotropy).toDouble(),
          FConfig.value(CGradientSmooth).toDouble(),
          FConfig.value(CTensorSmooth).toDouble());
  }

  if (!qFuzzyIsNull(AStrength)) {
    AImage->WaveletDenoise(
        ChMask_a,
        AStrength /strengthDiv,
        FConfig.value(CASoftness).toDouble());
  }

  if (!qFuzzyIsNull(BStrength)) {
    AImage->WaveletDenoise(
        ChMask_a,
        BStrength /strengthDiv,
        FConfig.value(CBSoftness).toDouble());
  }
}
void TerrainTessellationScene::update( float t )
{
    Q_UNUSED( t );
    m_theta += 0.2;
    if ( m_theta > 360.0f )
        m_theta -= 360.0f;

    m_modelMatrix.setToIdentity();
    m_modelMatrix.scale( 50.0f );
    m_modelMatrix.translate( -5.0f, 0.0f, 0.0f );

    // Update the camera position and orientation
    Camera::CameraTranslationOption option = m_viewCenterFixed
                                           ? Camera::DontTranslateViewCenter
                                           : Camera::TranslateViewCenter;
    m_camera->translate( QVector3D( m_vx, m_vy, m_vz ), option );

    if ( !qFuzzyIsNull( m_panAngle ) )
    {
        m_camera->pan( m_panAngle );
        m_panAngle = 0.0f;
    }

    if ( !qFuzzyIsNull( m_tiltAngle ) )
    {
        m_camera->tilt( m_tiltAngle );
        m_tiltAngle = 0.0f;
    }
}
void QQuickTextNodeEngine::BinaryTreeNode::insert(QVarLengthArray<BinaryTreeNode, 16> *binaryTree, const QGlyphRun &glyphRun, SelectionState selectionState,
                                             QQuickTextNode::Decorations decorations, const QColor &textColor,
                                             const QColor &backgroundColor, const QPointF &position)
{
    QRectF searchRect = glyphRun.boundingRect();
    searchRect.translate(position);

    if (qFuzzyIsNull(searchRect.width()) || qFuzzyIsNull(searchRect.height()))
        return;

    decorations |= (glyphRun.underline() ? QQuickTextNode::Underline : QQuickTextNode::NoDecoration);
    decorations |= (glyphRun.overline()  ? QQuickTextNode::Overline  : QQuickTextNode::NoDecoration);
    decorations |= (glyphRun.strikeOut() ? QQuickTextNode::StrikeOut : QQuickTextNode::NoDecoration);
    decorations |= (backgroundColor.isValid() ? QQuickTextNode::Background : QQuickTextNode::NoDecoration);

    qreal ascent = glyphRun.rawFont().ascent();
    insert(binaryTree, BinaryTreeNode(glyphRun,
                                      selectionState,
                                      searchRect,
                                      decorations,
                                      textColor,
                                      backgroundColor,
                                      position,
                                      ascent));
}
Пример #14
0
static bool addCircle(const QBezier *b, qreal offset, QBezier *o)
{
    QPointF normals[3];

    normals[0] = QPointF(b->y2 - b->y1, b->x1 - b->x2);
    qreal dist = qSqrt(normals[0].x()*normals[0].x() + normals[0].y()*normals[0].y());
    if (qFuzzyIsNull(dist))
        return false;
    normals[0] /= dist;
    normals[2] = QPointF(b->y4 - b->y3, b->x3 - b->x4);
    dist = qSqrt(normals[2].x()*normals[2].x() + normals[2].y()*normals[2].y());
    if (qFuzzyIsNull(dist))
        return false;
    normals[2] /= dist;

    normals[1] = QPointF(b->x1 - b->x2 - b->x3 + b->x4, b->y1 - b->y2 - b->y3 + b->y4);
    normals[1] /= -1*qSqrt(normals[1].x()*normals[1].x() + normals[1].y()*normals[1].y());

    qreal angles[2];
    qreal sign = 1.;
    for (int i = 0; i < 2; ++i) {
        qreal cos_a = normals[i].x()*normals[i+1].x() + normals[i].y()*normals[i+1].y();
        if (cos_a > 1.)
            cos_a = 1.;
        if (cos_a < -1.)
            cos_a = -1;
        angles[i] = qAcos(cos_a)/Q_PI;
    }

    if (angles[0] + angles[1] > 1.) {
        // more than 180 degrees
        normals[1] = -normals[1];
        angles[0] = 1. - angles[0];
        angles[1] = 1. - angles[1];
        sign = -1.;

    }

    QPointF circle[3];
    circle[0] = QPointF(b->x1, b->y1) + normals[0]*offset;
    circle[1] = QPointF(qreal(0.5)*(b->x1 + b->x4), qreal(0.5)*(b->y1 + b->y4)) + normals[1]*offset;
    circle[2] = QPointF(b->x4, b->y4) + normals[2]*offset;

    for (int i = 0; i < 2; ++i) {
        qreal kappa = qreal(2.0) * KAPPA * sign * offset * angles[i];

        o->x1 = circle[i].x();
        o->y1 = circle[i].y();
        o->x2 = circle[i].x() - normals[i].y()*kappa;
        o->y2 = circle[i].y() + normals[i].x()*kappa;
        o->x3 = circle[i+1].x() + normals[i+1].y()*kappa;
        o->y3 = circle[i+1].y() - normals[i+1].x()*kappa;
        o->x4 = circle[i+1].x();
        o->y4 = circle[i+1].y();

        ++o;
    }
    return true;
}
Пример #15
0
static inline bool fuzzyCompare( double a, double b ) 
{
#if QT_VERSION < 0x040600
    const int eps = 0.000000000001;
    return ( ( qAbs(a) <= eps ) && ( qAbs(b) <= eps ) ) || qFuzzyCompare(a, b);
#else
    return ( qFuzzyIsNull(a) && qFuzzyIsNull(b) ) || qFuzzyCompare(a, b);
#endif
}
void InstancedHistogramScene::update( float t )
{
    QMutexLocker locker( &m_mutex );

    // Update the data being plotted
    if ( m_updatesEnabled )
    {
        const float xMin = -15.0f, xMax = 15.0f;
        const float zMin = -15.0f, zMax = 15.0f;
        const float dx = ( xMax - xMin ) / static_cast<float>( xPoints - 1 );
        const float dz = ( zMax - zMin ) / static_cast<float>( zPoints - 1 );
        int i = 0;
        const float A = 5.0;
        for ( int zi = 0; zi < zPoints; ++zi )
        {
            float z = zMin + static_cast<float>( zi ) * dz;

            for ( int xi = 0; xi < xPoints; ++xi )
            {
                float x = xMin + static_cast<float>( xi ) * dx;

                double r = sqrt( x * x + z * z );
                float y = A * ( sinf( m_frequency * t ) + cosf( m_frequency * t ) ) * j0( m_spatialFrequency * r );

                m_data[3 * i]     = x;
                m_data[3 * i + 1] = y;
                m_data[3 * i + 2] = z;
                ++i;
            }
        }
    }

    // Store the time to pass into the shader
    const float dt = t - m_time;
    m_time = t;

    // Update the camera position and orientation
    Camera::CameraTranslationOption option = m_viewCenterFixed
                                           ? Camera::DontTranslateViewCenter
                                           : Camera::TranslateViewCenter;
    m_camera->translate( QVector3D( m_vx * dt, m_vy * dt, m_vz * dt ), option );

    if ( !qFuzzyIsNull( m_panAngle ) )
    {
        m_camera->pan( m_panAngle * dt );
        m_panAngle = 0.0f;
    }

    if ( !qFuzzyIsNull( m_tiltAngle ) )
    {
        m_camera->tilt( m_tiltAngle * dt );
        m_tiltAngle = 0.0f;
    }
}
Пример #17
0
void IRWidget::paintEvent(QPaintEvent *)
{
  Q_D(IRWidget);

  if (d->irFrame.isNull() || qFuzzyIsNull(d->imageAspectRatio) || qFuzzyIsNull(d->windowAspectRatio))
    return;

  QPainter p(this);
  p.fillRect(rect(), Qt::gray);
  p.drawImage(d->destRect, d->irFrame);
}
Пример #18
0
/*!
    Returns the normalized unit vector form of this vector.

    If this vector is null, then a null vector is returned.  If the length
    of the vector is very close to 1, then the vector will be returned as-is.
    Otherwise the normalized form of the vector of length 1 will be returned.

    \sa length(), normalize()
*/
QVector2D QVector2D::normalized() const
{
    // Need some extra precision if the length is very small.
    double len = double(xp) * double(xp) +
                 double(yp) * double(yp);
    if (qFuzzyIsNull(len - 1.0f))
        return *this;
    else if (!qFuzzyIsNull(len))
        return *this / qSqrt(len);
    else
        return QVector2D();
}
Пример #19
0
Vec Vec::normalized() const
{
	// Need some extra precision if the length is very small.
	TGPSReal len = TGPSReal(xp) * TGPSReal(xp) +
			TGPSReal(yp) * TGPSReal(yp) +
			TGPSReal(zp) * TGPSReal(zp);
	if (qFuzzyIsNull(len - 1.0))
		return *this;
	else if (!qFuzzyIsNull(len))
		return *this / qSqrt(len);
	else
		return Vec();
}
Пример #20
0
/*!
    Normalizes the currect vector in place.  Nothing happens if this
    vector is a null vector or the length of the vector is very close to 1.

    \sa length(), normalized()
*/
void QVector2D::normalize()
{
    // Need some extra precision if the length is very small.
    double len = double(xp) * double(xp) +
                 double(yp) * double(yp);
    if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
        return;

    len = sqrt(len);

    xp = float(double(xp) / len);
    yp = float(double(yp) / len);
}
Пример #21
0
/*!
    Normalizes the currect vector in place.  Nothing happens if this
    vector is a null vector or the length of the vector is very close to 1.

    \sa length(), normalized()
*/
void TVector2D::normalize()
{
    // Need some extra precision if the length is very small.
    double len = double(xp) * double(xp) +
                 double(yp) * double(yp);
    if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
        return;

    len = qSqrt(len);

    xp /= len;
    yp /= len;
}
Пример #22
0
void Vec::normalize()
{
	// Need some extra precision if the length is very small.
	TGPSReal len = TGPSReal(xp) * TGPSReal(xp) + TGPSReal(yp) * TGPSReal(yp) + TGPSReal(zp) * TGPSReal(zp);
	if (qFuzzyIsNull(len - 1.0) || qFuzzyIsNull(len))
		return;

	len = qSqrt(len);

	xp /= len;
	yp /= len;
	zp /= len;
}
Пример #23
0
QPixmap Icon::applyEffects() const
{
    QPixmap gfx = pixmap;

    if (isColor && !qFuzzyIsNull(depth)) {
        QLabel w;
        QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect();
        effect->setColor(color);
        effect->setStrength(depth);
        w.setPixmap(gfx);
        w.setGraphicsEffect(effect);
        gfx = w.grab();
    }

    if (!qFuzzyIsNull(radius)) {
        QImage canvas(gfx.size(), QImage::Format_ARGB32_Premultiplied);
        QPainter painter(&canvas);
        painter.setCompositionMode(QPainter::CompositionMode_Source);
        painter.fillRect(gfx.rect(), Qt::transparent);
        painter.setPen(Qt::NoPen);
        painter.setBrush(QBrush(gfx));
        painter.setRenderHint(QPainter::Antialiasing);
        painter.drawRoundedRect(gfx.rect(), radius, radius);
        painter.end();
        gfx = QPixmap::fromImage(canvas);
    }

    if (blur > 1.0) {
        QLabel w;
        QGraphicsBlurEffect *effect = new QGraphicsBlurEffect();
        effect->setBlurRadius(blur);
        effect->setBlurHints(QGraphicsBlurEffect::QualityHint);
        w.setPixmap(gfx);
        w.setGraphicsEffect(effect);
        gfx = w.grab();
    }

    if (flipX) {
        gfx = gfx.transformed(QTransform().scale(-1, 1));
    }

    if (flipY) {
        gfx = gfx.transformed(QTransform().scale(1, -1));
    }

    if (angle != 0) {
        gfx = gfx.transformed(QTransform().rotate(angle));
    }

    return gfx;
}
Пример #24
0
/*!
    Returns the normalized unit form of this quaternion.

    If this quaternion is null, then a null quaternion is returned.
    If the length of the quaternion is very close to 1, then the quaternion
    will be returned as-is.  Otherwise the normalized form of the
    quaternion of length 1 will be returned.

    \sa length(), normalize()
*/
QQuaternion QQuaternion::normalized() const
{
    // Need some extra precision if the length is very small.
    double len = double(xp) * double(xp) +
                 double(yp) * double(yp) +
                 double(zp) * double(zp) +
                 double(wp) * double(wp);
    if (qFuzzyIsNull(len - 1.0f))
        return *this;
    else if (!qFuzzyIsNull(len))
        return *this / qSqrt(len);
    else
        return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
}
Пример #25
0
/*!
    Creates a normalized quaternion that corresponds to rotating through
    \a angle degrees about the 3D axis (\a x, \a y, \a z).
*/
QQuaternion QQuaternion::fromAxisAndAngle
        (qreal x, qreal y, qreal z, qreal angle)
{
    qreal length = qSqrt(x * x + y * y + z * z);
    if (!qFuzzyIsNull(length - 1.0f) && !qFuzzyIsNull(length)) {
        x /= length;
        y /= length;
        z /= length;
    }
    qreal a = (angle / 2.0f) * M_PI / 180.0f;
    qreal s = qSin(a);
    qreal c = qCos(a);
    return QQuaternion(c, x * s, y * s, z * s).normalized();
}
Пример #26
0
/*!
    Creates a normalized quaternion that corresponds to rotating through
    \a angle degrees about the 3D axis (\a x, \a y, \a z).

    \sa getAxisAndAngle()
*/
QQuaternion QQuaternion::fromAxisAndAngle
        (float x, float y, float z, float angle)
{
    float length = std::sqrt(x * x + y * y + z * z);
    if (!qFuzzyIsNull(length - 1.0f) && !qFuzzyIsNull(length)) {
        x /= length;
        y /= length;
        z /= length;
    }
    float a = qDegreesToRadians(angle / 2.0f);
    float s = std::sin(a);
    float c = std::cos(a);
    return QQuaternion(c, x * s, y * s, z * s).normalized();
}
Пример #27
0
/*!
    \since 5.5

    Calculates \a roll, \a pitch, and \a yaw Euler angles (in degrees)
    that corresponds to this quaternion.

    \sa fromEulerAngles()
*/
void QQuaternion::getEulerAngles(float *pitch, float *yaw, float *roll) const
{
    Q_ASSERT(pitch && yaw && roll);

    // Algorithm from:
    // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q37

    float xx = xp * xp;
    float xy = xp * yp;
    float xz = xp * zp;
    float xw = xp * wp;
    float yy = yp * yp;
    float yz = yp * zp;
    float yw = yp * wp;
    float zz = zp * zp;
    float zw = zp * wp;

    const float lengthSquared = xx + yy + zz + wp * wp;
    if (!qFuzzyIsNull(lengthSquared - 1.0f) && !qFuzzyIsNull(lengthSquared)) {
        xx /= lengthSquared;
        xy /= lengthSquared; // same as (xp / length) * (yp / length)
        xz /= lengthSquared;
        xw /= lengthSquared;
        yy /= lengthSquared;
        yz /= lengthSquared;
        yw /= lengthSquared;
        zz /= lengthSquared;
        zw /= lengthSquared;
    }

    *pitch = std::asin(-2.0f * (yz - xw));
    if (*pitch < M_PI_2) {
        if (*pitch > -M_PI_2) {
            *yaw = std::atan2(2.0f * (xz + yw), 1.0f - 2.0f * (xx + yy));
            *roll = std::atan2(2.0f * (xy + zw), 1.0f - 2.0f * (xx + zz));
        } else {
            // not a unique solution
            *roll = 0.0f;
            *yaw = -std::atan2(-2.0f * (xy - zw), 1.0f - 2.0f * (yy + zz));
        }
    } else {
        // not a unique solution
        *roll = 0.0f;
        *yaw = std::atan2(-2.0f * (xy - zw), 1.0f - 2.0f * (yy + zz));
    }

    *pitch = qRadiansToDegrees(*pitch);
    *yaw = qRadiansToDegrees(*yaw);
    *roll = qRadiansToDegrees(*roll);
}
Пример #28
0
/*!
    Creates a normalized quaternion that corresponds to rotating through
    \a angle degrees about the 3D axis (\a x, \a y, \a z).
*/
QQuaternion QQuaternion::fromAxisAndAngle
        (float x, float y, float z, float angle)
{
    float length = qSqrt(x * x + y * y + z * z);
    if (!qFuzzyIsNull(length - 1.0f) && !qFuzzyIsNull(length)) {
        x /= length;
        y /= length;
        z /= length;
    }
    float a = (angle / 2.0f) * M_PI / 180.0f;
    float s = sinf(a);
    float c = cosf(a);
    return QQuaternion(c, x * s, y * s, z * s).normalized();
}
Пример #29
0
/*!
    Returns the normalized unit vector form of this vector.

    If this vector is null, then a null vector is returned.  If the length
    of the vector is very close to 1, then the vector will be returned as-is.
    Otherwise the normalized form of the vector of length 1 will be returned.

    \sa length(), normalize()
*/
QVector2D QVector2D::normalized() const
{
    // Need some extra precision if the length is very small.
    double len = double(xp) * double(xp) +
                 double(yp) * double(yp);
    if (qFuzzyIsNull(len - 1.0f)) {
        return *this;
    } else if (!qFuzzyIsNull(len)) {
        double sqrtLen = sqrt(len);
        return QVector2D(float(double(xp) / sqrtLen), float(double(yp) / sqrtLen));
    } else {
        return QVector2D();
    }
}
/*!
    Decelerate \a timeLineValue from the starting \a velocity to zero over the given
    \a distance.  This is like accel(), but the QQuickTimeLine calculates the exact
    deceleration to use.

    \a distance should be positive.
*/
int QQuickTimeLine::accelDistance(QQuickTimeLineValue &timeLineValue, qreal velocity, qreal distance)
{
    if (qFuzzyIsNull(distance) || qIsNaN(distance) || qFuzzyIsNull(velocity) || qIsNaN(velocity))
        return -1;

    Q_ASSERT((distance >= 0.0f) == (velocity >= 0.0f));

    int time = static_cast<int>(1000 * (2.0f * distance) / velocity);
    if (time <= 0) return -1;

    QQuickTimeLinePrivate::Op op(QQuickTimeLinePrivate::Op::AccelDistance, time, velocity, distance, d->order++);
    d->add(timeLineValue, op);

    return time;
}