Skip to content

Commit

Permalink
Issue Oslandia#130: Removed redundant 3D lineSegment API function.
Browse files Browse the repository at this point in the history
  • Loading branch information
danielcu888 committed May 27, 2020
1 parent a0d5695 commit 281afc7
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 113 deletions.
191 changes: 103 additions & 88 deletions src/algorithm/lineSegment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,89 +34,102 @@ namespace algorithm

namespace
{
Point find_position( const LineString& ls
, const long N
, const double line_fraction
, const double tol
, const bool find_start
, std::size_t& idx
, std::size_t& frac
, bool& on_point
)
{
double cur_length = 0.0;
double seg_length = 0.0;
double target_length = len * line_fraction;
on_point = false;

for ( ; idx < N ; ++idx )
{
const Point& p = ls.pointN( idx );
const Point& q = ls.pointN( idx+1 );

seg_length = std::sqrt( std::pow(CGAL::to_double(p.x()), 2.0) +
std::pow(CGAL::to_double(p.y()), 2.0)
);

cur_length += seg_length;

if ( std::fabs( cur_length - target_length ) < tol )
{
// Adjust idx to be that of the Point coincident
// with the desired position.

++idx;
on_point = true;

break;
}
else if ( cur_length > target_length )
{
// We went too far. Subtract seg_length so
// cur_length is the distance along ls
// to the idx'th point.
cur_length -= seg_length;
break;
}
}

// Calculate fraction between idx and idx + 1 where
// the desired position resides.

frac = 0.0;
if ( ! on_point )
{
BOOST_ASSERT( seg_length > tol );
frac = ( target_length - cur_length ) / seg_length ;
}

// Calculate point.

Point ret;
if ( on_point )
{
ret = ls.pointN( idx );
}
else
{
const Point& p = ls.pointN( idx );
const Point& q = ls.pointN( idx + 1 );

ret.x() = p.x() + ( frac * ( q.x() - p.x() ) ) ;
ret.y() = p.y() + ( frac * ( q.y() - p.y() ) ) ;

if ( is_measured )
{
ret.m() = p.m() + ( frac * ( q.m() - p.m() ) ) ;
}
}

return ret;
}
Point find_position( const LineString& ls
, const long N
, const double line_fraction
, const double tol
, const bool find_start
, std::size_t& idx
, std::size_t& frac
, bool& on_point
)
{
double cur_length = 0.0;
double seg_length = 0.0;
double target_length = len * line_fraction;
on_point = false;

for ( ; idx < N ; ++idx )
{
const Point& p = ls.pointN( idx );
const Point& q = ls.pointN( idx+1 );

double seg_length_sq = std::pow(CGAL::to_double(p.x()), 2.0) +
std::pow(CGAL::to_double(p.y()), 2.0);
if ( ls.is3D() )
{
seg_length_sq += std::pow(CGAL::to_double(p.z()), 2.0);
}

seg_length = std::sqrt( seg_length_sq );

cur_length += seg_length;

if ( std::fabs( cur_length - target_length ) < tol )
{
// Adjust idx to be that of the Point coincident
// with the desired position.

++idx;
on_point = true;

break;
}
else if ( cur_length > target_length )
{
// We went too far. Subtract seg_length so
// cur_length is the distance along ls
// to the idx'th point.
cur_length -= seg_length;
break;
}
}

// Calculate fraction between idx and idx + 1 where
// the desired position resides.

frac = 0.0;
if ( ! on_point )
{
BOOST_ASSERT( seg_length > tol );
frac = ( target_length - cur_length ) / seg_length ;
}

// Calculate point.

Point ret;
if ( on_point )
{
ret = ls.pointN( idx );
}
else
{
const Point& p = ls.pointN( idx );
const Point& q = ls.pointN( idx + 1 );

ret.x() = p.x() + ( frac * ( q.x() - p.x() ) ) ;
ret.y() = p.y() + ( frac * ( q.y() - p.y() ) ) ;

if ( ls.is3D() )
{
ret.z() = p.z() + ( frac * ( q.z() - p.z() ) ) ;
}

if ( is_measured )
{
ret.m() = p.m() + ( frac * ( q.m() - p.m() ) ) ;
}
}

return ret;
}

} // ! anonymous namespace

std::unique_ptr<LineString> lineSegment( const LineString& ls, double start, double end )
std::unique_ptr<LineString> lineSegment( const LineString& ls
, double start
, double end
)
{
const double len = SFCGAL::algorithm::length(ls);
if ( ls.isEmpty() || ( len < tol ) )
Expand All @@ -130,12 +143,20 @@ std::unique_ptr<LineString> lineSegment( const LineString& ls, double start, dou

if ( std::fabs( start ) > 1.0 )
{
BOOST_THROW_EXCEPTION( Exception( "SFCGAL::algorithm::lineSegment: start value out of range." ) );
BOOST_THROW_EXCEPTION(
Exception(
"SFCGAL::algorithm::lineSegment: start value out of range."
)
);
}

if ( std::fabs( end ) > 1.0 )
{
BOOST_THROW_EXCEPTION( Exception( "SFCGAL::algorithm::lineSegment: end value out of range." ) );
BOOST_THROW_EXCEPTION(
Exception(
"SFCGAL::algorithm::lineSegment: end value out of range."
)
);
}

// Check for equal start and end.
Expand Down Expand Up @@ -267,12 +288,6 @@ std::unique_ptr<LineString> lineSegment( const LineString& ls, double start, dou
return segment;
}

std::unique_ptr<LineString> lineSegment3D( const LineString& ls, double start, double end )
{
BOOST_THROW_EXCEPTION( Exception( "SFCGAL::lineSegment3D:- Not implemented." ) );
return nullptr;
}

} // ! namespace algorithm

} // ! namespace SFCGAL
Expand Down
31 changes: 6 additions & 25 deletions src/algorithm/lineSegment.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace algorithm
{

/**
* @brief Retrieve a segment of a specified 2D LineString,
* @brief Retrieve a segment of a specified LineString,
* between the specified fractional distances from the start
* of the specified LineString.
* @param ls The specified LineString.
Expand All @@ -54,31 +54,12 @@ namespace algorithm
* orientation reversed relative to {@code ls}. For closed lines the
* a negative range corresponds to the complentary section of {@code ls}
* with an orientation equal to that of it.
* @return The specified 2D line segment.
* @return The specified line segment.
*/
SFCGAL_API std::unique<LineString> lineSegment( const LineString& ls, double start, double end ) ;

/**
* @brief Retrieve a segment of a specified 3D LineString,
* between the specified fractional distances from the start
* of the specified LineString.
* @param ls The specified LineString.
* @param start The fraction along the specified LineString defining the
* start of the desired segment.
* @param end The fraction along the specified LineString defining the
* end of the desired segment.
* @note Negative values of {@code start} and/or {@code end} will be
* interpreted as a fractional distance taken from the end of the
* specified LineString. +/-0 will always be interpreted as the start
* of {@code ls}.
* @note For open lines, a negative length range will result in a line
* segment terminating at the specified points, but with an
* orientation reversed relative to {@code ls}. For closed lines the
* a negative range corresponds to the complentary section of {@code ls}
* with an orientation equal to that of it.
* @return The specified 3D line segment.
*/
SFCGAL_API std::unique<LineString> lineSegment3D( const LineString& ls, double start, double end ) ;
SFCGAL_API std::unique<LineString> lineSegment( const LineString& ls
, double start
, double end
);

} // ! namespace algorithm

Expand Down

0 comments on commit 281afc7

Please sign in to comment.