diff --git a/src/line.cpp b/src/line.cpp index ecd0605763800..a68ef3011a39a 100644 --- a/src/line.cpp +++ b/src/line.cpp @@ -16,49 +16,47 @@ extern bool trigdist; -void bresenham( const int x1, const int y1, const int x2, const int y2, int t, +void bresenham( const point &p1, const point &p2, int t, const std::function &interact ) { // The slope components. - const int dx = x2 - x1; - const int dy = y2 - y1; + const point d = p2 - p1; // Signs of slope values. - const int sx = ( dx == 0 ) ? 0 : sgn( dx ); - const int sy = ( dy == 0 ) ? 0 : sgn( dy ); + const int sx = ( d.x == 0 ) ? 0 : sgn( d.x ); + const int sy = ( d.y == 0 ) ? 0 : sgn( d.y ); // Absolute values of slopes x2 to avoid rounding errors. - const int ax = abs( dx ) * 2; - const int ay = abs( dy ) * 2; + const point a = abs( d ) * 2; - point cur( x1, y1 ); + point cur = p1; - if( ax == ay ) { - while( cur.x != x2 ) { + if( a.x == a.y ) { + while( cur.x != p2.x ) { cur.y += sy; cur.x += sx; if( !interact( cur ) ) { break; } } - } else if( ax > ay ) { - while( cur.x != x2 ) { + } else if( a.x > a.y ) { + while( cur.x != p2.x ) { if( t > 0 ) { cur.y += sy; - t -= ax; + t -= a.x; } cur.x += sx; - t += ay; + t += a.y; if( !interact( cur ) ) { break; } } } else { - while( cur.y != y2 ) { + while( cur.y != p2.y ) { if( t > 0 ) { cur.x += sx; - t -= ay; + t -= a.y; } cur.y += sy; - t += ax; + t += a.x; if( !interact( cur ) ) { break; } @@ -198,16 +196,16 @@ void bresenham( const tripoint &loc1, const tripoint &loc2, int t, int t2, //Trying to pull points out of a tripoint vector is messy and //probably slow, so leaving two full functions for now -std::vector line_to( const int x1, const int y1, const int x2, const int y2, int t ) +std::vector line_to( const point &p1, const point &p2, int t ) { std::vector line; // Preallocate the number of cells we need instead of allocating them piecewise. - const int numCells = square_dist( tripoint( x1, y1, 0 ), tripoint( x2, y2, 0 ) ); + const int numCells = square_dist( p1, p2 ); if( numCells == 0 ) { - line.push_back( {x1, y1} ); + line.push_back( p1 ); } else { line.reserve( numCells ); - bresenham( x1, y1, x2, y2, t, [&line]( const point & new_point ) { + bresenham( p1, p2, t, [&line]( const point & new_point ) { line.push_back( new_point ); return true; } ); @@ -215,11 +213,6 @@ std::vector line_to( const int x1, const int y1, const int x2, const int return line; } -std::vector line_to( const point &p1, const point &p2, const int t ) -{ - return line_to( p1.x, p1.y, p2.x, p2.y, t ); -} - std::vector line_to( const tripoint &loc1, const tripoint &loc2, int t, int t2 ) { std::vector line; @@ -237,11 +230,6 @@ std::vector line_to( const tripoint &loc1, const tripoint &loc2, int return line; } -float trig_dist( const int x1, const int y1, const int x2, const int y2 ) -{ - return trig_dist( tripoint( x1, y1, 0 ), tripoint( x2, y2, 0 ) ); -} - float trig_dist( const point &loc1, const point &loc2 ) { return trig_dist( tripoint( loc1, 0 ), tripoint( loc2, 0 ) ); @@ -254,30 +242,16 @@ float trig_dist( const tripoint &loc1, const tripoint &loc2 ) ( ( loc1.z - loc2.z ) * ( loc1.z - loc2.z ) ) ); } -int square_dist( const int x1, const int y1, const int x2, const int y2 ) -{ - return square_dist( point( x1, y1 ), point( x2, y2 ) ); -} - int square_dist( const point &loc1, const point &loc2 ) { - const int dx = abs( loc1.x - loc2.x ); - const int dy = abs( loc1.y - loc2.y ); - return dx > dy ? dx : dy; + const point d = abs( loc1 - loc2 ); + return std::max( d.x, d.y ); } int square_dist( const tripoint &loc1, const tripoint &loc2 ) { - const int dx = abs( loc1.x - loc2.x ); - const int dy = abs( loc1.y - loc2.y ); - const int dz = abs( loc1.z - loc2.z ); - int maxDxDy = ( dx > dy ? dx : dy ); // Sloppy, but should be quick. - return ( maxDxDy > dz ? maxDxDy : dz ); // Too bad it doesn't scale. -} - -int rl_dist( const int x1, const int y1, const int x2, const int y2 ) -{ - return rl_dist( tripoint( x1, y1, 0 ), tripoint( x2, y2, 0 ) ); + const tripoint d = abs( loc1 - loc2 ); + return std::max( { d.x, d.y, d.z } ); } int rl_dist( const point &a, const point &b ) @@ -406,9 +380,9 @@ direction direction_from( const tripoint &p ) noexcept return static_cast( make_xyz( p ) ); } -direction direction_from( const int x1, const int y1, const int x2, const int y2 ) noexcept +direction direction_from( const point &p1, const point &p2 ) noexcept { - return direction_from( point( x2 - x1, y2 - y1 ) ); + return direction_from( p2 - p1 ); } direction direction_from( const tripoint &p, const tripoint &q ) @@ -557,24 +531,24 @@ std::vector squares_closer_to( const tripoint &from, const tripoint &t // Returns a vector of the adjacent square in the direction of the target, // and the two squares flanking it. -std::vector squares_in_direction( const int x1, const int y1, const int x2, const int y2 ) +std::vector squares_in_direction( const point &p1, const point &p2 ) { int junk = 0; - point center_square = line_to( x1, y1, x2, y2, junk )[0]; + point center_square = line_to( p1, p2, junk )[0]; std::vector adjacent_squares; adjacent_squares.push_back( center_square ); - if( x1 == center_square.x ) { + if( p1.x == center_square.x ) { // Horizontally adjacent. - adjacent_squares.push_back( point( x1 + 1, center_square.y ) ); - adjacent_squares.push_back( point( x1 - 1, center_square.y ) ); - } else if( y1 == center_square.y ) { + adjacent_squares.push_back( point( p1.x + 1, center_square.y ) ); + adjacent_squares.push_back( point( p1.x - 1, center_square.y ) ); + } else if( p1.y == center_square.y ) { // Vertically adjacent. - adjacent_squares.push_back( point( center_square.x, y1 + 1 ) ); - adjacent_squares.push_back( point( center_square.x, y1 - 1 ) ); + adjacent_squares.push_back( point( center_square.x, p1.y + 1 ) ); + adjacent_squares.push_back( point( center_square.x, p1.y - 1 ) ); } else { // Diagonally adjacent. - adjacent_squares.push_back( point( x1, center_square.y ) ); - adjacent_squares.push_back( point( center_square.x, y1 ) ); + adjacent_squares.push_back( point( p1.x, center_square.y ) ); + adjacent_squares.push_back( point( center_square.x, p1.y ) ); } return adjacent_squares; } diff --git a/src/line.h b/src/line.h index fab466e1cc6a0..752bcc35fda3e 100644 --- a/src/line.h +++ b/src/line.h @@ -83,8 +83,6 @@ enum direction : unsigned { direction direction_from( const point &p ) noexcept; direction direction_from( const tripoint &p ) noexcept; -direction direction_from( int x1, int y1, int x2, int y2 ) noexcept; -direction direction_from( const point &p1, int x2, int y2 ) noexcept; direction direction_from( const point &p1, const point &p2 ) noexcept; direction direction_from( const tripoint &p, const tripoint &q ); @@ -99,10 +97,6 @@ std::string direction_suffix( const tripoint &p, const tripoint &q ); * The actual Bresenham algorithm in 2D and 3D, everything else should call these * and pass in an interact functor to iterate across a line between two points. */ -void bresenham( int x1, int y1, int x2, int y2, int t, - const std::function &interact ); -void bresenham( const point &p1, int x2, int y2, int t, - const std::function &interact ); void bresenham( const point &p1, const point &p2, int t, const std::function &interact ); void bresenham( const tripoint &loc1, const tripoint &loc2, int t, int t2, @@ -111,25 +105,18 @@ void bresenham( const tripoint &loc1, const tripoint &loc2, int t, int t2, tripoint move_along_line( const tripoint &loc, const std::vector &line, int distance ); // The "t" value decides WHICH Bresenham line is used. -std::vector line_to( int x1, int y1, int x2, int y2, int t = 0 ); -std::vector line_to( const point &p1, int x2, int y2, int t = 0 ); std::vector line_to( const point &p1, const point &p2, int t = 0 ); // t and t2 decide which Bresenham line is used. std::vector line_to( const tripoint &loc1, const tripoint &loc2, int t = 0, int t2 = 0 ); // sqrt(dX^2 + dY^2) -float trig_dist( int x1, int y1, int x2, int y2 ); -float trig_dist( const point &p1, int x2, int y2 ); float trig_dist( const point &loc1, const point &loc2 ); float trig_dist( const tripoint &loc1, const tripoint &loc2 ); // Roguelike distance; minimum of dX and dY -int square_dist( int x1, int y1, int x2, int y2 ); -int square_dist( const point &p1, int x2, int y2 ); int square_dist( const point &loc1, const point &loc2 ); int square_dist( const tripoint &loc1, const tripoint &loc2 ); -int rl_dist( int x1, int y1, int x2, int y2 ); -int rl_dist( const point &p1, int x2, int y2 ); -int rl_dist( const tripoint &loc1, const tripoint &loc2 ); +// Choose between the above two according to the "circular distances" option int rl_dist( const point &a, const point &b ); +int rl_dist( const tripoint &loc1, const tripoint &loc2 ); // Sum of distance in both axes int manhattan_dist( const point &loc1, const point &loc2 ); @@ -140,8 +127,6 @@ double atan2_degrees( const point & ); // Get the magnitude of the slope ranging from 0.0 to 1.0 float get_normalized_angle( const point &start, const point &end ); std::vector continue_line( const std::vector &line, int distance ); -std::vector squares_in_direction( int x1, int y1, int x2, int y2 ); -std::vector squares_in_direction( const point &p1, int x2, int y2 ); std::vector squares_in_direction( const point &p1, const point &p2 ); // Returns a vector of squares adjacent to @from that are closer to @to than @from is. // Currently limited to the same z-level as @from.