20#include <unordered_set>
30#if __cplusplus >= 202002L
31#define CPP20_OR_LATER 1
33#define CPP20_OR_LATER 0
39 using Vec3 = YasiuMath::Types::Vec3<T>;
40 using Vec3f = YasiuMath::Types::Vec3<float>;
41 using Vec3d = YasiuMath::Types::Vec3<double>;
47 T Degrees2Radians( T degree )
53 T Radians2Degrees( T radian )
79 T temp =
static_cast<T
>(fmod(angle, period));
105 assert(spreadDistance > 0);
107 std::vector<std::pair<T, T>> result;
118 T dy = sin(beta) * spreadDistance;
119 T dx = cos(beta) * spreadDistance;
121 T X = cos(angle) * radius;
122 T Y = sin(angle) * radius;
128 result.push_back({X + dx, Y - dy});
130 result.push_back({X - dx, Y + dy});
153 T angle = atan2f(Y, X);
154 T radius = sqrtf((X * X) + (Y * Y));
186 T angleDiff = fmod(abs(alfa - beta), 360);
187 assert(symmetricWidth > 0);
188 assert(angleDiff > 0);
189 assert(angleDiff != 180);
191 T nominator = symmetricWidth * (sin(alfa) + sin(beta));
192 T denominator = cos(beta) - cos(alfa);
193 T result = abs(nominator / denominator);
225 std::pair<T, T> result;
227 T angleDiff = fmod(abs(alfa - beta), 360);
230 assert(angleDiff > 0);
231 assert(angleDiff != 180);
234 T nominator1 = sin(alfa) * widthA + sin(beta) * widthB;
235 T denominator1 = cos(alfa) - cos(beta);
236 T radius1 = abs(nominator1 / denominator1);
239 T nominator2 = -(cos(alfa) * widthA + cos(beta) * widthB);
240 T denominator2 = sin(alfa) - sin(beta);
241 T radius2 = abs(nominator2 / denominator2);
243 if ( widthA < widthB ) {
245 if ( radius1 > radius2 ) {
246 result.first = radius1;
247 result.second = radius2;
250 result.first = radius2;
251 result.second = radius1;
256 if ( radius1 < radius2 ) {
257 result.first = radius1;
258 result.second = radius2;
261 result.first = radius2;
262 result.second = radius1;
277 inline std::pair<T, T> CalculateVector(
278 const std::vector<std::pair<T, T>>& polygonPoints,
291 T dX = polygonPoints.at(ind1).first - polygonPoints.at(ind2).first;
292 T dY = polygonPoints.at(ind1).second - polygonPoints.at(ind2).second;
299 T Cross(
const std::pair<T, T>& A,
const std::pair<T, T>& B )
301 auto temp1 = A.first * B.second;
302 auto temp2 = A.second * B.first;
303 return temp1 - temp2;
308 void CheckHullBackwards(
309 std::vector<int>& currentConvex,
310 const int& checkIndex,
311 const std::vector<std::pair<T, T>>& allPoints,
312 const bool clockWise =
false
315 if ( currentConvex.size() < 2 ) {
return; }
319 std::pair<T, T> vec1 = CalculateVector<T>(allPoints, currentConvex.at(currentConvex.size() - 1), checkIndex);
320 std::pair<T, T> vec2 = CalculateVector<T>(
322 currentConvex.at(currentConvex.size() - 2),
323 currentConvex.at(currentConvex.size() - 1)
325 cross = Cross<T>(vec1, vec2);
328 std::pair<T, T> vec1 = CalculateVector<T>(
330 currentConvex.at(currentConvex.size() - 1),
331 currentConvex.at(currentConvex.size() - 2)
333 std::pair<T, T> vec2 = CalculateVector<T>(allPoints, checkIndex, currentConvex.at(currentConvex.size() - 1));
334 cross = Cross<T>(vec1, vec2);
341 currentConvex.pop_back();
343 CheckHullBackwards(currentConvex, checkIndex, allPoints, clockWise);
356 void AddPointToConvex(
357 std::vector<int>& currentConvex,
359 const std::vector<std::pair<T, T>>& allPoints,
360 const bool clockWise =
false
363 if ( currentConvex.size() <= 1 ) {
364 currentConvex.push_back(index);
368 CheckHullBackwards(currentConvex, index, allPoints, clockWise);
369 currentConvex.push_back(index);
382 std::vector<int>
ConvexHull2D(
const std::vector<std::pair<T, T>>& polygonPoints )
384 using namespace Types;
385 if ( polygonPoints.size() == 0 ) {
388 else if ( polygonPoints.size() == 1 ) {
391 else if ( polygonPoints.size() == 2 ) {
395 std::vector<IndexedPair<int, T>> sortedPoints;
396 sortedPoints.reserve(polygonPoints.size() + 1);
397 for (
int i = 0; i < static_cast<int>(polygonPoints.size()); i++ ) {
398 sortedPoints.emplace_back(
IndexedPair<int, T>(i, polygonPoints.at(i).first, polygonPoints.at(i).second));
402 sortedPoints.begin(),
404 [] (
const auto& a,
const auto& b ) {
406 return a.second < b.second;
412 Point<T> startEndDiff = top - bottom;
413 T angleThreshold = startEndDiff.fastAngleModded();
415 std::vector<PointAngle<T>> pointsOnLeft;
416 std::vector<PointAngle<T>> pointsOnRight;
421 if ( point == bottom || point == top ) {
426 T angle = temp.fastAngleModded();
428 if ( point.first == top.
first && point.first == bottom.
second ) {
431 else if ( angle > angleThreshold ) {
432 pointsOnLeft.emplace_back(point.index, angle);
435 pointsOnRight.emplace_back(point.index, angle);
440 std::sort(pointsOnLeft.begin(), pointsOnLeft.end(), std::greater<
PointAngle<T>>());
441 std::sort(pointsOnRight.begin(), pointsOnRight.end());
444 std::unordered_set<int> visitedPoints;
445 visitedPoints.reserve(polygonPoints.size());
448 std::vector<int> convexLeft;
449 std::vector<int> convexRight;
450 convexLeft.reserve(polygonPoints.size());
451 convexRight.reserve(polygonPoints.size());
454 convexLeft.push_back(bottom.
index);
455 visitedPoints.insert(bottom.
index);
456 if ( pointsOnLeft.size() > 0 ) {
457 convexLeft.push_back(pointsOnLeft.at(0).index);
458 visitedPoints.insert(pointsOnLeft.at(0).index);
459 Point<T> pt = CalculateVector<T>(polygonPoints, pointsOnLeft.at(0).index, bottom.
index);
463 if ( nextPoint.index == top.
index ) {
468 if ( visitedPoints.contains(nextPoint.index) ) {
473 if ( visitedPoints.find(nextPoint.index) != visitedPoints.end() ) {
481 visitedPoints.insert(nextPoint.index);
482 AddPointToConvex<T>(convexLeft, nextPoint.index, polygonPoints,
true);
485 AddPointToConvex<T>(convexLeft, top.
index, polygonPoints,
true);
492 visitedPoints.clear();
493 convexRight.push_back(bottom.
index);
494 visitedPoints.insert(bottom.
index);
495 if ( pointsOnRight.size() > 0 ) {
496 convexRight.push_back(pointsOnRight.at(0).index);
497 visitedPoints.insert(pointsOnRight.at(0).index);
503 if ( nextPoint.index == top.
index ) {
507 if ( visitedPoints.find(nextPoint.index) != visitedPoints.end() ) {
513 visitedPoints.insert(nextPoint.index);
514 AddPointToConvex<T>(convexRight, nextPoint.index, polygonPoints);
517 AddPointToConvex<T>(convexRight, top.
index, polygonPoints);
546 for (
auto it = convexLeft.end(); it != convexLeft.begin(); ) {
549 if ( point == top.
index || point == bottom.
index ) {
continue; }
550 convexRight.push_back(point);
620 TempState.
AutoStep(QueryTime, DeltaTime);
651 return ProjectileState;
654 const T Xa = ProjectileState.
Acceleration.LengthSquared();
658 const T delta = Xb * Xb - 4 * Xa * Xc;
659 T TimeToMaxSpeed = -1;
670 TimeToMaxSpeed = -Xb / (2 * Xa);
674 T x1 = (-Xb - std::sqrt(delta)) / (2 * Xa);
675 T x2 = (-Xb + std::sqrt(delta)) / (2 * Xa);
684 if ( x1 > 0 && x2 > 0 && x1 < x2 ) {
701 if ( QueryTime < TimeToMaxSpeed || TimeToMaxSpeed < 0 ) {
704 QueryTime * QueryTime);
710 TimeToMaxSpeed * TimeToMaxSpeed);
718 float RestofTime = QueryTime - TimeToMaxSpeed;
719 if ( RestofTime > 0 ) {
725 return ProjectileState;
748 const auto TrapezVelocity = (oldVel +
Velocity) / 2;
751 Vec3<T> drag = (TrapezVelocity * TrapezVelocity.Abs()) *
AirFrictionCoeff * deltaTime;
761 const auto CurSpeed =
Velocity.Length();
794 const int N = QueryTime / DeltaTime;
795 for (
int i = 0; i < N; i++ ) {
799 const T missingTime = QueryTime - (DeltaTime * N);
800 if ( missingTime > 0 ) {
858 const Vec3<T>& TargetPosition,
859 const Vec3<T>& TargetVelocity,
861 Vec3<T>& InterceptLocation
888 const T MaxQueryTime,
921 const T MaxQueryTime,
952 const T MaxQueryTime,
954 const T AccurateStepTime,
959 return InterceptMissile_Dynamic(Target, Interceptor, MaxQueryTime, StepTime, AccurateStepTime, HitLocation, TempTime);
988 const T MaxQueryTime,
990 const T AccurateStepTime,
1000 template<
typename T>
1021 template<
typename T>
1022 T
Remap(
const T Value,
const T InMin,
const T InMax, T OutMin, T OutMax,
const bool ClampOutput =
false )
1024 const T SubVal = Value - InMin;
1025 const T Divid = InMax - InMin;
1027 if ( OutMax < OutMin ) {
1028 std::swap(OutMin, OutMax);
1036 const T Factor = SubVal / Divid;
1039 const T SubValOut = OutMax - OutMin;
1040 const T Output = (Factor * SubValOut) + OutMin;
1041 if ( ClampOutput ) {
1042 return std::clamp(Output, OutMin, OutMax);
1051#include "YasiuMathLib.inl"
Linear algebra problems.
Definition YasiuMathLib.h:1009
T Remap(const T Value, const T InMin, const T InMax, T OutMin, T OutMax, const bool ClampOutput=false)
Remaps Value between input range to output range with optional clamping.
Definition YasiuMathLib.h:1022
Linear and dynamic objects simulation / prediction.
Definition YasiuMathLib.h:578
bool InterceptMissile_Dynamic(ProjectileDynamicState< T > Target, const InterceptorParams< T > &Interceptor, const T MaxQueryTime, const T StepTime, Types::Vec3< T > &PredictedLocation)
Iterative state prediction. Returns first possible intercept location and time.
Definition YasiuMathLib.h:885
bool InterceptMissile_Linear(const Types::Vec3< T > &MissilePosition, const Types::Vec3< T > &MissileVelocity, const T BulletSpeed, Types::Vec3< T > &InterceptLocation, T &ImpactTime)
Linear movement with linear velocity, Fast: O(1).
constexpr double Y_PI
Famous PI value.
Definition Constants.h:14
constexpr double EPSILON
Value used for number stability check.
Definition Constants.h:17
Convex hull functions and helper functions.
Definition YasiuMathLib.h:273
std::vector< int > ConvexHull2D(const std::vector< std::pair< T, T > > &polygonPoints)
Find Convex Hull in 2D space from given points.
Definition YasiuMathLib.h:382
Generic functions.
Definition YasiuMathLib.h:998
bool IsNearly0(T Value)
Checks if value is nearly 0, YasiuMath::Constants::EPSILON.
Definition YasiuMathLib.h:1001
Manipulation of rotation or angles.
Definition YasiuMathLib.h:45
T NormalizeAngleToPeriod(T angle, T period=360.f)
Normalize angle to range <0, period>. Unit independent.
Definition YasiuMathLib.h:73
Trigonometry problems in 2D or 3D space.
Definition YasiuMathLib.h:91
std::vector< std::pair< T, T > > SpreadPointsOnTangentByAngleRadius(const T angle, const T radius, const T spreadDistance)
Definition YasiuMathLib.h:102
T FindMinimalRadiusForIntersectingTangentsOnArc(const T alfa, const T beta, const T symmetricWidth)
Finds radius of circle for both tangent line that intersect.
Definition YasiuMathLib.h:179
std::vector< std::pair< T, T > > SpreadPointsOnTangentByXY(const T X, const T Y, const T spreadDistance)
Spread points on tangent line to arc.
Definition YasiuMathLib.h:151
std::pair< T, T > FindMinimalRadiusForIntersectingTangentsOnArcAsymmetric(const T alfa, const T beta, const T widthA, const T widthB)
Finds radius of 2 circles for both tangent line that intersect. Tangents on circle are defined by ang...
Definition YasiuMathLib.h:218
Generic Types used in library.
Definition YasiuMathDataTypes.h:24
Categorized name spaces.
Definition Constants.h:10
Params used for ballistics predictions.
Definition YasiuMathLib.h:812
T InitialSpeed
Speed at which object starts moving.
Definition YasiuMathLib.h:817
T Acceleration
Acceleration in any direction.
Definition YasiuMathLib.h:820
T AirResistance
Keep in <0, 1> range!
Definition YasiuMathLib.h:826
T MaxSpeed
Max speed object can reach with acceleration, 0 or less is ignored.
Definition YasiuMathLib.h:823
Ballistic state. Can move in time with DiscreteStep function.
Definition YasiuMathLib.h:587
T MaxSpeed
Maximal speed(length) of velocity vector.
Definition YasiuMathLib.h:606
ProjectileDynamicState PredictQuick(T QueryTime) const
Quick prediction of ballistic state at time. Limitation: Only constant acceleration and no Air Drag....
Definition YasiuMathLib.h:634
Vec3< T > Acceleration
Acceleration or Deceleration or combined with Gravity Forces.
Definition YasiuMathLib.h:597
virtual void DiscreteStep(T deltaTime)
Discrete Step. Function used to modify state in time.
Definition YasiuMathLib.h:737
void AutoStep(T QueryTime, T DeltaTime)
Step function. O(1) for AirDrag=0.
Definition YasiuMathLib.h:787
Vec3< T > Position
Current position.
Definition YasiuMathLib.h:591
ProjectileDynamicState Predict(T QueryTime, T DeltaTime) const
Prediction.
Definition YasiuMathLib.h:617
T AirFrictionCoeff
Movement resistance opposite to current velocity vector. Must be in <0, 1> range. More in details....
Definition YasiuMathLib.h:603
Vec3< T > Velocity
Movement velocity vector.
Definition YasiuMathLib.h:594
Helper object, for point description in algorithm. Index and 2 values.
Definition YasiuMathDataTypes.h:69
T second
Definition YasiuMathDataTypes.h:75
U index
Definition YasiuMathDataTypes.h:71
T first
Definition YasiuMathDataTypes.h:73
Helper Struct. Point description with index and angle.
Definition YasiuMathDataTypes.h:105
Pair-like type, Helper for point description in ConvexHull algorithm.
Definition YasiuMathDataTypes.h:33
Structure reflecting vector of size 3, Templated Type.
Definition YasiuMathDataTypes.h:142
T Length() const
Default Pythagoras Length.
Definition YasiuMathDataTypes.h:292