25 #define _USE_MATH_DEFINES
31 #include <unordered_map>
36 #include <boost/asio/thread_pool.hpp>
37 #include <boost/asio/post.hpp>
38 #include <boost/lockfree/queue.hpp>
40 #include "WAngleHelper.h"
67 typedef boost::lockfree::queue< SaptData*, boost::lockfree::fixed_sized< false > > lfr_queue;
77 double num = a.x() * b.x() + a.y() * b.y() + a.z() * b.z();
78 double denom = ( a.x() * a.x() + a.y() * a.y() + a.z() * a.z() ) *
79 ( b.x() * b.x() + b.y() * b.y() + b.z() * b.z() );
80 denom = sqrt( denom );
81 double angle = acos( num / denom ) * 180.0 / M_PI;
91 if( positions.empty() )
93 return std::make_pair( prevMap, postMap );
96 std::sort( positions.begin(), positions.end(), compareWPosition );
97 std::vector< WPosition > oldPoints;
98 std::vector< WPosition > currentPoints;
99 double currentZ = positions.at( 0 ).z();
103 for(
size_t idx = 0; idx < positions.size(); idx++ )
106 if( point.z() - currentZ > 4.0 )
108 currentZ = point.z();
110 oldPoints.insert( oldPoints.end(), currentPoints.begin(), currentPoints.end() );
111 currentPoints.clear();
115 for(
size_t j = 0; j < oldPoints.size(); j++ )
120 double angleX = -atan2( point.x() - p.x(), point.y() - p.y() ) / M_PI * 180.0 + 180.0;
121 double angleY = asin( ( point.z() - p.z() ) / distance( p, point ) ) / M_PI * 180.0;
125 postMap[p][point] = angle;
127 prevMap[point] = prevM;
129 currentPoints.push_back( point );
132 return std::make_pair( prevMap, postMap );
137 std::vector< WPosition > Q;
141 for(
size_t idx = 0; idx < points.size(); idx++ )
144 dist[p] = std::numeric_limits< double >::infinity();
149 while( Q.size() > 0 )
152 auto min = std::min_element( Q.begin(), Q.end(),
155 return dist.at( a ) < dist.at( b );
161 if( dist[u] == std::numeric_limits< double >::infinity() )
169 for(
auto it = postM.begin(); it != postM.end(); it++ )
172 auto pr = prev.find( u );
173 auto old = pr == prev.end() ? prevM.end() : prevM.find( pr->second );
177 if( old != prevM.end() )
179 WPosition angles = it->second - old->second;
180 alt = dist[u] + abs( angles.x() ) + abs( angles.y() );
190 return std::make_pair( prev, dist );
199 std::shared_ptr< lfr_queue > data = std::shared_ptr< lfr_queue >(
new lfr_queue( 0 ) );
201 double firstZ = positions.at( 0 ).z();
202 double lastZ = positions.at( positions.size() - 1 ).z();
203 auto points = positions.begin();
206 boost::asio::thread_pool pool( std::thread::hardware_concurrency() );
207 while( points->z() == firstZ )
210 boost::asio::post( pool, [lines, positions, start, lastZ, data]()
212 DJOut res = dijkstra( lines, positions, start );
213 double endDis = std::numeric_limits< double >::infinity();
216 auto end = positions.end();
218 while( end->z() == lastZ )
220 if( res.second[ *end ] < endDis )
222 endDis = res.second[ *end ];
228 data->push(
new SaptData( res.first, endPoint, endDis ) );
238 double eDis = std::numeric_limits< double >::infinity();
242 while( data->pop( d ) )
253 std::vector< WPosition > S;
257 S.insert( S.begin(), u );
258 auto it = prevs.find( u );
259 if( it == prevs.end() )
271 if( positions.empty() )
273 return std::vector< WPosition >();
275 std::sort( positions.begin(), positions.end(), compareWPosition );
282 std::vector< WPosition > pos;
283 auto posIter = positions.begin();
284 auto fibIter = fiber.begin();
287 while( posIter < positions.end() )
289 if( fibIter >= fiber.end() || posIter->z() < fibIter->z() )
291 pos.push_back( *posIter );
294 else if( posIter->z() == fibIter->z() )
300 pos.push_back( *fibIter );
305 while( fibIter < fiber.end() )
307 pos.push_back( *fibIter );
313 return std::vector< WPosition >();
std::vector< osg::Vec3 > PCFiber
Vector of 3D vectors, representing points.
This only is a 3d double vector.
std::unordered_map< WPosition, double, HashFn > PositionDoubleMap
An unordered map from WPosition to double.
std::vector< WPosition > findSmoothestPath(std::vector< WPosition > positions)
Determines the path with the smallest angle change.
std::unordered_map< WPosition, PositionMap, HashFn > PositionLineMap
An unordered map from WPosition to a PositionDoubleMap.
std::pair< WAngleHelper::PositionLineMap, WAngleHelper::PositionLineMap > DJLinePair
The output of the createLine function.
std::pair< PositionMap, PositionDoubleMap > DJOut
The output of the dijkstra algorithm.
double calculateAngle(WPosition a, WPosition b)
Calculates the angle between two positions.
std::unordered_map< WPosition, WPosition, HashFn > PositionMap
An unordered map from WPosition to WPosition.
Data for the thread handling.
WPosition endPoint
The endpoint.
SaptData(WAngleHelper::PositionMap prevs, WPosition endPoint, double distance)
Creates the sapt data.
double distance
The distance to the endpoint.
WAngleHelper::PositionMap prevs
The unordered_map of previous points.