1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qquicktargetdirection_p.h"
41#include "qquickparticleemitter_p.h"
42#include <cmath>
43#include <QDebug>
44#include <QRandomGenerator>
45
46QT_BEGIN_NAMESPACE
47/*!
48 \qmltype TargetDirection
49 \instantiates QQuickTargetDirection
50 \inqmlmodule QtQuick.Particles
51 \ingroup qtquick-particles
52 \inherits Direction
53 \brief For specifying a direction towards the target point.
54
55*/
56/*!
57 \qmlproperty real QtQuick.Particles::TargetDirection::targetX
58*/
59/*!
60 \qmlproperty real QtQuick.Particles::TargetDirection::targetY
61*/
62/*!
63 \qmlproperty Item QtQuick.Particles::TargetDirection::targetItem
64 If specified, this will take precedence over targetX and targetY.
65 The targeted point will be the center of the specified Item
66*/
67/*!
68 \qmlproperty real QtQuick.Particles::TargetDirection::targetVariation
69*/
70/*!
71 \qmlproperty real QtQuick.Particles::TargetDirection::magnitude
72*/
73/*!
74 \qmlproperty real QtQuick.Particles::TargetDirection::magnitudeVariation
75*/
76/*!
77 \qmlproperty bool QtQuick.Particles::TargetDirection::proportionalMagnitude
78
79 If true, then the value of magnitude and magnitudeVariation shall be interpreted as multiples
80 of the distance between the source point and the target point, per second.
81
82 If false(default), then the value of magnitude and magnitudeVariation shall be interpreted as
83 pixels per second.
84*/
85
86QQuickTargetDirection::QQuickTargetDirection(QObject *parent) :
87 QQuickDirection(parent)
88 , m_targetX(0)
89 , m_targetY(0)
90 , m_targetVariation(0)
91 , m_proportionalMagnitude(false)
92 , m_magnitude(0)
93 , m_magnitudeVariation(0)
94 , m_targetItem(nullptr)
95{
96}
97
98QPointF QQuickTargetDirection::sample(const QPointF &from)
99{
100 //###This approach loses interpolating the last position of the target (like we could with the emitter) is it worthwhile?
101 QPointF ret;
102 qreal targetX;
103 qreal targetY;
104 if (m_targetItem){
105 QQuickParticleEmitter* parentEmitter = qobject_cast<QQuickParticleEmitter*>(object: parent());
106 targetX = m_targetItem->width()/2;
107 targetY = m_targetItem->height()/2;
108 if (!parentEmitter){
109 qWarning() << "Directed vector is not a child of the emitter. Mapping of target item coordinates may fail.";
110 targetX += m_targetItem->x();
111 targetY += m_targetItem->y();
112 }else{
113 ret = parentEmitter->mapFromItem(item: m_targetItem, point: QPointF(targetX, targetY));
114 targetX = ret.x();
115 targetY = ret.y();
116 }
117 }else{
118 targetX = m_targetX;
119 targetY = m_targetY;
120 }
121 targetX += 0 - from.x() - m_targetVariation + QRandomGenerator::global()->generateDouble() * m_targetVariation*2;
122 targetY += 0 - from.y() - m_targetVariation + QRandomGenerator::global()->generateDouble() * m_targetVariation*2;
123 qreal theta = std::atan2(y: targetY, x: targetX);
124 qreal mag = m_magnitude + QRandomGenerator::global()->generateDouble() * m_magnitudeVariation * 2 - m_magnitudeVariation;
125 if (m_proportionalMagnitude)
126 mag *= std::sqrt(x: targetX * targetX + targetY * targetY);
127 ret.setX(mag * std::cos(x: theta));
128 ret.setY(mag * std::sin(x: theta));
129 return ret;
130}
131
132QT_END_NAMESPACE
133
134#include "moc_qquicktargetdirection_p.cpp"
135

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