aboutsummaryrefslogtreecommitdiffstats
path: root/src/particles/qquickpointattractor.cpp
blob: a7df598f6b947d1869dbe7f8abc172dfb3ebc59b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include "qquickpointattractor_p.h"
#include <cmath>
#include <QDebug>
QT_BEGIN_NAMESPACE
/*!
    \qmltype Attractor
    \instantiates QQuickAttractorAffector
    \inqmlmodule QtQuick.Particles
    \ingroup qtquick-particles
    \inherits Affector
    \brief Attracts particles towards a specific point.

    Like other affectors, Attractor has the standard properties x, y, width,
    and height that represent the affected area. The size and position of the
    Attractor item determine the affected particles.

    The size of the attracting point is always 0x0, and its location is
    specified by \l pointX and \l pointY properties.
*/


/*!
    \qmlproperty real QtQuick.Particles::Attractor::pointX

    The x coordinate of the attracting point, relative
    to the x coordinate of the Attractor item.
*/
/*!
    \qmlproperty real QtQuick.Particles::Attractor::pointY

    The y coordinate of the attracting point, relative
    to the y coordinate of the Attractor item.
*/
/*!
    \qmlproperty real QtQuick.Particles::Attractor::strength

    The pull, in units per second, to be exerted on an item one pixel away.

    Strength, together with the value of \l proportionalToDistance property,
    determine the exact amount of pull exerted on particles at a distance.
*/
/*!
    \qmlproperty enumeration QtQuick.Particles::Attractor::affectedParameter

    The attribute of particles that is directly affected.

    \value Attractor.Position Position
    \value Attractor.Velocity Velocity
    \value Attractor.Acceleration Acceleration
*/
/*!
    \qmlproperty enumeration QtQuick.Particles::Attractor::proportionalToDistance

    The relation between the \l strength of the attraction and the distance from
    the particle to the attracting point.

    \value Attractor.Constant Constant
    \value Attractor.Linear Linear
    \value Attractor.InverseLinear Inverse linear
    \value Attractor.Quadratic Quadratic
    \value Attractor.InverseQuadratic Inverse quadratic
*/


QQuickAttractorAffector::QQuickAttractorAffector(QQuickItem *parent) :
    QQuickParticleAffector(parent), m_strength(0.0), m_x(0), m_y(0)
  , m_physics(Velocity), m_proportionalToDistance(Linear)
{
}

bool QQuickAttractorAffector::affectParticle(QQuickParticleData *d, qreal dt)
{
    if (m_strength == 0.0)
        return false;
    qreal dx = m_x+m_offset.x() - d->curX(m_system);
    qreal dy = m_y+m_offset.y() - d->curY(m_system);
    qreal r = std::sqrt((dx*dx) + (dy*dy));
    qreal theta = std::atan2(dy,dx);
    qreal ds = 0;
    switch (m_proportionalToDistance){
    case InverseQuadratic:
        ds = (m_strength / qMax<qreal>(1.,r*r));
        break;
    case InverseLinear:
        ds = (m_strength / qMax<qreal>(1.,r));
        break;
    case Quadratic:
        ds = (m_strength * qMax<qreal>(1.,r*r));
        break;
    case Linear:
        ds = (m_strength * qMax<qreal>(1.,r));
        break;
    default: //also Constant
        ds = m_strength;
    }
    ds *= dt;
    dx = ds * std::cos(theta);
    dy = ds * std::sin(theta);
    qreal vx,vy;
    switch (m_physics){
    case Position:
        d->x = (d->x + dx);
        d->y = (d->y + dy);
        break;
    case Acceleration:
        d->setInstantaneousAX(d->ax + dx, m_system);
        d->setInstantaneousAY(d->ay + dy, m_system);
        break;
    case Velocity: //also default
    default:
        vx = d->curVX(m_system);
        vy = d->curVY(m_system);
        d->setInstantaneousVX(vx + dx, m_system);
        d->setInstantaneousVY(vy + dy, m_system);
    }

    return true;
}
QT_END_NAMESPACE

#include "moc_qquickpointattractor_p.cpp"