Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
potentialscene2d.cpp
Go to the documentation of this file.
1/**
2 * @file potentialscene2d.cpp
3 * @brief Implements the potentialscene2d physics/numerical component used by QPE experiments.
4 * @ingroup qpe_quantum
5 *
6 * Source: @c core/quantum/potentialscene2d.cpp. This file is part of Quantum Phenomena Explorer (QPE),
7 * maintained by Officina Turini. See LICENSE_IT.txt / LICENSE.txt for the
8 * QPE freeware source-available terms and THIRD_PARTY_NOTICES.txt for
9 * third-party components.
10 */
11
12#include "potentialscene2d.h"
13
14#include "potentialfield2d.h"
15
16#include <algorithm>
17#include <cmath>
18#include <limits>
19#include <vector>
20
21namespace qpe {
22namespace {
23
24/**
25 * @brief Performs finite.
26 * @param v The v value used by the operation.
27 */
28bool finite(float v) noexcept
29{
30 return std::isfinite(static_cast<double>(v));
31}
32
33/**
34 * @brief Performs positive.
35 * @param v The v value used by the operation.
36 */
37bool positive(float v) noexcept
38{
39 return finite(v) && v > 0.0f;
40}
41
42/**
43 * @brief Performs rasterize object.
44 * @param object The object value used by the operation.
45 * @param field Field data to read or modify.
46 */
48{
49 switch (object.type) {
51 field.addRectangle(object.centerX, object.centerY,
52 object.width, object.height, object.value);
53 break;
55 field.addCircle(object.centerX, object.centerY,
56 object.radius, object.value);
57 break;
59 const float halfLength = 0.5f * object.length;
60 field.addBarrier(object.centerX, object.centerY - halfLength,
61 object.centerX, object.centerY + halfLength,
62 object.thickness, object.value);
63 break;
64 }
66 field.addSingleSlit(object.centerX, object.wallWidth,
67 object.centerY, object.slitHeight, object.value);
68 break;
70 field.addDoubleSlit(object.centerX, object.wallWidth,
71 object.centerY, object.slitSeparation,
72 object.slitHeight, object.value);
73 break;
75 const float halfWidth = 0.5f * object.width;
76 const float halfHeight = 0.5f * object.height;
77 const std::vector<PotentialPoint2D> vertices = {
78 {object.centerX - halfWidth, object.centerY},
79 {object.centerX + halfWidth, object.centerY - halfHeight},
80 {object.centerX + halfWidth, object.centerY + halfHeight}
81 };
82 field.addPolygon(vertices, object.value);
83 break;
84 }
86 field.addGaussian(object.centerX, object.centerY,
87 object.sigmaX, object.sigmaY, object.value);
88 break;
90 field.addHarmonic(object.centerX, object.centerY, object.value,
91 object.curvatureX, object.curvatureY);
92 break;
94 field.addLinear(object.centerX, object.centerY, object.value,
95 object.slopeX, object.slopeY);
96 break;
98 field.addSoftenedRadial(object.centerX, object.centerY,
99 object.value, object.softening);
100 break;
102 field.addStadiumExterior(object.centerX, object.centerY,
103 object.width, object.radius, object.value);
104 break;
105 }
106}
107
108} // namespace
109
110bool PotentialObject2D::valid() const noexcept
111{
112 if (!finite(value) || !finite(centerX) || !finite(centerY)) {
113 return false;
114 }
115
116 switch (type) {
119 return positive(width) && positive(height);
121 return positive(radius);
123 return positive(length) && positive(thickness);
125 return positive(wallWidth) && positive(slitHeight);
127 return positive(wallWidth) && positive(slitHeight) && positive(slitSeparation);
129 return positive(sigmaX) && positive(sigmaY);
131 return finite(curvatureX) && finite(curvatureY);
133 return finite(slopeX) && finite(slopeY);
135 return positive(softening);
137 return positive(width) && positive(radius);
138 }
139 return false;
140}
141
142std::uint64_t PotentialScene2D::allocateId() noexcept
143{
144 if (nextId_ == 0) {
145 nextId_ = 1;
146 }
147 const std::uint64_t id = nextId_++;
148 if (nextId_ == 0) {
149 nextId_ = 1;
150 }
151 return id;
152}
153
155{
156 if (!object.valid()) {
157 return 0;
158 }
159
160 if (object.id == 0 || find(object.id) != nullptr) {
161 object.id = allocateId();
162 } else if (object.id >= nextId_) {
163 nextId_ = object.id + 1;
164 if (nextId_ == 0) {
165 nextId_ = 1;
166 }
167 }
168
169 objects_.push_back(object);
170 return object.id;
171}
172
173bool PotentialScene2D::update(std::uint64_t id, const PotentialObject2D &object)
174{
175 PotentialObject2D *existing = find(id);
176 if (!existing) {
177 return false;
178 }
179
180 PotentialObject2D replacement = object;
181 replacement.id = id;
182 if (!replacement.valid()) {
183 return false;
184 }
185
186 *existing = replacement;
187 return true;
188}
189
190bool PotentialScene2D::remove(std::uint64_t id)
191{
192 const std::vector<PotentialObject2D>::iterator it =
193 std::find_if(objects_.begin(), objects_.end(),
194 [id](const PotentialObject2D &object) { return object.id == id; });
195 if (it == objects_.end()) {
196 return false;
197 }
198 objects_.erase(it);
199 return true;
200}
201
203{
204 objects_.clear();
205 nextId_ = 1;
206}
207
208bool PotentialScene2D::empty() const noexcept
209{
210 return objects_.empty();
211}
212
213std::size_t PotentialScene2D::size() const noexcept
214{
215 return objects_.size();
216}
217
218const std::vector<PotentialObject2D> &PotentialScene2D::objects() const noexcept
219{
220 return objects_;
221}
222
223PotentialObject2D *PotentialScene2D::find(std::uint64_t id) noexcept
224{
225 for (PotentialObject2D &object : objects_) {
226 if (object.id == id) {
227 return &object;
228 }
229 }
230 return nullptr;
231}
232
233const PotentialObject2D *PotentialScene2D::find(std::uint64_t id) const noexcept
234{
235 for (const PotentialObject2D &object : objects_) {
236 if (object.id == id) {
237 return &object;
238 }
239 }
240 return nullptr;
241}
242
244{
245 target.clear();
246 if (target.empty()) {
247 return;
248 }
249
250 PotentialField2D scratch(target.width(), target.height(), target.dx(), target.dy());
251 for (const PotentialObject2D &object : objects_) {
252 if (!object.enabled || !object.valid()) {
253 continue;
254 }
255 scratch.clear();
256 rasterizeObject(object, scratch);
257 target.accumulate(scratch);
258 }
259}
260
261} // namespace qpe
Implements the Potential Field2D component.
void addHarmonic(float centerX, float centerY, Value offset, float curvatureX, float curvatureY)
Adds harmonic.
std::size_t height() const noexcept
Returns height.
void addLinear(float centerX, float centerY, Value offset, float slopeX, float slopeY)
Adds linear.
void clear() noexcept
Performs clear.
void addPolygon(const std::vector< PotentialPoint2D > &vertices, Value value)
Adds polygon.
void addRectangle(float centerX, float centerY, float width, float height, Value value)
Adds rectangle.
float dy() const noexcept
Performs dy.
void addCircle(float centerX, float centerY, float radius, Value value)
Adds circle.
bool empty() const noexcept
Performs empty.
void addGaussian(float centerX, float centerY, float sigmaX, float sigmaY, Value amplitude)
Adds gaussian.
std::size_t width() const noexcept
Returns width.
float dx() const noexcept
Performs dx.
void addBarrier(float x1, float y1, float x2, float y2, float thickness, Value value)
Adds barrier.
void addStadiumExterior(float centerX, float centerY, float straightLength, float radius, Value value)
Adds stadium exterior.
void addSoftenedRadial(float centerX, float centerY, Value coupling, float softening)
Adds softened radial.
void accumulate(const PotentialField2D &other, Value scale=1.0f)
Performs accumulate.
void addDoubleSlit(float centerX, float barrierWidth, float slitCenterY, float slitSeparation, float slitHeight, Value value)
Adds double slit.
void addSingleSlit(float centerX, float barrierWidth, float slitCenterY, float slitHeight, Value value)
Adds single slit.
std::uint64_t add(PotentialObject2D object)
Performs add.
std::uint64_t allocateId() noexcept
Performs allocate id.
void rasterize(PotentialField2D &target) const
Performs rasterize.
std::vector< PotentialObject2D > objects_
std::size_t size() const noexcept
Returns size.
PotentialObject2D * find(std::uint64_t id) noexcept
Performs find.
bool empty() const noexcept
Performs empty.
bool update(std::uint64_t id, const PotentialObject2D &object)
Performs update.
bool remove(std::uint64_t id)
Performs remove.
const std::vector< PotentialObject2D > & objects() const noexcept
Performs objects.
void clear() noexcept
Performs clear.
void rasterizeObject(const PotentialObject2D &object, PotentialField2D &field)
Performs rasterize object.
bool positive(float v) noexcept
Performs positive.
Declares the potentialfield2d physics/numerical component used by QPE experiments.
Declares the potentialscene2d physics/numerical component used by QPE experiments.
Data structure used by the Potential Object2D component.
PotentialObjectType2D type
bool valid() const noexcept
Performs valid.