some of my collision detection (2d)

Code: Select all

```
#pragma once
namespace Thor
{
static constexpr int _pt0 = 0;
static constexpr int _pt1 = 1;
static constexpr int _pt2 = 2;
class Line_2D;
class AABB_2D;
class Sphere_2D;
class Triangle_2D;
class Polygon_2D;
template<typename T,int count>
class Shape
{
protected:
T points[count];
public:
Shape() {};
virtual ~Shape() {}
};
class AABB_2D : public Shape<Math::vec2, 2>
{
static constexpr int _min = 0;
static constexpr int _max = 1;
Math::vec2 m_extents;
public:
AABB_2D() {}
AABB_2D(const Math::vec2& pos, const Math::vec2& extents);
~AABB_2D() {}
Math::vec2 getMinPoint()const;
Math::vec2 getMaxPoint()const;
Math::vec2 getHalfExtents()const;
Math::vec2 getExtents()const;
Math::vec2& operator[](const int& index)
{
if (index < _min || index > _max)
return points[0];
return points[index];
}
Math::vec2 operator[](const int& index)const
{
if (index < _min || index > _max)
return Math::vec2(FLT_MAX);
return points[index];
}
void set(const Math::vec2& position, const Math::vec2& extents);
inline Math::vec2 getCenter() { return points[_min] + getHalfExtents(); }
inline float getMinX()const { return points[_min].x; };
inline float getMinY()const { return points[_min].y; };
inline float getMaxX()const { return points[_max].x; };
inline float getMaxY()const { return points[_max].y; };
AABB_2D transform(const Math::vec2& position);
inline bool pointIn(const Math::vec2& pt)
{
return (pt.x > points[_min].x && pt.x < points[_max].x &&
pt.y > points[_min].y && pt.y < points[_max].y);
}
Line_2D getEdge(const unsigned int& index)const;
};
class Sphere_2D : public Shape<Math::vec2, 1>
{
float m_radius;
public:
Sphere_2D() {}
Sphere_2D(const Math::vec2& position, const float& radius);
~Sphere_2D() {}
inline Math::vec2 getCenter()const { return points[0]; }
inline float getRadius()const { return m_radius; }
inline float getRadiusSq()const { return m_radius * m_radius ; }
inline void set(const Math::vec2& position, const float& radius)
{
points[0] = position;
m_radius = radius;
}
inline void set(const Math::vec2& position)
{
points[0] = position;
}
inline bool pointIn(const Math::vec2& pt)
{
return (points[0] - pt).Magnitude() < m_radius;
}
};
class Line_2D : public Shape<Math::vec2, 2>
{
public:
Line_2D() {}
Line_2D(const Math::vec2& pt0, const Math::vec2& pt1);
~Line_2D() {}
inline Math::vec2 getPt0()const { return points[_pt0]; }
inline Math::vec2 getPt1()const { return points[_pt1]; }
inline void set(const Math::vec2& pt0, const Math::vec2& pt1)
{
points[_pt0] = pt0;
points[_pt1] = pt1;
};
Math::vec2& operator[](const int& index)
{
if (index < _pt0 || index > _pt1)
return points[_pt0];
return points[index];
}
Math::vec2 operator[](const int& index)const
{
if (index < _pt0 || index > _pt1)
return Math::vec2(FLT_MAX);
return points[index];
}
};
class Triangle_2D : public Shape<Math::vec2, 3>
{
public:
Triangle_2D() {}
Triangle_2D(const Math::vec2& pt0, const Math::vec2& pt1, const Math::vec2& pt2);
~Triangle_2D() {}
inline Math::vec2 getPt0()const { return points[_pt0]; }
inline Math::vec2 getPt1()const { return points[_pt1]; }
inline Math::vec2 getPt2()const { return points[_pt2]; }
inline Math::vec2 getCenter()const
{
Math::vec2 result = (points[_pt0] + points[_pt1] + points[_pt2]) / 3.0f;
return result;
}
Math::vec2& operator[](const int& index)
{
if (index < _pt0 || index > _pt2)
return points[0];
return points[index];
}
Math::vec2 operator[](const int& index)const
{
if (index < _pt0 || index > _pt2)
return Math::vec2(FLT_MAX);
return points[index];
}
Line_2D getEdge(const unsigned int& index)const;
};
class Polygon_2D
{
protected:
std::vector<Math::vec2> m_points;
public:
Polygon_2D() {}
Polygon_2D(const std::vector<Math::vec2>& points)
:m_points(points)
{};
~Polygon_2D() {}
inline size_t getPointCount()const { return m_points.size(); }
Line_2D getEdge(const unsigned int& index)const;
Math::vec2& operator[](const int& index)
{
if (index < 0 || index > m_points.size())
return m_points[0];
return m_points[index];
}
Math::vec2 operator[](const int& index)const
{
if (index < 0 || index > m_points.size())
return Math::vec2(FLT_MAX);
return m_points[index];
}
};
}
```

