cangine
Loading...
Searching...
No Matches
rectangle.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <array>
5#include <cfloat>
6
7#include "../types/vector2.hpp"
8#include "../types/vector3.hpp"
9#include "../util/color.hpp"
10
11#include "../engine/components/transform_component.hpp"
12
13namespace cangine {
21 struct Rectangle {
23 float width;
24 float height;
26
34 inline static bool containsPoint(const Rectangle& rect, const Transform& transform, const Vector2& point) {
35 Vector3 pos = transform.getPosition();
36 Vector3 rot = transform.getRotation();
37 Vector3 scl = transform.getScale();
38
39 // transform point into rect's local space
40 float dx = point.x - pos.x;
41 float dy = point.y - pos.y;
42
43 float radians = -rot.z * 3.14159265f / 180.0f; // inverse rotation
44 float c = std::cos(radians);
45 float s = std::sin(radians);
46
47 float localX = dx * c - dy * s;
48 float localY = dx * s + dy * c;
49
50 float hw = (rect.width * scl.x) / 2.0f;
51 float hh = (rect.height * scl.y) / 2.0f;
52
53 return (localX >= -hw && localX <= hw) &&
54 (localY >= -hh && localY <= hh);
55 }
56
68 inline static bool overlaps(const Rectangle& r1, const Transform& t1,
69 const Rectangle& r2, const Transform& t2) {
70
71 // lambda that returns the 4 corners of a rect
72 auto getCorners = [](const Rectangle& r, const Transform& t) {
73 Vector3 pos = t.getPosition();
74 Vector3 rot = t.getRotation();
75 Vector3 scl = t.getScale();
76
77 float hw = (r.width * scl.x) / 2.0f;
78 float hh = (r.height * scl.y) / 2.0f;
79 float rad = rot.z * 3.14159265f / 180.0f;
80 float c = std::cos(rad), s = std::sin(rad);
81
82 auto rotate = [&](float x, float y) -> Vector2 {
83 return { pos.x + x*c - y*s, pos.y + x*s + y*c };
84 };
85
86 return std::array<Vector2, 4>{
87 rotate(-hw, -hh), rotate( hw, -hh),
88 rotate( hw, hh), rotate(-hw, hh)
89 };
90 };
91
92 auto corners1 = getCorners(r1, t1);
93 auto corners2 = getCorners(r2, t2);
94
95 // SAT: project all corners onto the given axis and check for overlap
96 auto testAxis = [](const Vector2& axis,
97 const std::array<Vector2, 4>& c1,
98 const std::array<Vector2, 4>& c2) -> bool {
99 float min1 = FLT_MAX, max1 = -FLT_MAX;
100 float min2 = FLT_MAX, max2 = -FLT_MAX;
101
102 for (auto& v : c1) {
103 float p = v.x * axis.x + v.y * axis.y;
104 min1 = std::min(min1, p); max1 = std::max(max1, p);
105 }
106 for (auto& v : c2) {
107 float p = v.x * axis.x + v.y * axis.y;
108 min2 = std::min(min2, p); max2 = std::max(max2, p);
109 }
110
111 return max1 >= min2 && max2 >= min1; // true if there is overlap
112 };
113
114 // 2 axes from r1 + 2 axes from r2 = 4 axes
115 Vector3 rot1 = t1.getRotation(), rot2 = t2.getRotation();
116 float rad1 = rot1.z * 3.14159265f / 180.0f;
117 float rad2 = rot2.z * 3.14159265f / 180.0f;
118
119 std::array<Vector2, 4> axes = {{
120 { std::cos(rad1), std::sin(rad1) }, // r1 x axis
121 {-std::sin(rad1), std::cos(rad1) }, // r1 y axis
122 { std::cos(rad2), std::sin(rad2) }, // r2 x axis
123 {-std::sin(rad2), std::cos(rad2) } // r2 y axis
124 }};
125
126 for (auto& axis : axes) {
127 if (!testAxis(axis, corners1, corners2))
128 return false; // separating axis found, no collision
129 }
130
131 return true; // all axes overlap, collision confirmed
132 }
133 };
134
141 constexpr inline bool operator>>(const Vector2& vec, const Rectangle& rect) noexcept {
142 float halfW = rect.width / 2.0f;
143 float halfH = rect.height / 2.0f;
144 return (vec.x >= rect.pos.x - halfW && vec.x <= rect.pos.x + halfW) &&
145 (vec.y >= rect.pos.y - halfH && vec.y <= rect.pos.y + halfH);
146 }
147
154 constexpr inline bool operator>>(const Rectangle& rect, const Vector2& vec) noexcept { return vec >> rect; };
155
162 constexpr inline bool operator>>(const Rectangle& r1, const Rectangle& r2) noexcept {
163 return (std::abs(r1.pos.x - r2.pos.x) < (r1.width + r2.width) / 2.0f) &&
164 (std::abs(r1.pos.y - r2.pos.y) < (r1.height + r2.height) / 2.0f);
165 }
166
167}
Component holding an object's position, rotation and scale.
Definition transform_component.hpp:17
Vector3 getPosition() const
Returns the position.
Definition transform_component.cpp:18
Vector3 getScale() const
Returns the scale.
Definition transform_component.cpp:34
Vector3 getRotation() const
Returns the rotation.
Definition transform_component.cpp:26
Definition audiomanager.cpp:4
constexpr bool operator>>(const Vector2 &vec, const Rectangle &rect) noexcept
Point-in-rectangle test (axis-aligned, untransformed).
Definition rectangle.hpp:141
RGBA color stored as normalized floating-point components.
Definition color.hpp:12
An axis-aligned rectangle with a position, size and color.
Definition rectangle.hpp:21
Color color
Fill color.
Definition rectangle.hpp:25
Vector3 pos
Center position (z is the layer).
Definition rectangle.hpp:22
static bool containsPoint(const Rectangle &rect, const Transform &transform, const Vector2 &point)
Tests whether a point lies inside a (possibly transformed) rectangle.
Definition rectangle.hpp:34
float width
Width before scaling.
Definition rectangle.hpp:23
float height
Height before scaling.
Definition rectangle.hpp:24
static bool overlaps(const Rectangle &r1, const Transform &t1, const Rectangle &r2, const Transform &t2)
Tests whether two (possibly transformed) rectangles overlap.
Definition rectangle.hpp:68
Two-component floating-point vector.
Definition vector2.hpp:13
float x
Definition vector2.hpp:14
float y
Vector components.
Definition vector2.hpp:14
Three-component floating-point vector.
Definition vector3.hpp:13
float y
Definition vector3.hpp:14
float z
Vector components.
Definition vector3.hpp:14
float x
Definition vector3.hpp:14