KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
collinear_segment_chain.h
Go to the documentation of this file.
1 /* $Id */
2 
3 /* =========================================================================== *
4 |
5 | Copyright (c) 1994-2008 by Kobus Barnard (author).
6 |
7 | Personal and educational use of this code is granted, provided that this
8 | header is kept intact, and that the authorship is not misrepresented, that
9 | its use is acknowledged in publications, and relevant papers are cited.
10 |
11 | For other use contact the author (kobus AT cs DOT arizona DOT edu).
12 |
13 | Please note that the code in this file has not necessarily been adequately
14 | tested. Naturally, there is no guarantee of performance, support, or fitness
15 | for any particular task. Nonetheless, I am interested in hearing about
16 | problems that you encounter.
17 |
18 | Author: Jinyan Guan, Ernesto Brau
19 * =========================================================================== */
20 
21 #ifndef COLLINEAR_SEGMENT_CHAIN_H_INCLUDED
22 #define COLLINEAR_SEGMENT_CHAIN_H_INCLUDED
23 
24 #include <l_cpp/l_exception.h>
25 #include <edge_cpp/line_segment.h>
26 #include <algorithm>
27 
28 namespace kjb {
29 
37 {
38 public:
39 
44  (
45  const std::vector<Line_segment>& segments
46  );
47 
53  Line_segment(csc), m_segments(csc.m_segments)
54  {}
55 
61  {
62  if(&csc != this)
63  {
65  m_segments = csc.m_segments;
66  }
67  return (*this);
68  }
69 
74 
78  const std::vector<Line_segment>& get_segments() const
79  {
80  return m_segments;
81  }
82 
86  void read(std::istream& in);
87 
91  void write(std::ostream& out) const;
92 
93 private:
94 
98  class Compare_starting_point
99  {
100  public:
101  Compare_starting_point(double orientation)
102  : m_orientation(orientation)
103  {}
104 
105  bool operator()
106  (
107  const Line_segment& s1,
108  const Line_segment& s2
109  ) const
110  {
111  if(m_orientation < M_PI_4 || m_orientation > M_PI_4*3)
112  {
113  return (s1.get_start_x() < s2.get_start_x());
114  }
115 
116  // else
117  return (s1.get_start_y() < s2.get_start_y());
118  }
119  private:
120  double m_orientation;
121  };
122 
126  std::vector<Line_segment> m_segments;
127 };
128 
132 template<class InputIterator>
133 std::vector<Collinear_segment_chain> find_collinear_segment_chains
134 (
135  InputIterator first,
136  InputIterator last,
137  double distance_threshold,
138  double orientation_threshold
139 )
140 {
141  typedef std::vector<Line_segment> Segment_vector;
142 
143  std::vector<Segment_vector> candidates(1, Segment_vector(1, *first));
144 
145  for(InputIterator it = first; it != last; it++)
146  {
147  const Line_segment& seg = *it;
148  bool found = false;
149 
150  //Check whether seg belongs to one of the candidates
151  for(unsigned int j = 0; j < candidates.size(); j++)
152  {
153  //Edge_segment_set segments = candidates[j];
154  Segment_vector chains = candidates[j];
155  for(unsigned int k = 0; k < chains.size(); k++)
156  {
157  const Line_segment& seg_to_compare = chains[k];
158  bool is_collinear = false;
159  if(fabs(seg.get_orientation() - seg_to_compare.get_orientation())
160  < orientation_threshold)
161  {
162  const Vector& center = seg.get_centre();
163  Line line2(seg_to_compare.get_start(), seg_to_compare.get_end());
164  double dist = line2.find_distance_to_point(center);
165  if(dist < distance_threshold)
166  {
167  is_collinear = true;
168  }
169  }
170  if(!found && is_collinear)
171  {
172  Vector seg_center = seg.get_centre();
173  Vector center = seg_to_compare.get_centre();
174  {
175  candidates[j].push_back(seg);
176  found = true;
177  break;
178  }
179  }
180  }
181  }
182 
183  if(!found)
184  {
185  candidates.push_back(Segment_vector(1, seg));
186  }
187  }
188 
189  // Construct the collinear line segments from the candindates
190  std::vector<Collinear_segment_chain> chains(candidates.begin(), candidates.end());
191  //std::copy(candidates.begin(), candidates.end(), chains.begin());
192 
193  return chains;
194 }
195 
196 } //namespace kjb
197 
198 #endif /*COLLINEAR_SEGMENT_CHAIN */
199 
Line_segment & operator=(const Line_segment &ls)
Assignment operator.
Definition: gr_line_segment.cpp:115
const std::vector< Line_segment > & get_segments() const
Returns underlying vector of Line_segment's.
Definition: collinear_segment_chain.h:78
Represent a collinear line segment, a collinear line segment is inherited from an Line_segment...
Definition: collinear_segment_chain.h:36
for k
Definition: APPgetLargeConnectedEdges.m:61
void push_back(Value_type x)
inserts an element at the back of the vector in amortized constant time.
Definition: m_vector.h:1128
double orientation
Orientation of this line segment, defined as the angle between the x axis and the segment...
Definition: gr_line_segment.h:428
const kjb::Vector & get_centre() const
Returns the mid-point.
Definition: gr_line_segment.h:150
This class implements vectors, in the linear-algebra sense, with real-valued elements.
Definition: m_vector.h:87
void read(std::istream &in)
Reads this Collinear_segment_chain from an input stream.
Definition: collinear_segment_chain.cpp:110
double get_orientation() const
Returns the orientation.
Definition: gr_line_segment.h:235
double dist(const pt a, const pt b)
compute approx. Great Circle distance between two UTM points
Definition: layer.cpp:45
Collinear_segment_chain(const Collinear_segment_chain &csc)
Copy Constructor constructrs a new Collinear_segment_chain from an existing Collinear_segment_chain.
Definition: collinear_segment_chain.h:52
void write(std::ostream &out) const
Writes this Collinear_segment_chain to an output stream.
Definition: collinear_segment_chain.cpp:140
Parametric representation of a 2D line in terms of three parameters (a,b,c) (as in ax+by+c = 0)...
Definition: g_line.h:30
Collinear_segment_chain & operator=(const Collinear_segment_chain &csc)
Assignment operator Assigns a Collinear_segment_chain to another Collinear_segment_chain.
Definition: collinear_segment_chain.h:60
std::vector< Collinear_segment_chain > find_collinear_segment_chains(InputIterator first, InputIterator last, double distance_threshold, double orientation_threshold)
Find a set of collinear_segments_chains.
Definition: collinear_segment_chain.h:134
const kjb::Vector & get_end() const
Returns the rightmost point of the segment.
Definition: gr_line_segment.h:180
~Collinear_segment_chain()
Nothing.
Definition: collinear_segment_chain.h:73
const kjb::Vector & get_start() const
Returns the leftmost point of the segment.
Definition: gr_line_segment.h:165
Collinear_segment_chain(const std::vector< Line_segment > &segments)
Constructs a new Collinear_segment_chain.
Definition: collinear_segment_chain.cpp:48
Line_segment()
Constructor without initializations.
Definition: gr_line_segment.h:67
Support for error handling exception classes in libKJB.
Class to manipulate a line segment The class is parametrized in terms the position of the centre...
Definition: gr_line_segment.h:62