Code: Select all

```
#include "pch.h"
#include "Shapes.h"
namespace Thor
{
AABB_2D::AABB_2D(const Math::vec2 & pos, const Math::vec2 & extents)
{
points[_min] = pos;
points[_max] = pos + extents;
m_extents = extents;
}
Math::vec2 AABB_2D::getMinPoint() const
{
return points[_min];
}
Math::vec2 AABB_2D::getMaxPoint() const
{
return points[_max];
}
Math::vec2 AABB_2D::getHalfExtents() const
{
return m_extents * 0.5f;
}
Math::vec2 AABB_2D::getExtents() const
{
return m_extents;
}
void AABB_2D::set(const Math::vec2 & position, const Math::vec2 & extents)
{
points[_min] = position;
points[_max] = position + extents;
m_extents = extents;
}
AABB_2D AABB_2D::transform(const Math::vec2 & position)
{
return AABB_2D(position,m_extents);
}
Line_2D AABB_2D::getEdge(const unsigned int & index)const
{
switch (index)
{
case 0:
return Line_2D(Math::vec2(getMinX(),getMinY()), Math::vec2(getMaxX(), getMinY()));
case 1:
return Line_2D(Math::vec2(getMaxX(), getMinY()), Math::vec2(getMaxX(), getMaxY()));
case 2:
return Line_2D(Math::vec2(getMaxX(), getMaxY()), Math::vec2(getMinX(), getMaxY()));
case 3:
return Line_2D(Math::vec2(getMinX(), getMaxY()), Math::vec2(getMinX(), getMinY()));
};
return Line_2D();
}
Sphere_2D::Sphere_2D(const Math::vec2 & position, const float & radius)
{
points[0] = position;
m_radius = radius;
}
Line_2D::Line_2D(const Math::vec2 & pt0, const Math::vec2 & pt1)
{
points[_pt0] = pt0;
points[_pt1] = pt1;
}
Triangle_2D::Triangle_2D(const Math::vec2 & pt0, const Math::vec2 & pt1, const Math::vec2 & pt2)
{
points[_pt0] = pt0;
points[_pt1] = pt1;
points[_pt2] = pt2;
}
Line_2D Triangle_2D::getEdge(const unsigned int & index)const
{
switch (index)
{
case 0:
return Line_2D(points[_pt0], points[_pt1]);
case 1:
return Line_2D(points[_pt1], points[_pt2]);
case 2:
return Line_2D(points[_pt2], points[_pt0]);
};
return Line_2D();
}
Line_2D Polygon_2D::getEdge(const unsigned int & index) const
{
if (index >= 0)
{
if (index == m_points.size() - 1)
{
return Line_2D(m_points[index], m_points[0]);
}
return Line_2D(m_points[index], m_points[index + 1]);
}
return Line_2D();
};
}
```

Code: Select all

```
#pragma once
#include "Shapes.h"
namespace Thor
{
class Physics
{
public:
struct Intersection
{
bool hit;
float distance;
Intersection() {}
Intersection(const bool& hit, const float& dist)
:hit(hit), distance(distance)
{}
};
static Intersection line_Line2D(const Line_2D& lineA, const Line_2D& lineB);
static Intersection line_Line2D(const Math::vec2& pt1, const Math::vec2& pt2, const Math::vec2& pt3, const Math::vec2& pt4);
static Intersection line_AABB2D(const Line_2D& line, const AABB_2D& box);
static Intersection line_Triangle2D(const Line_2D& line, const Triangle_2D& tri);
static Intersection line_Polygon2D(const Line_2D& line, const Polygon_2D& poly);
static Intersection line_Sphere(const Line_2D& line, const Sphere_2D& sphere);
static Intersection AABB2D_AABB2D(const AABB_2D& box1, const AABB_2D& box2);
static Intersection Sphere2D_Sphere2D(const Sphere_2D& sphere1, const Sphere_2D& sphere2);
};
}
```

