Esempio n. 1
0
/*!
    \since 5.5

    Creates a rotation matrix that corresponds to this quaternion.

    \note If this quaternion is not normalized,
    the resulting rotation matrix will contain scaling information.

    \sa fromRotationMatrix(), getAxes()
*/
QMatrix3x3 QQuaternion::toRotationMatrix() const
{
    // Algorithm from:
    // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54

    QMatrix3x3 rot3x3(Qt::Uninitialized);

    const float f2x = xp + xp;
    const float f2y = yp + yp;
    const float f2z = zp + zp;
    const float f2xw = f2x * wp;
    const float f2yw = f2y * wp;
    const float f2zw = f2z * wp;
    const float f2xx = f2x * xp;
    const float f2xy = f2x * yp;
    const float f2xz = f2x * zp;
    const float f2yy = f2y * yp;
    const float f2yz = f2y * zp;
    const float f2zz = f2z * zp;

    rot3x3(0, 0) = 1.0f - (f2yy + f2zz);
    rot3x3(0, 1) =         f2xy - f2zw;
    rot3x3(0, 2) =         f2xz + f2yw;
    rot3x3(1, 0) =         f2xy + f2zw;
    rot3x3(1, 1) = 1.0f - (f2xx + f2zz);
    rot3x3(1, 2) =         f2yz - f2xw;
    rot3x3(2, 0) =         f2xz - f2yw;
    rot3x3(2, 1) =         f2yz + f2xw;
    rot3x3(2, 2) = 1.0f - (f2xx + f2yy);

    return rot3x3;
}
Esempio n. 2
0
/*!
    \since 5.5

    Returns the 3 orthonormal axes (\a xAxis, \a yAxis, \a zAxis) defining the quaternion.

    \sa fromAxes(), toRotationMatrix()
*/
void QQuaternion::getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const
{
    Q_ASSERT(xAxis && yAxis && zAxis);

    const QMatrix3x3 rot3x3(toRotationMatrix());

    *xAxis = QVector3D(rot3x3(0, 0), rot3x3(1, 0), rot3x3(2, 0));
    *yAxis = QVector3D(rot3x3(0, 1), rot3x3(1, 1), rot3x3(2, 1));
    *zAxis = QVector3D(rot3x3(0, 2), rot3x3(1, 2), rot3x3(2, 2));
}
Esempio n. 3
0
/*!
    \since 5.5

    Constructs the quaternion using 3 axes (\a xAxis, \a yAxis, \a zAxis).

    \note The axes are assumed to be orthonormal.

    \sa getAxes(), fromRotationMatrix()
*/
QQuaternion QQuaternion::fromAxes(const QVector3D &xAxis, const QVector3D &yAxis, const QVector3D &zAxis)
{
    QMatrix3x3 rot3x3(Qt::Uninitialized);
    rot3x3(0, 0) = xAxis.x();
    rot3x3(1, 0) = xAxis.y();
    rot3x3(2, 0) = xAxis.z();
    rot3x3(0, 1) = yAxis.x();
    rot3x3(1, 1) = yAxis.y();
    rot3x3(2, 1) = yAxis.z();
    rot3x3(0, 2) = zAxis.x();
    rot3x3(1, 2) = zAxis.y();
    rot3x3(2, 2) = zAxis.z();

    return QQuaternion::fromRotationMatrix(rot3x3);
}
void QgsPoint3DSymbolWidget::setSymbol( const QgsPoint3DSymbol &symbol )
{
  cboAltClamping->setCurrentIndex( static_cast<int>( symbol.altitudeClamping() ) );

  QVariantMap vm = symbol.shapeProperties();
  int index = cboShape->findData( symbol.shape() );
  cboShape->setCurrentIndex( index != -1 ? index : 1 );  // use cylinder by default if shape is not set

  widgetMaterial->setEnabled( true );
  switch ( cboShape->currentIndex() )
  {
    case 0:  // sphere
      spinRadius->setValue( vm[QStringLiteral( "radius" )].toDouble() );
      break;
    case 1:  // cylinder
      spinRadius->setValue( vm[QStringLiteral( "radius" )].toDouble() );
      spinLength->setValue( vm[QStringLiteral( "length" )].toDouble() );
      break;
    case 2:  // cube
      spinSize->setValue( vm[QStringLiteral( "size" )].toDouble() );
      break;
    case 3:  // cone
      spinTopRadius->setValue( vm[QStringLiteral( "topRadius" )].toDouble() );
      spinBottomRadius->setValue( vm[QStringLiteral( "bottomRadius" )].toDouble() );
      spinLength->setValue( vm[QStringLiteral( "length" )].toDouble() );
      break;
    case 4:  // plane
      spinSize->setValue( vm[QStringLiteral( "size" )].toDouble() );
      break;
    case 5:  // torus
      spinRadius->setValue( vm[QStringLiteral( "radius" )].toDouble() );
      spinMinorRadius->setValue( vm[QStringLiteral( "minorRadius" )].toDouble() );
      break;
    case 6:  // 3d model
      lineEditModel->setText( vm[QStringLiteral( "model" )].toString() );
      bool overwriteMaterial = vm[QStringLiteral( "overwriteMaterial" )].toBool();
      widgetMaterial->setEnabled( overwriteMaterial );
      cbOverwriteMaterial->setChecked( overwriteMaterial );
      break;
  }

  widgetMaterial->setMaterial( symbol.material() );

  // decompose the transform matrix
  // assuming the last row has values [0 0 0 1]
  // see https://math.stackexchange.com/questions/237369/given-this-transformation-matrix-how-do-i-decompose-it-into-translation-rotati
  QMatrix4x4 m = symbol.transform();
  float *md = m.data();  // returns data in column-major order
  float sx = QVector3D( md[0], md[1], md[2] ).length();
  float sy = QVector3D( md[4], md[5], md[6] ).length();
  float sz = QVector3D( md[8], md[9], md[10] ).length();
  float rd[9] =
  {
    md[0] / sx, md[4] / sy, md[8] / sz,
    md[1] / sx, md[5] / sy, md[9] / sz,
    md[2] / sx, md[6] / sy, md[10] / sz,
  };
  QMatrix3x3 rot3x3( rd ); // takes data in row-major order
  QVector3D rot = QQuaternion::fromRotationMatrix( rot3x3 ).toEulerAngles();

  spinTX->setValue( md[12] );
  spinTY->setValue( md[13] );
  spinTZ->setValue( md[14] );
  spinSX->setValue( sx );
  spinSY->setValue( sy );
  spinSZ->setValue( sz );
  spinRX->setValue( rot.x() );
  spinRY->setValue( rot.y() );
  spinRZ->setValue( rot.z() );
}