103 lines
2.5 KiB
C++
103 lines
2.5 KiB
C++
// DR. ROBOTNIK'S RING RACERS
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2024 by James Robert Roman
|
|
// Copyright (C) 2024 by Kart Krew
|
|
//
|
|
// This program is free software distributed under the
|
|
// terms of the GNU General Public License, version 2.
|
|
// See the 'LICENSE' file for more details.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef math_line_equation_hpp
|
|
#define math_line_equation_hpp
|
|
|
|
#include "fixed.hpp"
|
|
#include "line_segment.hpp"
|
|
#include "vec.hpp"
|
|
|
|
namespace srb2::math
|
|
{
|
|
|
|
template <typename T>
|
|
struct LineEquation
|
|
{
|
|
using vec2 = Vec2<T>;
|
|
using line_segment = LineSegment<T>;
|
|
|
|
// Fixed-point: shift value by this amount during
|
|
// multiplications and divisions to avoid overflows.
|
|
static constexpr std::enable_if_t<std::is_same_v<T, Fixed>, fixed_t> kF = 1024; // fixed_t, not Fixed
|
|
|
|
LineEquation() {}
|
|
LineEquation(const vec2& p, const vec2& d) : d_(d), m_(d.y / d.x), b_(p.y - (p.x * m())) {}
|
|
LineEquation(const line_segment& l) : LineEquation(l.a, l.b - l.a) {}
|
|
|
|
const vec2& d() const { return d_; }
|
|
T m() const { return m_; }
|
|
T b() const { return b_; }
|
|
T y(T x) const { return (m() * x) + b(); }
|
|
|
|
vec2 intersect(const LineEquation& q) const
|
|
{
|
|
T x = (b() - q.b()) / (q.m() - m());
|
|
return {x, y(x)};
|
|
}
|
|
|
|
protected:
|
|
vec2 d_{};
|
|
T m_{}, b_{};
|
|
};
|
|
|
|
template <>
|
|
inline LineEquation<Fixed>::LineEquation(const vec2& p, const vec2& d) :
|
|
d_(d), m_((d.y / d.x) / kF), b_((p.y / kF) - (p.x * m_))
|
|
{
|
|
}
|
|
|
|
template <>
|
|
inline Fixed LineEquation<Fixed>::m() const
|
|
{
|
|
return m_ * kF;
|
|
}
|
|
|
|
template <>
|
|
inline Fixed LineEquation<Fixed>::b() const
|
|
{
|
|
return b_ * kF;
|
|
}
|
|
|
|
template <>
|
|
inline Fixed LineEquation<Fixed>::y(Fixed x) const
|
|
{
|
|
return ((m_ * x) + b_) * kF;
|
|
}
|
|
|
|
template <>
|
|
inline LineEquation<Fixed>::vec2 LineEquation<Fixed>::intersect(const LineEquation& q) const
|
|
{
|
|
Fixed x = ((b_ - q.b_) / ((q.m_ - m_) * kF)) * kF;
|
|
return {x, y(x)};
|
|
}
|
|
|
|
template <typename T>
|
|
struct LineEquationX : LineEquation<T>
|
|
{
|
|
T x(T y) const { return (y - LineEquation<T>::b()) / LineEquation<T>::m(); }
|
|
};
|
|
|
|
template <>
|
|
struct LineEquationX<Fixed> : LineEquation<Fixed>
|
|
{
|
|
LineEquationX() {}
|
|
LineEquationX(const vec2& p, const vec2& d) : LineEquation(p, d), w_((d.x / d.y) / kF), a_((p.x / kF) - (p.y * w_)) {}
|
|
LineEquationX(const line_segment& l) : LineEquationX(l.a, l.b - l.a) {}
|
|
|
|
Fixed x(Fixed y) const { return ((w_ * y) + a_) * kF; }
|
|
|
|
protected:
|
|
Fixed w_{}, a_{};
|
|
};
|
|
|
|
}; // namespace srb2::math
|
|
|
|
#endif/*math_line_equation_hpp*/
|