20char UnicodeToChar(uint32_t unicode)
22 return (unicode < 128) ?
static_cast<char>(unicode) : 0;
25template<
typename TFloat>
26inline TFloat LimitRangeAngle(TFloat angleDegree)
28 static_assert(std::is_floating_point_v<TFloat>,
"TFloat must be a floating point value");
29 angleDegree =
static_cast<TFloat
>(std::fmod(angleDegree,
static_cast<TFloat
>(360)));
30 if (angleDegree <
static_cast<TFloat
>(0))
32 angleDegree +=
static_cast<TFloat
>(360.f);
39IsVertexInCone(
fge::Line const& line1,
fge::Line const& line2, fge::Vector2f
const& origin, fge::Vector2f
const& vertex)
41 auto const relativePos = vertex - origin;
43 auto const line1Product = fge::Cross2d(relativePos, line1.getDirection());
44 auto const line2Product = fge::Cross2d(relativePos, line2.getDirection());
46 return line1Product < 0.0f && line2Product > 0.0f;
48inline bool IsVertexInCone(
float coneAngle,
49 fge::Vector2f
const& direction,
50 fge::Vector2f
const& origin,
51 fge::Vector2f
const& vertex)
53 auto const demiConeAngle = glm::radians(coneAngle / 2.0f);
55 fge::Line const lineLeft{origin, glm::rotate(direction, -demiConeAngle), 1.0f};
56 fge::Line const lineRight{origin, glm::rotate(direction, demiConeAngle), 1.0f};
58 return fge::IsVertexInCone(lineLeft, lineRight, origin, vertex);
63fge::Rect<T> ToRect(fge::Vector2<T>
const& pos1, fge::Vector2<T>
const& pos2)
65 return fge::Rect<T>({(pos1.x < pos2.x) ? pos1.x : pos2.x, (pos1.y < pos2.y) ? pos1.y : pos2.y},
66 {(pos1.x > pos2.x) ? (pos1.x - pos2.x) : (pos2.x - pos1.x),
67 (pos1.y > pos2.y) ? (pos1.y - pos2.y) : (pos2.y - pos1.y)});
70fge::Rect<T> ToRect(std::vector<fge::Vector2<T>>
const& pos)
72 float smallestX = std::numeric_limits<float>::max();
73 float biggestX = std::numeric_limits<float>::lowest();
74 float smallestY = std::numeric_limits<float>::max();
75 float biggestY = std::numeric_limits<float>::lowest();
77 for (std::size_t i = 0; i < pos.size(); ++i)
79 if (pos[i].x < smallestX)
83 if (pos[i].x > biggestX)
87 if (pos[i].y < smallestY)
91 if (pos[i].y > biggestY)
97 return fge::Rect<T>({smallestX, smallestY}, {biggestX - smallestX, biggestY - smallestY});
100fge::Rect<T> ToRect(fge::Vector2<T>
const* pos, std::size_t size)
102 T smallestX = std::numeric_limits<T>::max();
103 T biggestX = std::numeric_limits<T>::lowest();
104 T smallestY = std::numeric_limits<T>::max();
105 T biggestY = std::numeric_limits<T>::lowest();
107 for (std::size_t i = 0; i < size; ++i)
109 if (pos[i].x < smallestX)
111 smallestX = pos[i].x;
113 if (pos[i].x > biggestX)
117 if (pos[i].y < smallestY)
119 smallestY = pos[i].y;
121 if (pos[i].y > biggestY)
127 return fge::Rect<T>({smallestX, smallestY}, {biggestX - smallestX, biggestY - smallestY});
132T ReachValue(T value, T target, T speed,
float deltaTime)
134 float travelDistance =
static_cast<float>(speed) * deltaTime;
135 float direction = (
static_cast<float>(target) -
static_cast<float>(value)) /
136 std::abs(
static_cast<float>(target) -
static_cast<float>(value));
137 T actualDistance = std::abs(target - value);
139 if (travelDistance >= actualDistance)
143 return static_cast<T
>(
static_cast<float>(value) + direction * travelDistance);
147inline constexpr float Cross2d(fge::Vector2f
const& vec1, fge::Vector2f
const& vec2)
149 return glm::cross(fge::Vector3f{vec1, 0.0f}, fge::Vector3f{vec2, 0.0f}).z;
151inline fge::Vector2f GetSegmentNormal(fge::Vector2f
const& vec1, fge::Vector2f
const& vec2)
153 return glm::normalize(fge::Vector2f{vec1.y - vec2.y, vec2.x - vec1.x});
155inline constexpr float GetAngle(fge::Vector2f
const& vec)
157 auto const angle = glm::degrees(std::atan2(vec.y, vec.x));
158 return angle < 0.0f ? angle + 360.0f : angle;
160inline constexpr float GetAngleBetween(fge::Vector2f
const& vec1, fge::Vector2f
const& vec2)
162 auto const angle = glm::degrees(std::atan2(fge::Cross2d(vec1, vec2), glm::dot(vec1, vec2)));
163 return angle < 0.0f ? angle + 360.0f : angle;
165inline float GetDistanceBetween(fge::Vector2f
const& vec1, fge::Vector2f
const& vec2)
167 return glm::length(vec2 - vec1);
170GetShortestDistanceBetween(fge::Vector2f
const& point, fge::Vector2f
const& lineStart, fge::Vector2f
const& lineEnd)
172 auto normalDir = glm::normalize(lineEnd - lineStart);
173 return std::abs((normalDir.y * (point.x - lineStart.x) - normalDir.x * (point.y - lineStart.y)) /
174 (normalDir.x * normalDir.x + normalDir.y * normalDir.y));
177template<
typename TIterator>
178TIterator GetNearestPoint(fge::Vector2f
const& point, TIterator
const& pointsBegin, TIterator
const& pointsEnd)
180 TIterator bestNearestPoint = pointsEnd;
181 float bestNearestDistance;
183 for (TIterator it = pointsBegin; it != pointsEnd; ++it)
185 float distance = fge::GetDistanceBetween(point, *it);
186 if (bestNearestPoint == pointsEnd)
188 bestNearestPoint = it;
189 bestNearestDistance = distance;
193 if (distance < bestNearestDistance)
195 bestNearestPoint = it;
196 bestNearestDistance = distance;
201 return bestNearestPoint;
204inline constexpr fge::Vector2f GetForwardVector(
float angle)
206 angle = glm::radians(angle);
207 return {std::cos(angle), std::sin(angle)};
209inline constexpr fge::Vector2f GetBackwardVector(
float angle)
211 angle = glm::radians(angle);
212 return -fge::Vector2f{std::cos(angle), std::sin(angle)};
214inline constexpr fge::Vector2f GetLeftVector(
float angle)
216 angle = glm::radians(angle - 90.0f);
217 return {std::cos(angle), std::sin(angle)};
219inline constexpr fge::Vector2f GetRightVector(
float angle)
221 angle = glm::radians(angle + 90.0f);
222 return {std::cos(angle), std::sin(angle)};
225inline constexpr float DotSquare(fge::Vector2f
const& vec)
227 return glm::dot(vec, vec);
230inline constexpr float GetHandedness(fge::Vector2f
const& vec1, fge::Vector2f
const& vec2, fge::Vector2f
const& vec3)
232 auto const edge1 = vec2 - vec1;
233 auto const edge2 = vec3 - vec2;
235 return fge::Cross2d(edge1, edge2);
238inline constexpr float ConvertRange(
float x,
float xMin,
float xMax,
float yMin,
float yMax)
240 float const a = (yMax - yMin) / (xMax - xMin);
241 float const b = yMin - xMin * a;
244inline constexpr fge::Vector2f ConvertRange(fge::Vector2f
const& x,
245 fge::Vector2f
const& xMin,
246 fge::Vector2f
const& xMax,
247 fge::Vector2f
const& yMin,
248 fge::Vector2f
const& yMax)
250 return fge::Vector2f{ConvertRange(x.x, xMin.x, xMax.x, yMin.x, yMax.x),
251 ConvertRange(x.y, xMin.y, xMax.y, yMin.y, yMax.y)};
254inline constexpr fge::Vector2f MapCircleToSquareCoords(fge::Vector2f
const& circleCoords)
256 fge::Vector2f
const circleCoordsPow2 = circleCoords * circleCoords;
258 return fge::Vector2f{0.5f * std::sqrt(2.0f + circleCoordsPow2.x - circleCoordsPow2.y +
259 2.0f * circleCoords.x *
static_cast<float>(FGE_MATH_SQRT2)) -
260 0.5f * std::sqrt(2.0f + circleCoordsPow2.x - circleCoordsPow2.y -
261 2.0f * circleCoords.x *
static_cast<float>(FGE_MATH_SQRT2)),
262 0.5f * std::sqrt(2.0f - circleCoordsPow2.x + circleCoordsPow2.y +
263 2.0f * circleCoords.y *
static_cast<float>(FGE_MATH_SQRT2)) -
264 0.5f * std::sqrt(2.0f - circleCoordsPow2.x + circleCoordsPow2.y -
265 2.0f * circleCoords.y *
static_cast<float>(FGE_MATH_SQRT2))};
267inline constexpr fge::Vector2f MapSquareToCircleCoords(fge::Vector2f
const& squareCoords)
269 return fge::Vector2f{squareCoords.x * std::sqrt(1.0f - 0.5f * squareCoords.y * squareCoords.y),
270 squareCoords.y * std::sqrt(1.0f - 0.5f * squareCoords.x * squareCoords.x)};
297float DurationToSecondFloat(T duration)
299 return std::chrono::duration<float, std::ratio<1, 1>>(duration).count();
Definition C_color.hpp:35
Definition extra_function.hpp:44