00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <nav_grid_iterators/line.h>
00036 #include <nav_grid_iterators/line/bresenham.h>
00037 #include <nav_grid_iterators/line/ray_trace.h>
00038 #include <nav_grid/coordinate_conversion.h>
00039
00040 namespace nav_grid_iterators
00041 {
00042 Line::Line(const nav_grid::NavGridInfo* info, double x0, double y0, double x1, double y1,
00043 bool include_last_index, bool bresenham)
00044 : BaseIterator(info), x0_(x0), y0_(y0), x1_(x1), y1_(y1), include_last_index_(include_last_index),
00045 bresenham_(bresenham), start_index_(0, 0), end_index_(0, 0)
00046 {
00047 constructIterator();
00048
00049
00050 signed_width_ = static_cast<int>(info->width);
00051 signed_height_ = static_cast<int>(info->height);
00052
00053
00054 nav_grid::SignedIndex end = internal_iterator_->getFinalIndex();
00055 end_index_.x = end.x;
00056 end_index_.y = end.y;
00057
00058
00059 nav_grid::SignedIndex sindex = **internal_iterator_;
00060 while (!internal_iterator_->isFinished() && !inBounds(sindex))
00061 {
00062 internal_iterator_->increment();
00063 sindex = **internal_iterator_;
00064 }
00065
00066
00067 if (internal_iterator_->isFinished())
00068 {
00069 start_index_ = end_index_;
00070 }
00071 else
00072 {
00073 start_index_.x = sindex.x;
00074 start_index_.y = sindex.y;
00075 }
00076
00077 index_ = start_index_;
00078 }
00079
00080 Line::Line(const Line& other)
00081 : Line(other.info_, other.index_, other.x0_, other.y0_, other.x1_, other.y1_, other.include_last_index_,
00082 other.bresenham_, other.start_index_, other.end_index_)
00083 {
00084 }
00085
00086 Line::Line(const nav_grid::NavGridInfo* info, const nav_grid::Index& index, double x0, double y0, double x1, double y1,
00087 bool include_last_index, bool bresenham, nav_grid::Index start_index, nav_grid::Index end_index)
00088 : BaseIterator(info, index), x0_(x0), y0_(y0), x1_(x1), y1_(y1), include_last_index_(include_last_index),
00089 bresenham_(bresenham), start_index_(start_index), end_index_(end_index)
00090 {
00091 constructIterator();
00092 signed_width_ = static_cast<int>(info->width);
00093 signed_height_ = static_cast<int>(info->height);
00094 }
00095
00096 Line& Line::operator=(const Line& other)
00097 {
00098 info_ = other.info_;
00099 index_ = other.index_;
00100 x0_ = other.x0_;
00101 y0_ = other.y0_;
00102 x1_ = other.x1_;
00103 y1_ = other.y1_;
00104 include_last_index_ = other.include_last_index_;
00105 bresenham_ = other.bresenham_;
00106 start_index_ = other.start_index_;
00107 end_index_ = other.end_index_;
00108 signed_width_ = other.signed_width_;
00109 signed_height_ = other.signed_height_;
00110 constructIterator();
00111 return *this;
00112 }
00113
00114 void Line::constructIterator()
00115 {
00116
00117 double local_x0, local_y0, local_x1, local_y1;
00118 worldToGrid(*info_, x0_, y0_, local_x0, local_y0);
00119 worldToGrid(*info_, x1_, y1_, local_x1, local_y1);
00120
00121 if (bresenham_)
00122 {
00123 internal_iterator_.reset(new Bresenham(local_x0, local_y0, local_x1, local_y1, include_last_index_));
00124 }
00125 else
00126 {
00127 internal_iterator_.reset(new RayTrace(local_x0, local_y0, local_x1, local_y1, include_last_index_));
00128 }
00129 }
00130
00131 bool Line::inBounds(const nav_grid::SignedIndex& sindex)
00132 {
00133 return sindex.x >= 0 && sindex.y >= 0 && sindex.x < signed_width_ && sindex.y < signed_height_;
00134 }
00135
00136 Line Line::begin() const
00137 {
00138 return Line(info_, start_index_, x0_, y0_, x1_, y1_, include_last_index_, bresenham_, start_index_, end_index_);
00139 }
00140
00141 Line Line::end() const
00142 {
00143 return Line(info_, end_index_, x0_, y0_, x1_, y1_, include_last_index_, bresenham_, start_index_, end_index_);
00144 }
00145
00146 void Line::increment()
00147 {
00148 internal_iterator_->increment();
00149 nav_grid::SignedIndex sindex = **internal_iterator_;
00150 if (!internal_iterator_->isFinished() && !inBounds(sindex))
00151 {
00152 index_ = end_index_;
00153 }
00154 else
00155 {
00156 index_.x = sindex.x;
00157 index_.y = sindex.y;
00158 }
00159 }
00160
00161 bool Line::fieldsEqual(const Line& other)
00162 {
00163 return x0_ == other.x0_ && y0_ == other.y0_ && x1_ == other.x1_ && y1_ == other.y1_ &&
00164 include_last_index_ == other.include_last_index_ && bresenham_ == other.bresenham_;
00165 }
00166
00167 }