Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
ObjectPosSelector.h
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#ifndef SF_OBJECT_POS_SELECTOR_H
7#define SF_OBJECT_POS_SELECTOR_H
8
9#include<Common.h>
10
11#include<map>
12
14
16{
17 return uptype == USED_POS_PLUS ? USED_POS_MINUS : USED_POS_PLUS;
18}
19
21{
22 struct UsedPos
23 {
24 UsedPos(float sign_, float size_, float dist_) : sign(sign_), size(size_), dist(dist_) { }
25
26 float sign;
27
28 float size; // size of point
29 float dist; // dist to central point (including central point size)
30 };
31
32 typedef std::multimap<float, UsedPos> UsedPosList; // abs(angle)->Node
33
34 ObjectPosSelector(float x, float y, float size, float dist);
35
36 void AddUsedPos(float size, float angle, float dist);
37 void InitializeAngle();
38
39 bool FirstAngle(float& angle);
40 bool NextAngle(float& angle);
41 bool NextUsedAngle(float& angle);
42
43 bool NextPosibleAngle(float& angle);
44
45 bool CheckAngle(UsedPosList::value_type const& nextUsedPos, float sign, float angle) const
46 {
47 float angle_step2 = GetAngle(nextUsedPos.second);
48
49 float next_angle = nextUsedPos.first;
50 if (nextUsedPos.second.sign * sign < 0) // last node from diff. list (-pi+alpha)
51 next_angle = 2 * M_PI - next_angle; // move to positive
52
53 return fabs(angle) + angle_step2 <= next_angle;
54 }
55
56 bool CheckOriginal() const
57 {
58 return (m_UsedPosLists[USED_POS_PLUS].empty() || CheckAngle(*m_UsedPosLists[USED_POS_PLUS].begin(), 1.0f, 0)) &&
59 (m_UsedPosLists[USED_POS_MINUS].empty() || CheckAngle(*m_UsedPosLists[USED_POS_MINUS].begin(), -1.0f, 0));
60 }
61
62 bool IsNonBalanced() const { return m_UsedPosLists[USED_POS_PLUS].empty() != m_UsedPosLists[USED_POS_MINUS].empty(); }
63
64 bool NextAngleFor(UsedPosList::value_type const& usedPos, float sign, UsedPosType uptype, float& angle)
65 {
66 float angle_step = GetAngle(usedPos.second);
67
68 // next possible angle
69 angle = usedPos.first * usedPos.second.sign + angle_step * sign;
70
71 UsedPosList::value_type const* nextNode = nextUsedPos(uptype);
72 if (nextNode)
73 {
74 // if next node permit use selected angle, then do it
75 if (!CheckAngle(*nextNode, sign, angle))
76 {
77 m_smallStepOk[uptype] = false;
78 return false;
79 }
80 }
81
82 // possible more points
83 m_smallStepOk[uptype] = true;
84 m_smallStepAngle[uptype] = angle;
85 m_smallStepNextUsedPos[uptype] = nextNode;
86
87 return true;
88 }
89
90 bool NextSmallStepAngle(float sign, UsedPosType uptype, float& angle)
91 {
92 // next possible angle
93 angle = m_smallStepAngle[uptype] + m_anglestep * sign;
94
95 if (fabs(angle) > M_PI)
96 {
97 m_smallStepOk[uptype] = false;
98 return false;
99 }
100
101 if (m_smallStepNextUsedPos[uptype])
102 {
103 if (fabs(angle) >= m_smallStepNextUsedPos[uptype]->first)
104 {
105 m_smallStepOk[uptype] = false;
106 return false;
107 }
108
109 // if next node permit use selected angle, then do it
110 if (!CheckAngle(*m_smallStepNextUsedPos[uptype], sign, angle))
111 {
112 m_smallStepOk[uptype] = false;
113 return false;
114 }
115 }
116
117 // possible more points
118 m_smallStepAngle[uptype] = angle;
119 return true;
120 }
121
122 // next used post for m_nextUsedPos[uptype]
123 UsedPosList::value_type const* nextUsedPos(UsedPosType uptype);
124
125 // angle from used pos to next possible free pos
126 float GetAngle(UsedPos const& usedPos) const { return acos(m_dist / (usedPos.dist + usedPos.size + m_size)); }
127
130 float m_size; // size of object in center
131 float m_dist; // distance for searching pos (including central object size)
133
135 UsedPosList::const_iterator m_nextUsedPos[2];
136
137 // field for small step from first after next used pos until next pos
140 UsedPosList::value_type const* m_smallStepNextUsedPos[2];
141};
142#endif
#define M_PI
Definition Common.h:192
UsedPosType operator~(UsedPosType uptype)
UsedPosType
@ USED_POS_PLUS
@ USED_POS_MINUS
UsedPos(float sign_, float size_, float dist_)
bool IsNonBalanced() const
bool NextAngleFor(UsedPosList::value_type const &usedPos, float sign, UsedPosType uptype, float &angle)
bool FirstAngle(float &angle)
ObjectPosSelector(float x, float y, float size, float dist)
bool NextPosibleAngle(float &angle)
UsedPosList::const_iterator m_nextUsedPos[2]
bool CheckAngle(UsedPosList::value_type const &nextUsedPos, float sign, float angle) const
std::multimap< float, UsedPos > UsedPosList
bool NextUsedAngle(float &angle)
bool NextSmallStepAngle(float sign, UsedPosType uptype, float &angle)
UsedPosList::value_type const * nextUsedPos(UsedPosType uptype)
UsedPosList::value_type const * m_smallStepNextUsedPos[2]
bool CheckOriginal() const
void AddUsedPos(float size, float angle, float dist)
float GetAngle(UsedPos const &usedPos) const
bool NextAngle(float &angle)
UsedPosList m_UsedPosLists[2]