00001
00002 #include <vifa/vifa_line_cover.h>
00003
00004
00005 #include <vcl_algorithm.h>
00006
00007
00008
00009
00010
00011 vifa_line_cover::
00012 vifa_line_cover()
00013 {
00014 line_ = NULL;
00015 index_ = NULL;
00016 max_extent_ = NULL;
00017 min_extent_ = NULL;
00018 dim_ =0;
00019 }
00020
00021 vifa_line_cover::
00022 vifa_line_cover(imp_line_sptr prototype_line,
00023 int indexdimension)
00024 {
00025 line_ = prototype_line;
00026 dim_ = indexdimension;
00027 index_ = new int[dim_];
00028 max_extent_ = new double[dim_];
00029 min_extent_ = new double[dim_];
00030 for (int i = 0; i < dim_; i++)
00031 {
00032 index_[i] = 0;
00033 max_extent_[i] = -1E6;
00034 min_extent_[i] = 1E6;
00035 }
00036 }
00037
00038
00039
00040 vifa_line_cover::
00041 ~vifa_line_cover()
00042 {
00043 delete [] index_;
00044 delete [] max_extent_;
00045 delete [] min_extent_;
00046 }
00047
00048
00049
00050 void vifa_line_cover::
00051 InsertLine(imp_line_sptr l)
00052 {
00053 int rdim1 = dim_ - 1;
00054
00055
00056
00057 vgl_point_2d<double> sp;
00058 vgl_point_2d<double> ep;
00059 sp = l->point1();
00060 ep = l->point2();
00061 double ts = line_->find_t(sp);
00062 double te = line_->find_t(ep);
00063
00064
00065 int ist;
00066 int iend;
00067 if (ts < te)
00068 {
00069 if (ts < 0)
00070 ts = 0;
00071 if (te > 1.0)
00072 te = 1.0;
00073
00074 ist = (int)(rdim1 * ts);
00075 iend = (int)(rdim1 * te);
00076 }
00077 else
00078 {
00079 if (te < 0)
00080 te = 0;
00081 if (ts > 1.0)
00082 ts = 1.0;
00083
00084 ist = (int)(rdim1 * te);
00085 iend = (int)(rdim1 * ts);
00086 }
00087
00088
00089 for (int i = ist; i <= iend; i++)
00090 {
00091 index_[i]++;
00092 double t = (double)i / (double)rdim1;
00093 vgl_point_2d<double> pos = line_->find_at_t(t);
00094
00095 vgl_point_2d<double> p = l->project_2d_pt(pos);
00096 double d = this->get_signed_distance(p);
00097
00098 min_extent_[i] = vcl_min(min_extent_[i], d);
00099 max_extent_[i] = vcl_max(max_extent_[i], d);
00100 }
00101 }
00102
00103
00104
00105
00106
00107 double vifa_line_cover::
00108 GetCoverage()
00109 {
00110 int sum = 0;
00111 for (int i = 0; i < dim_; i++)
00112 {
00113 int nlines = index_[i];
00114 if (nlines > 1)
00115 sum += (nlines - 1);
00116 }
00117
00118 return (double)sum / dim_;
00119 }
00120
00121
00122
00123
00124 double vifa_line_cover::
00125 GetDenseCoverage()
00126 {
00127 double cov = this->GetCoverage();
00128 double cover_extent = double(this->get_index_max() - this->get_index_min());
00129 if (cover_extent <= 0)
00130 return 0.0;
00131 else
00132 return (dim_ * cov) / cover_extent;
00133 }
00134
00135
00136
00137
00138
00139 double vifa_line_cover::
00140 GetCustomCoverage(const double norm)
00141 {
00142 double total_cover = this->GetCoverage() * dim_;
00143 if (norm <= 0)
00144 return 0.0;
00145 else
00146 return total_cover / norm;
00147 }
00148
00149
00150 void vifa_line_cover::
00151 GetExtent(imp_line_sptr& lmin,
00152 imp_line_sptr& lmax)
00153 {
00154 if (!line_)
00155 {
00156 lmin = NULL;
00157 lmax = NULL;
00158 return;
00159 }
00160
00161 int st = get_index_min();
00162 int en = get_index_max();
00163 double min_ex = 1E6;
00164 double max_ex = -1E6;
00165
00166
00167 for (int i = st; i <= en; i++)
00168 {
00169 min_ex = vcl_min(min_extent_[i], min_ex);
00170 max_ex = vcl_max(max_extent_[i], max_ex);
00171 }
00172
00173
00174 lmin = get_offset_line(st, en, min_ex);
00175 lmax = get_offset_line(st, en, max_ex);
00176 }
00177
00178 int vifa_line_cover::
00179 get_index_min()
00180 {
00181 for (int i = 1; (i < dim_); i++)
00182 {
00183 if (index_[i] > 1)
00184 return i;
00185 }
00186
00187 return 0;
00188 }
00189
00190 int vifa_line_cover::
00191 get_index_max()
00192 {
00193 for (int i = dim_ - 1; i > 0; --i)
00194 {
00195 if (index_[i] > 1)
00196 return i;
00197 }
00198 return 0;
00199 }
00200
00201
00202 double vifa_line_cover::
00203 get_signed_distance(vgl_point_2d<double> const & p)
00204 {
00205 double a = line_->a(), b = line_->b(), c = line_->c();
00206 double d = a * p.x() + b * p.y() + c;
00207 return d;
00208 }
00209
00210
00211
00212 imp_line_sptr vifa_line_cover::
00213 get_offset_line(int start,
00214 int end,
00215 double d)
00216 {
00217
00218 vgl_vector_2d<double> n = line_->normal();
00219
00220
00221 double ts = (double)start / double(dim_ - 1);
00222 vgl_point_2d<double> ps = line_->find_at_t(ts);
00223 double te = (double)end / double(dim_ - 1);
00224 vgl_point_2d<double> pe = line_->find_at_t(te);
00225
00226 n *= d;
00227 ps += n;
00228 pe += n;
00229 imp_line_sptr il = new imp_line(ps, pe);
00230 return il;
00231 }