2020-11-21 19:57:40 +00:00
|
|
|
#include "sdlpp_circlecolider.hpp"
|
2021-03-13 14:05:16 +00:00
|
|
|
#include "sdlpp_geometry.hpp"
|
2020-11-21 19:57:40 +00:00
|
|
|
|
|
|
|
namespace SDLPP {
|
|
|
|
CircleColider::CircleColider( double x, double y, double rad )
|
2021-03-13 17:36:29 +00:00
|
|
|
: CircleColider( { x, y }, rad ) {}
|
2021-03-12 21:33:46 +00:00
|
|
|
|
|
|
|
CircleColider::CircleColider( const Vec2D< double > ¢er, double rad )
|
|
|
|
: CollisionPolygon( center ), original_rad( rad ) {}
|
2021-04-26 19:57:31 +00:00
|
|
|
CircleColider::CircleColider( double x, double y, double rad, uint64_t id )
|
|
|
|
: CircleColider( { x, y }, rad, id ) {}
|
|
|
|
CircleColider::CircleColider( const Vec2D< double > ¢er, double rad,
|
|
|
|
uint64_t id )
|
|
|
|
: CircleColider( center, rad ) {
|
|
|
|
_id = id;
|
|
|
|
}
|
2020-11-21 19:57:40 +00:00
|
|
|
|
|
|
|
bool CircleColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
|
|
|
|
if ( other.isCircle() ) {
|
2021-03-13 14:05:16 +00:00
|
|
|
/* check if distance of centers is lower than radiuses added together */
|
|
|
|
int otherRad =
|
|
|
|
dynamic_cast< const SDLPP::CircleColider & >( other ).getRadius();
|
2020-11-21 19:57:40 +00:00
|
|
|
int thisRad = getRadius();
|
|
|
|
int totalDist = otherRad + thisRad;
|
2021-03-13 14:05:16 +00:00
|
|
|
int xdiff = other.getX() - getX();
|
|
|
|
int ydiff = other.getY() - getY();
|
2020-11-21 19:57:40 +00:00
|
|
|
return ( xdiff * xdiff + ydiff * ydiff ) <= totalDist * totalDist;
|
|
|
|
} else if ( other.isInfinite() ) {
|
|
|
|
return infinityIntersection( other, *this );
|
|
|
|
}
|
2021-03-13 14:05:16 +00:00
|
|
|
/* other is not a circle */
|
|
|
|
int rad = getRadius();
|
|
|
|
for ( auto &line : other.getLines() ) {
|
|
|
|
auto distance = pointLineDistance( position, line );
|
|
|
|
if ( distance * distance <= rad * rad )
|
|
|
|
return true;
|
2020-11-21 19:57:40 +00:00
|
|
|
}
|
2021-03-13 14:05:16 +00:00
|
|
|
return false;
|
2020-11-21 19:57:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CircleColider::isCircle() const {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
int CircleColider::topmost() const {
|
|
|
|
return getY() - rad_;
|
|
|
|
}
|
|
|
|
int CircleColider::bottommost() const {
|
|
|
|
return getY() + rad_;
|
|
|
|
}
|
|
|
|
int CircleColider::leftmost() const {
|
|
|
|
return getX() - rad_;
|
|
|
|
}
|
|
|
|
int CircleColider::rightmost() const {
|
|
|
|
return getX() + rad_;
|
|
|
|
}
|
|
|
|
|
2021-04-26 19:57:31 +00:00
|
|
|
void CircleColider::updateCollision( int x, int y, int w, int h, uint64_t id ) {
|
2021-03-13 14:05:16 +00:00
|
|
|
position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y );
|
2020-11-21 19:57:40 +00:00
|
|
|
rad_ = original_rad * w;
|
2021-04-26 19:57:31 +00:00
|
|
|
if ( _id == static_cast< uint64_t >( -1 ) )
|
|
|
|
_id = id;
|
2020-11-21 19:57:40 +00:00
|
|
|
}
|
|
|
|
|
2021-03-13 14:05:16 +00:00
|
|
|
void CircleColider::render( Renderer &renderer, const SDL_Color &color,
|
|
|
|
const SDL_Color &outline_color ) {
|
2020-11-21 19:57:40 +00:00
|
|
|
std::vector< int > rect = { leftmost(), topmost(), rightmost(),
|
|
|
|
bottommost() };
|
|
|
|
auto center_x = getX();
|
|
|
|
auto center_y = getY();
|
|
|
|
auto radsq = rad_ * rad_;
|
|
|
|
for ( int i = rect[0]; i <= rect[2]; i++ ) {
|
|
|
|
auto xdiff = center_x - i;
|
|
|
|
auto xdist = xdiff * xdiff;
|
|
|
|
auto allowed_rad = sqrt( radsq - xdist );
|
2021-03-13 14:05:16 +00:00
|
|
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(), color.r, color.g,
|
|
|
|
color.b, color.a );
|
2020-11-21 19:57:40 +00:00
|
|
|
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
|
|
|
center_y - allowed_rad, i, center_y + allowed_rad );
|
2021-03-13 14:05:16 +00:00
|
|
|
SDL_SetRenderDrawColor( renderer.getRendererPtr(), outline_color.r,
|
|
|
|
outline_color.g, outline_color.b,
|
|
|
|
outline_color.a );
|
2020-11-21 19:57:40 +00:00
|
|
|
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
|
|
|
center_y - allowed_rad, i,
|
|
|
|
center_y - allowed_rad + 2 );
|
|
|
|
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
|
|
|
center_y + allowed_rad, i,
|
|
|
|
center_y + allowed_rad - 2 );
|
|
|
|
}
|
|
|
|
}
|
2021-03-13 14:05:16 +00:00
|
|
|
|
|
|
|
void CircleColider::render( Renderer &renderer, const SDL_Color &color ) {
|
|
|
|
auto input_color = color;
|
|
|
|
auto outline_color = color;
|
|
|
|
input_color.a = 0x40;
|
|
|
|
outline_color.a = 0x80;
|
|
|
|
render( renderer, input_color, outline_color );
|
|
|
|
}
|
|
|
|
|
2020-11-21 19:57:40 +00:00
|
|
|
void CircleColider::render( Renderer &renderer ) {
|
2021-03-13 14:05:16 +00:00
|
|
|
render( renderer, sdl_color, sdl_outline );
|
2020-11-21 19:57:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int CircleColider::getRadius() const {
|
|
|
|
return rad_;
|
|
|
|
}
|
2020-12-18 15:02:02 +00:00
|
|
|
|
|
|
|
std::shared_ptr< CollisionPolygon > CircleColider::copySelf() {
|
|
|
|
return std::make_shared< CircleColider >( *this );
|
|
|
|
}
|
2021-03-13 14:05:16 +00:00
|
|
|
|
|
|
|
std::vector< Line< int > > CircleColider::getLines() const {
|
|
|
|
return {};
|
|
|
|
}
|
2020-11-21 19:57:40 +00:00
|
|
|
} // namespace SDLPP
|