Phyth v0.1.0
A dimensional safe C++ header-only mechanics and electromagnetics simulation library.
Loading...
Searching...
No Matches
Constrainer.hpp
Go to the documentation of this file.
1#ifndef PHYTH_CONSTRAINER_HPP
2#define PHYTH_CONSTRAINER_HPP
3
4#include <memory>
5#include <utility>
6#include <cmath>
7
8#include "Particle.hpp"
10#include "Phyth/Core/Unit.hpp"
11
35 public:
45 DistanceConstrainer(std::shared_ptr<Particle> anchor, std::shared_ptr<Particle> particle)
46 : anchor_(std::move(anchor)), particle_(std::move(particle)),
47 interval_((particle_->GetPosition() - anchor_->GetPosition()).Length()) {
49 }
50
60 DistanceConstrainer(std::shared_ptr<Particle> anchor, std::shared_ptr<Particle> particle,
64 }
65
78 void Correct() const {
79 const Vector3<Quantity<Meter> > diff = particle_->GetPosition() - anchor_->GetPosition();
80 const Quantity<Meter> length = diff.Length();
82 return;
83
88
89 particle_->SetVelocity(particle_->GetVelocity() - (diff - target_offset) / Config::dt);
90 }
91
92 private:
93 std::shared_ptr<Particle> anchor_;
94 std::shared_ptr<Particle> particle_;
95
97
103 void IntervalCheck() const {
105 throw std::invalid_argument("DistanceConstrainer: interval minimum must be non-negative");
106 }
107 }
108 };
109
136 public:
145 AngleConstrainer(std::shared_ptr<Particle> anchor, std::shared_ptr<Particle> particle)
146 : anchor_(std::move(anchor)), particle_(std::move(particle)),
147 theta_interval_(std::get<1>((particle_->GetPosition() - anchor_->GetPosition()).ToSpherical())),
148 phi_interval_(std::get<2>((particle_->GetPosition() - anchor_->GetPosition()).ToSpherical())) {
150 }
151
161 AngleConstrainer(std::shared_ptr<Particle> anchor, std::shared_ptr<Particle> particle,
164 phi_interval_(std::get<2>((particle_->GetPosition() - anchor_->GetPosition()).ToSpherical())) {
166 }
167
178 AngleConstrainer(std::shared_ptr<Particle> anchor, std::shared_ptr<Particle> particle,
183 }
184
199 void Correct(const Quantity<Second> dt) const {
200 const Vector3<Quantity<Meter> > diff = particle_->GetPosition() - anchor_->GetPosition();
201 const Quantity<Meter> length = diff.Length();
202
203 if (length == 0_m) {
204 return;
205 }
206
207 const auto spherical = diff.ToSpherical();
208 Quantity<Radian> theta = std::get<1>(spherical);
209 Quantity<Radian> phi = std::get<2>(spherical);
210
211 // Wrap angles to [-2pi, 2pi] for validation
216
218 ? theta
222
224 ? phi
225 : phi > phi_interval_.GetMaximum()
228
229 if (theta == target_theta && phi == target_phi) {
230 return;
231 }
232
237 };
238
239 const Vector3<Quantity<Meter> > position_error = diff - (target_pos - anchor_->GetPosition());
240 particle_->SetVelocity(particle_->GetVelocity() - position_error / dt);
241 }
242
243 private:
244 std::shared_ptr<Particle> anchor_;
245 std::shared_ptr<Particle> particle_;
246
249
258 void IntervalCheck() const {
260 throw std::invalid_argument("AngleConstrainer: theta interval minimum must be >= -2pi");
261 }
263 throw std::invalid_argument("AngleConstrainer: phi interval minimum must be >= -2pi");
264 }
266 throw std::invalid_argument("AngleConstrainer: theta interval maximum must be <= 2pi");
267 }
269 throw std::invalid_argument("AngleConstrainer: phi interval maximum must be <= 2pi");
270 }
271 }
272 };
273}
274
275#endif // PHYTH_CONSTRAINER_HPP
Constrains a particle's angular position around an anchor.
void IntervalCheck() const
Validate that angle intervals are within [-2pi, 2pi].
std::shared_ptr< Particle > particle_
std::shared_ptr< Particle > anchor_
AngleConstrainer(std::shared_ptr< Particle > anchor, std::shared_ptr< Particle > particle)
Construct with automatic intervals set to initial angles.
AngleConstrainer(std::shared_ptr< Particle > anchor, std::shared_ptr< Particle > particle, const Interval< Radian > &theta_interval, const Interval< Radian > &phi_interval)
Construct with custom theta and phi intervals.
AngleConstrainer(std::shared_ptr< Particle > anchor, std::shared_ptr< Particle > particle, const Interval< Radian > &theta_interval)
Construct with custom theta interval, phi fixed to initial value.
void Correct(const Quantity< Second > dt) const
Correct velocity to satisfy angular constraints (Velocity Constrain)
Constrains a particle's distance from an anchor within an interval.
DistanceConstrainer(std::shared_ptr< Particle > anchor, std::shared_ptr< Particle > particle)
Construct with automatic interval set to initial distance.
std::shared_ptr< Particle > anchor_
void Correct() const
Correct velocity to satisfy the distance constraint (Velocity Constrain)
std::shared_ptr< Particle > particle_
DistanceConstrainer(std::shared_ptr< Particle > anchor, std::shared_ptr< Particle > particle, const Interval< Meter > &interval)
Construct with a custom distance interval.
void IntervalCheck() const
Validate that the interval minimum is non-negative.
constexpr double tau
Definition Constants.hpp:7
constexpr double varpi
Definition Constants.hpp:8
Scalar cos(const Scalar q)
Cosine of a dimensionless quantity.
Quantity< UnitT > fmod(Quantity< UnitT > x, Quantity< UnitT > y)
Floating-point remainder of x / y.
Scalar sin(const Scalar q)
Sine of a dimensionless quantity.
constexpr bool is_unit_v
Definition Unit.hpp:79
Compile-time physical dimension as 7 SI base exponents.
Definition Dimension.hpp:25
Closed interval [min, max] of physical quantities.
Definition Interval.hpp:20
Quantity< UnitT > GetMaximum() const noexcept
Definition Interval.hpp:70
bool Contains(Quantity< UnitT > x) const noexcept
Check if a value lies within the interval.
Definition Interval.hpp:52
Quantity< UnitT > GetMinimum() const noexcept
Definition Interval.hpp:67
Physical quantity with a value and a compile-time unit.
Definition Quantity.hpp:27
3D vector with Quantity components
Definition Vector3.hpp:28
Vector3< Scalar > Normalized() const
Normalized vector (unit vector in the same direction)
Definition Vector3.hpp:382