use QTransform; use QskTickmarksNodes
This commit is contained in:
parent
7a74014257
commit
cf890b5824
|
@ -73,6 +73,23 @@ namespace
|
||||||
sensor->setTickmarksLabels( axis, labels );
|
sensor->setTickmarksLabels( axis, labels );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_REQUIRED_RESULT QskSlider* makeAngleSlider( const Qt::Axis axis,
|
||||||
|
QskLevelingSensor* const sensor, double min = 0, double max = 90, QQuickItem* const parent = nullptr)
|
||||||
|
{
|
||||||
|
auto* const slider = new QskSlider( Qt::Horizontal, parent );
|
||||||
|
slider->setMinimum( min );
|
||||||
|
slider->setMaximum( max );
|
||||||
|
slider->setValue( sensor->angle()[ axis ] );
|
||||||
|
|
||||||
|
QObject::connect(slider, &QskSlider::valueChanged, sensor, [axis, sensor](const qreal v){
|
||||||
|
auto angles = sensor->angle();
|
||||||
|
angles[axis] = v;
|
||||||
|
sensor->setAngle(angles);
|
||||||
|
});
|
||||||
|
|
||||||
|
return slider;
|
||||||
|
}
|
||||||
|
|
||||||
Q_REQUIRED_RESULT QskSlider* makeTickmarksSlider( const Qt::Axis axis,
|
Q_REQUIRED_RESULT QskSlider* makeTickmarksSlider( const Qt::Axis axis,
|
||||||
QskLevelingSensor* const sensor, int min, int max,
|
QskLevelingSensor* const sensor, int min, int max,
|
||||||
std::function< QskIntervalF( qreal ) > intervalA,
|
std::function< QskIntervalF( qreal ) > intervalA,
|
||||||
|
@ -139,13 +156,16 @@ namespace
|
||||||
return { 180 - degree, 180 + degree };
|
return { 180 - degree, 180 + degree };
|
||||||
};
|
};
|
||||||
|
|
||||||
( void ) new QskTextLabel( "Tickmarks X", right );
|
( void ) new QskTextLabel( "Angles XYZ", right );
|
||||||
|
(void) makeAngleSlider(Qt::XAxis, sensor, 0, 45, right);
|
||||||
|
(void) makeAngleSlider(Qt::YAxis, sensor, 0, 45, right);
|
||||||
|
(void) makeAngleSlider(Qt::ZAxis, sensor, 0, 45, right);
|
||||||
|
|
||||||
|
( void ) new QskTextLabel( "Tickmarks XXZ", right );
|
||||||
auto* const sliderTickmarksX = makeTickmarksSlider(
|
auto* const sliderTickmarksX = makeTickmarksSlider(
|
||||||
Qt::XAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right );
|
Qt::XAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right );
|
||||||
( void ) new QskTextLabel( "Tickmarks Y", right );
|
|
||||||
auto* const sliderTickmarksY = makeTickmarksSlider(
|
auto* const sliderTickmarksY = makeTickmarksSlider(
|
||||||
Qt::YAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right );
|
Qt::YAxis, sensor, 0, 90, linearIntervalA, linearIntervalB, right );
|
||||||
( void ) new QskTextLabel( "Tickmarks Z", right );
|
|
||||||
auto* const sliderTickmarksZ = makeTickmarksSlider(
|
auto* const sliderTickmarksZ = makeTickmarksSlider(
|
||||||
Qt::ZAxis, sensor, 0, 90, radialIntervalA, radialIntervalB, right );
|
Qt::ZAxis, sensor, 0, 90, radialIntervalA, radialIntervalB, right );
|
||||||
|
|
||||||
|
@ -161,6 +181,10 @@ namespace
|
||||||
( void ) makeRotationSlider( Qt::XAxis, sensor, QskLevelingSensor::TickmarksZ, right );
|
( void ) makeRotationSlider( Qt::XAxis, sensor, QskLevelingSensor::TickmarksZ, right );
|
||||||
( void ) makeRotationSlider( Qt::YAxis, sensor, QskLevelingSensor::TickmarksZ, right );
|
( void ) makeRotationSlider( Qt::YAxis, sensor, QskLevelingSensor::TickmarksZ, right );
|
||||||
( void ) makeRotationSlider( Qt::ZAxis, sensor, QskLevelingSensor::TickmarksZ, right );
|
( void ) makeRotationSlider( Qt::ZAxis, sensor, QskLevelingSensor::TickmarksZ, right );
|
||||||
|
( void ) new QskTextLabel( "Horizon", right );
|
||||||
|
( void ) makeRotationSlider( Qt::XAxis, sensor, QskLevelingSensor::Horizon, right );
|
||||||
|
( void ) makeRotationSlider( Qt::YAxis, sensor, QskLevelingSensor::Horizon, right );
|
||||||
|
( void ) makeRotationSlider( Qt::ZAxis, sensor, QskLevelingSensor::Horizon, right );
|
||||||
|
|
||||||
sliderTickmarksX->setValue( 15 );
|
sliderTickmarksX->setValue( 15 );
|
||||||
sliderTickmarksY->setValue( 15 );
|
sliderTickmarksY->setValue( 15 );
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
#include "QskLevelingSensorUtility.h"
|
#include "QskLevelingSensorUtility.h"
|
||||||
|
|
||||||
|
#include <QskScaleTickmarks.h>
|
||||||
|
#include <QskAspect.h>
|
||||||
|
|
||||||
#include <QSGFlatColorMaterial>
|
#include <QSGFlatColorMaterial>
|
||||||
#include <QSGGeometry>
|
#include <QSGGeometry>
|
||||||
#include <QSGGeometryNode>
|
#include <QSGGeometryNode>
|
||||||
|
@ -9,6 +12,8 @@
|
||||||
#include <QFontMetricsF>
|
#include <QFontMetricsF>
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
|
|
||||||
|
class QskSkinnable;
|
||||||
|
|
||||||
class RadialTickmarksNode final : public QSGGeometryNode
|
class RadialTickmarksNode final : public QSGGeometryNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -23,6 +23,11 @@
|
||||||
#include <QSGFlatColorMaterial>
|
#include <QSGFlatColorMaterial>
|
||||||
#include <QSGGeometryNode>
|
#include <QSGGeometryNode>
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
|
#include <QTransform>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <optional>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -51,6 +56,11 @@ namespace
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_REQUIRED_RESULT QVector2D center() const noexcept
|
||||||
|
{
|
||||||
|
return { ( float ) cX, ( float ) cY};
|
||||||
|
}
|
||||||
|
|
||||||
Q_REQUIRED_RESULT QVector3D scale() const noexcept
|
Q_REQUIRED_RESULT QVector3D scale() const noexcept
|
||||||
{
|
{
|
||||||
return { ( float ) sX, ( float ) sY, ( float ) sZ };
|
return { ( float ) sX, ( float ) sY, ( float ) sZ };
|
||||||
|
@ -85,10 +95,63 @@ namespace
|
||||||
|
|
||||||
Q_REQUIRED_RESULT QMatrix4x4 matrix() const noexcept
|
Q_REQUIRED_RESULT QMatrix4x4 matrix() const noexcept
|
||||||
{
|
{
|
||||||
return matrix_deg( 0, 0, rZ, cX, cY );
|
return matrix_deg( rZ, cX, cY );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_REQUIRED_RESULT std::optional< std::pair< qreal, qreal > > minmax(
|
||||||
|
const QVector< qreal >& tickmarks )
|
||||||
|
{
|
||||||
|
if ( tickmarks.empty() )
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto [ pmin, pmax ] = std::minmax_element( tickmarks.begin(), tickmarks.end() );
|
||||||
|
return std::make_pair( *pmin, *pmax );
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_REQUIRED_RESULT std::optional< std::pair< qreal, qreal > > minmax(
|
||||||
|
const QskScaleTickmarks& tickmarks )
|
||||||
|
{
|
||||||
|
if ( tickmarks.tickCount() == 0 )
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto majorTicks = tickmarks.majorTicks();
|
||||||
|
const auto mediumTicks = tickmarks.mediumTicks();
|
||||||
|
const auto minorTicks = tickmarks.minorTicks();
|
||||||
|
|
||||||
|
const auto item = !majorTicks.empty() ? majorTicks[ 0 ]
|
||||||
|
: !mediumTicks.empty() ? mediumTicks[ 0 ]
|
||||||
|
: !minorTicks.empty() ? minorTicks[ 0 ]
|
||||||
|
: std::numeric_limits< qreal >::quiet_NaN();
|
||||||
|
|
||||||
|
Q_ASSERT_X( !std::isnan( item ), __func__, "NaN should not be possible!" );
|
||||||
|
|
||||||
|
std::array< qreal, 6 > local = { item };
|
||||||
|
|
||||||
|
if ( const auto opt = minmax( tickmarks.majorTicks() ) )
|
||||||
|
{
|
||||||
|
local[ 0 ] = opt->first;
|
||||||
|
local[ 1 ] = opt->second;
|
||||||
|
}
|
||||||
|
if ( const auto opt = minmax( tickmarks.mediumTicks() ) )
|
||||||
|
{
|
||||||
|
local[ 2 ] = opt->first;
|
||||||
|
local[ 3 ] = opt->second;
|
||||||
|
}
|
||||||
|
if ( const auto opt = minmax( tickmarks.minorTicks() ) )
|
||||||
|
{
|
||||||
|
local[ 4 ] = opt->first;
|
||||||
|
local[ 5 ] = opt->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto [ pmin, pmax ] = std::minmax_element( local.begin(), local.end() );
|
||||||
|
return std::make_pair( *pmin, *pmax );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using Q = QskLevelingSensor;
|
using Q = QskLevelingSensor;
|
||||||
|
@ -208,9 +271,9 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::OuterDisk >(
|
||||||
const auto cY = center( sensor ).y();
|
const auto cY = center( sensor ).y();
|
||||||
const auto rZ = 0.0;
|
const auto rZ = 0.0;
|
||||||
|
|
||||||
const auto matrix = matrix_deg( 0.0, 0.0, 0.0, cX, cY, 0 ) *
|
const auto matrix = matrix_deg( 0.0, cX, cY ) *
|
||||||
matrix_deg( 0.0, 0.0, rZ, 0, 0, 0 ) *
|
matrix_deg( rZ, 0, 0 ) *
|
||||||
matrix_deg( 0.0, 0.0, 0.0, -size, -size, 0 );
|
matrix_deg( 0.0, -size, -size );
|
||||||
|
|
||||||
root->setMatrix( matrix );
|
root->setMatrix( matrix );
|
||||||
return root;
|
return root;
|
||||||
|
@ -241,71 +304,64 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::Horizon >(
|
||||||
updateBoxNode(
|
updateBoxNode(
|
||||||
sensor, boxNode, { 0, 0, 2 * state.r1, 2 * state.r1 }, shape, metrics, colors, gradient );
|
sensor, boxNode, { 0, 0, 2 * state.r1, 2 * state.r1 }, shape, metrics, colors, gradient );
|
||||||
|
|
||||||
const auto matrix = matrix_deg( 0, 0, 0, state.cX, state.cY, 0 ) *
|
const auto matrix = matrix_deg( 0, state.cX, state.cY ) * matrix_deg( state.rZ, 0, 0 ) *
|
||||||
matrix_deg( 0, 0, 0, -state.r1, -state.r1, 0 );
|
matrix_deg( 0, -state.r1, -state.r1 );
|
||||||
|
|
||||||
tNode->setMatrix( matrix );
|
tNode->setMatrix( matrix );
|
||||||
return tNode;
|
return tNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_REQUIRED_RESULT QSGNode* updateLinearTickmarksNode(
|
||||||
|
const QskLevelingSensor* const sensor,
|
||||||
|
const QskAspect::Subcontrol subControl,
|
||||||
|
const QskScaleTickmarks& tickmarks,
|
||||||
|
const Qt::Orientation orientation,
|
||||||
|
QSGNode* const node )
|
||||||
|
{
|
||||||
|
const auto state = State< QskAspect::Subcontrol >( sensor, subControl );
|
||||||
|
const auto color = sensor->color( subControl );
|
||||||
|
const auto scale = sensor->strutSizeHint( subControl );
|
||||||
|
const auto width = state.r1 * scale.width();
|
||||||
|
const auto height = state.r1 * scale.height();
|
||||||
|
const auto alignment = sensor->alignmentHint( subControl );
|
||||||
|
|
||||||
|
const auto opt = minmax( tickmarks );
|
||||||
|
const auto min = opt ? opt->first : 0.0;
|
||||||
|
const auto max = opt ? opt->second : 0.0;
|
||||||
|
const auto interval = QskIntervalF{min,max};
|
||||||
|
|
||||||
|
const auto rect =
|
||||||
|
orientation == Qt::Horizontal
|
||||||
|
? QRectF{ QPointF{ min * state.sX, -height }, QPointF{ max * state.sX, +height } }
|
||||||
|
: QRectF{ QPointF{ -width, min * state.sY }, QPointF{ +width, max * state.sY } };
|
||||||
|
|
||||||
|
const auto translation = QPointF{state.tX + state.cX, state.tY + state.cY};
|
||||||
|
|
||||||
|
auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, QskTickmarksNode >( node );
|
||||||
|
auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() );
|
||||||
|
auto* const qNode = static_cast< QskTickmarksNode* >( tNode->firstChild() );
|
||||||
|
|
||||||
|
cNode->setGeometryProperties( state.r1, state.cX, state.cY );
|
||||||
|
tNode->setMatrix( matrix_deg( state.rZ, translation.x(), translation.y() ));
|
||||||
|
qNode->update( color, rect, interval, tickmarks, 1, orientation, alignment );
|
||||||
|
|
||||||
|
return cNode;
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >(
|
QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksX >(
|
||||||
const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const
|
const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const
|
||||||
{
|
{
|
||||||
const auto subControl = Q::TickmarksX;
|
return updateLinearTickmarksNode(
|
||||||
State< QskAspect::Subcontrol > state( sensor, subControl );
|
sensor, Q::TickmarksX, sensor->tickmarks( Qt::XAxis ), Qt::Horizontal, node );
|
||||||
const auto color = sensor->color( subControl );
|
|
||||||
const auto scale = sensor->strutSizeHint( subControl );
|
|
||||||
const auto r3 = state.r1 * scale.height();
|
|
||||||
|
|
||||||
auto* const clipping =
|
|
||||||
ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( node );
|
|
||||||
auto* const transform = static_cast< QSGTransformNode* >( clipping->firstChild() );
|
|
||||||
auto* const tickmarks = static_cast< LinearTickmarksNode* >( transform->firstChild() );
|
|
||||||
|
|
||||||
auto size = qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * r3;
|
|
||||||
|
|
||||||
clipping->setGeometryProperties( state.r1, state.cX, state.cY );
|
|
||||||
|
|
||||||
tickmarks->setMaterialProperties( color );
|
|
||||||
tickmarks->setGeometryProperties( sensor->tickmarks( Qt::XAxis ), size,
|
|
||||||
{ state.scale().x(), 0.0f }, state.translation().toVector2D() );
|
|
||||||
|
|
||||||
const auto matrix = matrix_deg( 0, 0, state.rZ, state.cX, state.cY );
|
|
||||||
transform->setMatrix( matrix );
|
|
||||||
return clipping;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >(
|
QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksY >(
|
||||||
const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const
|
const QskLevelingSensor* const sensor, const quint8 nodeRole, QSGNode* const node ) const
|
||||||
{
|
{
|
||||||
const auto subControl = Q::TickmarksY;
|
return updateLinearTickmarksNode(
|
||||||
const State< QskAspect::Subcontrol > state( sensor, subControl );
|
sensor, Q::TickmarksY, sensor->tickmarks( Qt::YAxis ), Qt::Vertical, node );
|
||||||
|
|
||||||
const auto color = sensor->color( subControl );
|
|
||||||
const auto scale = sensor->strutSizeHint( subControl );
|
|
||||||
|
|
||||||
const auto r3 = state.r1 * scale.width();
|
|
||||||
|
|
||||||
const auto rotation = sensor->subControlRotation( subControl );
|
|
||||||
|
|
||||||
auto* const cNode =
|
|
||||||
ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksNode >( node );
|
|
||||||
auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() );
|
|
||||||
auto* const lNode = static_cast< LinearTickmarksNode* >( tNode->firstChild() );
|
|
||||||
|
|
||||||
auto size = qvariant_cast< QVector3D >( sensor->effectiveSkinHint( subControl ) ) * r3;
|
|
||||||
|
|
||||||
cNode->setGeometryProperties( state.r1, state.cX, state.cY );
|
|
||||||
|
|
||||||
const auto sY = static_cast< float >( state.r1 / sensor->angle().y() );
|
|
||||||
lNode->setMaterialProperties( color );
|
|
||||||
lNode->setGeometryProperties( sensor->tickmarks( Qt::YAxis ), size, { 0.0f, state.scale().y() },
|
|
||||||
{ ( float ) state.tX, ( float ) state.tY } );
|
|
||||||
|
|
||||||
tNode->setMatrix( state.matrix() );
|
|
||||||
return cNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -326,7 +382,7 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksZ >(
|
||||||
tickmarksNode->setMaterialProperties( color );
|
tickmarksNode->setMaterialProperties( color );
|
||||||
tickmarksNode->setGeometryProperties( sensor->tickmarks( Qt::ZAxis ), state.r1, r3 );
|
tickmarksNode->setGeometryProperties( sensor->tickmarks( Qt::ZAxis ), state.r1, r3 );
|
||||||
|
|
||||||
const auto matrix = matrix_deg( 0.0, 0.0, state.rZ, state.cX, state.cY );
|
const auto matrix = matrix_deg( state.rZ, state.cX, state.cY );
|
||||||
transform->setMatrix( matrix );
|
transform->setMatrix( matrix );
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
@ -337,18 +393,16 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksXLabels >(
|
||||||
{
|
{
|
||||||
const auto subControl = Q::TickmarksXLabels;
|
const auto subControl = Q::TickmarksXLabels;
|
||||||
const State< QskAspect::Subcontrol > state( sensor, subControl );
|
const State< QskAspect::Subcontrol > state( sensor, subControl );
|
||||||
const auto r3 =
|
const auto r3 = state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height();
|
||||||
static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksX ).height() );
|
const auto dX = qFastCos(qDegreesToRadians(90 + state.rZ)) * r3;
|
||||||
const auto translation = state.translation().toVector2D() + QVector2D{ 0, r3 };
|
const auto dY = qFastSin(qDegreesToRadians(90 + state.rZ)) * r3;
|
||||||
|
|
||||||
auto* const cNode =
|
auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node );
|
||||||
ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node );
|
|
||||||
auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() );
|
auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() );
|
||||||
auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() );
|
auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() );
|
||||||
cNode->setGeometryProperties( state.r1, state.cX, state.cY );
|
cNode->setGeometryProperties( state.r1, state.cX, state.cY );
|
||||||
tNode->setMatrix( state.matrix() );
|
tNode->setMatrix( matrix_deg( state.rZ, state.cX + state.tX + dX, state.cY + state.tY + dY) );
|
||||||
lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ),
|
lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::XAxis ), { state.scale().x(), 0.0 } );
|
||||||
{ state.scale().x(), 0.0 }, translation );
|
|
||||||
return cNode;
|
return cNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,22 +412,16 @@ QSGNode* QskLevelingSensorSkinlet::updateSubNode< R::TickmarksYLabels >(
|
||||||
{
|
{
|
||||||
const auto subControl = Q::TickmarksYLabels;
|
const auto subControl = Q::TickmarksYLabels;
|
||||||
const State< QskAspect::Subcontrol > state( sensor, subControl );
|
const State< QskAspect::Subcontrol > state( sensor, subControl );
|
||||||
const auto r3 =
|
const auto r3 = state.r1 * sensor->strutSizeHint( Q::TickmarksY ).width();
|
||||||
static_cast< float >( state.r1 * sensor->strutSizeHint( Q::TickmarksY ).width() );
|
const auto dX = qFastCos(qDegreesToRadians(state.rZ)) * r3;
|
||||||
|
const auto dY = qFastSin(qDegreesToRadians(state.rZ)) * r3;
|
||||||
|
|
||||||
const auto scale = sensor->strutSizeHint( subControl );
|
auto* const cNode = ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node );
|
||||||
const auto angles = sensor->angle();
|
|
||||||
const auto rotation = sensor->subControlRotation( subControl );
|
|
||||||
const auto translation = state.translation().toVector2D() + QVector2D( r3, 0 );
|
|
||||||
|
|
||||||
auto* const cNode =
|
|
||||||
ensureNodes< RadialClipNode, QSGTransformNode, LinearTickmarksLabelsNode >( node );
|
|
||||||
auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() );
|
auto* const tNode = static_cast< QSGTransformNode* >( cNode->firstChild() );
|
||||||
auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() );
|
auto* const lNode = static_cast< LinearTickmarksLabelsNode* >( tNode->firstChild() );
|
||||||
cNode->setGeometryProperties( state.r1, state.cX, state.cY );
|
cNode->setGeometryProperties( state.r1, state.cX, state.cY );
|
||||||
tNode->setMatrix( state.matrix() );
|
tNode->setMatrix( matrix_deg( state.rZ, state.cX + state.tX + dX, state.cY + state.tY + dY) );
|
||||||
lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::YAxis ),
|
lNode->update( sensor, subControl, sensor->tickmarkLabels( Qt::YAxis ), { 0.0, state.scale().y() } );
|
||||||
{ 0.0, state.scale().y() }, translation );
|
|
||||||
return cNode;
|
return cNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,31 +2,18 @@
|
||||||
|
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
#include <qmatrix4x4.h>
|
#include <qmatrix4x4.h>
|
||||||
|
#include <qtransform.h>
|
||||||
|
|
||||||
#include <QskFunctions.h>
|
#include <QskFunctions.h>
|
||||||
#include <QskScaleTickmarks.h>
|
#include <QskScaleTickmarks.h>
|
||||||
|
|
||||||
// create a homogenous transformation matrix
|
inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rZ = 0.0f,
|
||||||
inline Q_REQUIRED_RESULT QMatrix4x4 matrix_deg( float rX = 0.0f, float rY = 0.0f, float rZ = 0.0f,
|
|
||||||
float tX = 0.0f, float tY = 0.0f, float tZ = 0.0f )
|
float tX = 0.0f, float tY = 0.0f, float tZ = 0.0f )
|
||||||
{
|
{
|
||||||
// Convert rotation angles to radians
|
QTransform transform;
|
||||||
float rotationX = qDegreesToRadians( rX );
|
transform.translate( tX, tY );
|
||||||
float rotationY = qDegreesToRadians( rY );
|
transform.rotate(rZ, Qt::ZAxis);
|
||||||
float rotationZ = qDegreesToRadians( rZ );
|
return transform.toAffine();
|
||||||
|
|
||||||
// Calculate sin and cos of the rotation angles
|
|
||||||
float cosX = qCos( rotationX );
|
|
||||||
float sinX = qSin( rotationX );
|
|
||||||
float cosY = qCos( rotationY );
|
|
||||||
float sinY = qSin( rotationY );
|
|
||||||
float cosZ = qCos( rotationZ );
|
|
||||||
float sinZ = qSin( rotationZ );
|
|
||||||
|
|
||||||
// Create the transform matrix
|
|
||||||
return QMatrix4x4( cosY * cosZ, sinX * sinY * cosZ - cosX * sinZ,
|
|
||||||
cosX * sinY * cosZ + sinX * sinZ, tX, cosY * sinZ, sinX * sinY * sinZ + cosX * cosZ,
|
|
||||||
cosX * sinY * sinZ - sinX * cosZ, tY, -sinY, sinX * cosY, cosX * cosY, tZ, 0, 0, 0, 1 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
|
|
Loading…
Reference in New Issue