Code: Select all

```
#include "pch.h"
#include "Physics.h"
namespace Thor
{
Physics::Intersection Physics::line_Line2D(const Line_2D & lineA, const Line_2D & lineB)
{
return line_Line2D(lineA.getPt0(), lineA.getPt1(), lineB.getPt0(), lineB.getPt1());
}
Physics::Intersection Physics::line_Line2D(const Math::vec2 & pt1, const Math::vec2 & pt2,
const Math::vec2 & pt3, const Math::vec2 & pt4)
{
float s1_x = pt2.x - pt1.x;
float s1_y = pt2.y - pt1.y;
float s2_x = pt4.x - pt3.x;
float s2_y = pt4.y - pt3.y;
float s = (-s1_y * (pt1.x - pt3.x) + s1_x * (pt1.y - pt3.y)) / (-s2_x * s1_y + s1_x * s2_y);
float t = (s2_x * (pt1.y - pt3.y) - s2_y * (pt1.x - pt3.x)) / (-s2_x * s1_y + s1_x * s2_y);
return Intersection((s >= 0.0f && s <= 1.0f && t >= 0.0f && t <= 1.0f), 0.0f);
}
Physics::Intersection Physics::line_AABB2D(const Line_2D & line, const AABB_2D & box)
{
for (unsigned int i = 0; i < 4; i++)
{
Intersection inter = line_Line2D(line, box.getEdge(i));
if (inter.hit)
return inter;
}
return Intersection(false, 0.0f);
}
Physics::Intersection Physics::line_Triangle2D(const Line_2D & line, const Triangle_2D & tri)
{
for (unsigned int i = 0; i < 3; i++)
{
Intersection inter = line_Line2D(line, tri.getEdge(i));
if (inter.hit)
return inter;
}
return Intersection(false, 0.0f);
}
Physics::Intersection Physics::line_Polygon2D(const Line_2D & line, const Polygon_2D& poly)
{
for (unsigned int i = 0; i < poly.getPointCount(); i++)
{
Intersection inter = line_Line2D(line, poly.getEdge(i));
if (inter.hit)
return inter;
}
return Intersection(false, 0.0f);
}
Physics::Intersection Physics::line_Sphere(const Line_2D & line, const Sphere_2D & sphere)
{
Math::vec2 linePt1 = line.getPt0();
Math::vec2 linePt2 = line.getPt1();
Math::vec2 center = sphere.getCenter();
Math::vec2 ac = Math::vec2(center.x - linePt1.x, center.y - linePt1.y);
Math::vec2 ab = Math::vec2(linePt2.x - linePt1.x, linePt2.y - linePt1.y);
float ab2 = ab.Dot(ab);
float acab = ac.Dot(ab);
float t = acab / ab2;
t = (t < 0.0f) ? 0.0f : t;
t = (t > 1.0f) ? 1.0f : t;
Math::vec2 h = Math::vec2((ab.x * t + linePt1.x) - center.x, (ab.y * t + linePt1.y) - center.y);
float h2 = h.Dot(h);
return Intersection(h2 <= sphere.getRadiusSq(), 0.0f);
//return h2 <= sphere.getRadiusSq();
}
Physics::Intersection Physics::AABB2D_AABB2D(const AABB_2D & box1, const AABB_2D & box2)
{
return Intersection((box1.getMaxX() > box2.getMinX() &&
box1.getMinX() < box2.getMaxX() &&
box1.getMaxY() > box2.getMinY() &&
box1.getMinY() < box2.getMaxY()), 0.0f);
}
Physics::Intersection Physics::Sphere2D_Sphere2D(const Sphere_2D & sphere1, const Sphere_2D & sphere2)
{
Math::vec2 result = sphere1.getCenter() - sphere2.getCenter();
float lengthSq = result.x * result.x + result.y * result.y;
float radiusSq = sphere1.getRadiusSq() + sphere2.getRadiusSq();
return Intersection((lengthSq < radiusSq), 0.0f);
}
}
```