1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qquicktargetdirection_p.h"
5#include "qquickparticleemitter_p.h"
6#include <cmath>
7#include <QDebug>
8#include <QRandomGenerator>
9
10QT_BEGIN_NAMESPACE
11/*!
12 \qmltype TargetDirection
13 \instantiates QQuickTargetDirection
14 \inqmlmodule QtQuick.Particles
15 \ingroup qtquick-particles
16 \inherits Direction
17 \brief For specifying a direction towards the target point.
18
19*/
20/*!
21 \qmlproperty real QtQuick.Particles::TargetDirection::targetX
22*/
23/*!
24 \qmlproperty real QtQuick.Particles::TargetDirection::targetY
25*/
26/*!
27 \qmlproperty Item QtQuick.Particles::TargetDirection::targetItem
28 If specified, this will take precedence over targetX and targetY.
29 The targeted point will be the center of the specified Item
30*/
31/*!
32 \qmlproperty real QtQuick.Particles::TargetDirection::targetVariation
33*/
34/*!
35 \qmlproperty real QtQuick.Particles::TargetDirection::magnitude
36*/
37/*!
38 \qmlproperty real QtQuick.Particles::TargetDirection::magnitudeVariation
39*/
40/*!
41 \qmlproperty bool QtQuick.Particles::TargetDirection::proportionalMagnitude
42
43 If true, then the value of magnitude and magnitudeVariation shall be interpreted as multiples
44 of the distance between the source point and the target point, per second.
45
46 If false(default), then the value of magnitude and magnitudeVariation shall be interpreted as
47 pixels per second.
48*/
49
50QQuickTargetDirection::QQuickTargetDirection(QObject *parent) :
51 QQuickDirection(parent)
52 , m_targetX(0)
53 , m_targetY(0)
54 , m_targetVariation(0)
55 , m_proportionalMagnitude(false)
56 , m_magnitude(0)
57 , m_magnitudeVariation(0)
58 , m_targetItem(nullptr)
59{
60}
61
62QPointF QQuickTargetDirection::sample(const QPointF &from)
63{
64 //###This approach loses interpolating the last position of the target (like we could with the emitter) is it worthwhile?
65 QPointF ret;
66 qreal targetX;
67 qreal targetY;
68 if (m_targetItem){
69 QQuickParticleEmitter* parentEmitter = qobject_cast<QQuickParticleEmitter*>(object: parent());
70 targetX = m_targetItem->width()/2;
71 targetY = m_targetItem->height()/2;
72 if (!parentEmitter){
73 qWarning() << "Directed vector is not a child of the emitter. Mapping of target item coordinates may fail.";
74 targetX += m_targetItem->x();
75 targetY += m_targetItem->y();
76 }else{
77 ret = parentEmitter->mapFromItem(item: m_targetItem, point: QPointF(targetX, targetY));
78 targetX = ret.x();
79 targetY = ret.y();
80 }
81 }else{
82 targetX = m_targetX;
83 targetY = m_targetY;
84 }
85 targetX += 0 - from.x() - m_targetVariation + QRandomGenerator::global()->generateDouble() * m_targetVariation*2;
86 targetY += 0 - from.y() - m_targetVariation + QRandomGenerator::global()->generateDouble() * m_targetVariation*2;
87 qreal theta = std::atan2(y: targetY, x: targetX);
88 qreal mag = m_magnitude + QRandomGenerator::global()->generateDouble() * m_magnitudeVariation * 2 - m_magnitudeVariation;
89 if (m_proportionalMagnitude)
90 mag *= qHypot(x: targetX, y: targetY);
91 ret.setX(mag * std::cos(x: theta));
92 ret.setY(mag * std::sin(x: theta));
93 return ret;
94}
95
96QT_END_NAMESPACE
97
98#include "moc_qquicktargetdirection_p.cpp"
99

source code of qtdeclarative/src/particles/qquicktargetdirection.cpp