102 lines
3.0 KiB
C++
102 lines
3.0 KiB
C++
/* +------------------------------------------------------+
|
|
____/ \____ /| - Open source game framework licensed to freely use, |
|
|
\ / / | copy, modify and sell without restriction |
|
|
+--\ ^__^ /--+ | |
|
|
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
|
|
| ~~~~~~~~~~~~ | +------------------------------------------------------+
|
|
| SPACE ~~~~~ | /
|
|
| ~~~~~~~ BOX |/
|
|
+-------------*/
|
|
|
|
#pragma once
|
|
|
|
#include <ostream>
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <vector>
|
|
#include <functional>
|
|
#include <optional>
|
|
|
|
#include "glm/vec2.hpp"
|
|
|
|
class Box;
|
|
|
|
class Segment
|
|
{
|
|
|
|
private:
|
|
|
|
glm::vec2 start_, end_;
|
|
|
|
public:
|
|
|
|
Segment(const glm::vec2&, const glm::vec2&);
|
|
Segment();
|
|
Segment(const glm::vec2&);
|
|
Segment(const Box&, const Box&);
|
|
glm::vec2 start() const;
|
|
void start(const glm::vec2&);
|
|
glm::vec2 end() const;
|
|
void end(const glm::vec2&);
|
|
|
|
/*!
|
|
* Check for an intersection with another segment object. If the intersection argument is given a reference to a 2D vector,
|
|
* it will be filled with the point of intersection.
|
|
*
|
|
* Original source: http://www.realtimerendering.com/resources/GraphicsGems/gemsii/xlines.c
|
|
*
|
|
* @param segment segment to collide with
|
|
* @param intersection optional reference to a 2D vector to fill with the intersection point
|
|
* @return `true` if the two segments intersect, `false` otherwise
|
|
*/
|
|
bool intersect(const Segment& segment, std::optional<std::reference_wrapper<glm::vec2>> intersection = std::nullopt) const;
|
|
|
|
float dx() const;
|
|
float dy() const;
|
|
float length() const;
|
|
Box box() const;
|
|
void move(const glm::vec2&);
|
|
glm::vec2 center() const;
|
|
|
|
/*!
|
|
* @return angle in radians between the start and end points
|
|
*/
|
|
float angle() const;
|
|
|
|
/*!
|
|
* @param distance length of the step
|
|
* @return a 2D vector representing a step along the segment at the given distance
|
|
*/
|
|
glm::vec2 step(float distance) const;
|
|
|
|
glm::vec2 step_relative(float) const;
|
|
std::vector<Segment> subsegments(int) const;
|
|
inline bool operator<(const Segment& segment) const { return operator<(segment.length()); }
|
|
|
|
template<typename N>
|
|
inline bool operator<(const N& other) const { return length() < other; }
|
|
|
|
template<typename N>
|
|
inline bool operator>(const N& other) const { return other < length(); }
|
|
|
|
template<typename N>
|
|
inline bool operator<=(const N& other) const { return !operator>(other); }
|
|
|
|
template<typename N>
|
|
inline bool operator>=(const N& other) const { return !operator<(other); }
|
|
|
|
};
|
|
|
|
namespace std
|
|
{
|
|
std::ostream& operator<<(std::ostream&, const Segment&);
|
|
}
|
|
|
|
/* Add Segment class to the sb namespace. This should be the default location, but Segment is left in the global namespace
|
|
* for backward compatibility.
|
|
*/
|
|
namespace sb
|
|
{
|
|
using ::Segment;
|
|
}
|