ACT-CV - Machine Vision for Cognitive Modeling
linien.h
Go to the documentation of this file.
1 // -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; coding: iso-8859-1; -*-
2 
3 /*
4 ACT-CV - Machine Vision for Cognitive Modeling
5 Copyright (c) 2008 Marc Halbruegge
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 
28 #ifndef __LINIEN_H
29 #define __LINIEN_H
30 
31 #include <iostream>
32 #include <cmath>
33 #include <garbagecoll.h>
34 #include <stdexcept>
35 #include <Pos.h>
36 
37 #include "punkt.h"
38 
39 
42 class PolLinie : virtual public ReferenceCount {
43 protected:
44  //Polardarstellung
45  double winkel, polAbs;
46 public:
47  PolLinie(double w=0, double p=0) :
48  winkel(w), polAbs(p) {}
49 
51  double GetWinkel() const {
52  return winkel;
53  }
54 
56  double GetPolAbs() const {
57  return polAbs;
58  }
59 
61  template<class _point>
62  double abstand(const _point &p) const {
63  return fabs(wert(p));
64  }
65 
67  template<class _point>
68  double wert(const _point &p) const {
69  return cos(GetWinkel())*p.x+sin(GetWinkel())*p.y+GetPolAbs();
70  }
71 
72  double wert(const Pos<2,double> &p) const {
73  return cos(GetWinkel())*p[0]+sin(GetWinkel())*p[1]+GetPolAbs();
74  }
75 
76  double wert(const DMatrix<2,1> &p) const {
77  return cos(GetWinkel())*p[0][0]+sin(GetWinkel())*p[1][0]+GetPolAbs();
78  }
79 
80  Pos<2,double> SchnittPunkt(const PolLinie &l2) const {
81  if (fabs(GetWinkel()-l2.GetWinkel())<1e-8) {
82  // parallel
83  throw std::runtime_error("parallel lines");
84  }
85 
86  double y=cos(l2.GetWinkel())/cos(GetWinkel())*GetPolAbs()-l2.GetPolAbs();
87  y/=sin(l2.GetWinkel())-sin(GetWinkel())*cos(l2.GetWinkel())/cos(GetWinkel());
88 
89  double x=-y*sin(GetWinkel())-GetPolAbs();
90  x/=cos(GetWinkel());
91 
92  Pos<2,double> result;
93  result[0]=x;
94  result[1]=y;
95  return result;
96  }
97 };
98 
100 double GetWinkelDiff(double w1, double w2);
101 
104 class Linie : public PolLinie {
105 protected:
106  //Ecken
108 
111 #if 0
112  if (rechts>links) {
113  double yDelta = oben - unten;
114  winkel=acos(yDelta/GetLen());
115  } else {
116  double yDelta = unten - oben;
117  winkel=acos(yDelta/GetLen());
118  }
119 #else
120  winkel=atan2(rechts-links,oben-unten);
121 #endif
122  polAbs = - links*cos(winkel) - oben*sin(winkel);
123  }
124 public:
125  Linie(double l=0, double o=0, double r=0, double u=0) :
126  oben(o), links(l), unten(u), rechts(r) {
128  }
129 
130  template<class _point1, class _point2>
131  Linie(const _point1 &p1, const _point2 &p2) :
132  oben(p1.y), links(p1.x), unten(p2.y), rechts(p2.x) {
134  }
135 
136  template<class _t>
137  Linie(const Pos<2,_t> &p1, const Pos<2,_t> &p2) :
138  oben(p1[1]), links(p1[0]), unten(p2[1]), rechts(p2[0]) {
140  }
141 
142  Linie(const DMatrix<2,1> &p1, const DMatrix<2,1> &p2) :
143  oben(p1[1][0]), links(p1[0][0]), unten(p2[1][0]), rechts(p2[0][0]) {
145  }
146 
148  double GetLen() const {
149  double res = (rechts-links)*(rechts-links) +
150  (oben-unten)*(oben-unten);
151  return sqrt(res);
152  }
153 
154  double GetOben() const {
155  return oben;
156  }
157  double GetLinks() const {
158  return links;
159  }
160  double GetUnten() const {
161  return unten;
162  }
163  double GetRechts() const {
164  return rechts;
165  }
166 
168  double abstand(const Linie &l) const {
169 #if 0
170  //erstmal nur die Winkel betrachten
171  double res = GetWinkel();
172  res -= l.GetWinkel();
173  res = fabs(res);
174  if (res > _PI / 2) res -= _PI / 2;
175  return res;
176 #else
177  /* andere Variante:
178  * den Abstand der beiden Eckpunkte einer
179  * Linie von der anderen berechnen, dann
180  * den groesseren davon ausgeben
181  */
182  double a1 = PolLinie::abstand(Punkt((int)l.GetLinks(),(int)l.GetOben()));
183  double a2 = PolLinie::abstand(Punkt((int)l.GetRechts(),(int)l.GetUnten()));
184  return a1 > a2 ? a1 : a2;
185 #endif
186  }
187 
189  double abstand(const PolLinie &l) const {
190  double a1 = l.abstand(Punkt((int)GetLinks(),(int)GetOben()));
191  double a2 = l.abstand(Punkt((int)GetRechts(),(int)GetUnten()));
192  return a1 > a2 ? a1 : a2;
193  }
194 
199  template<class _point>
200  double abstand(const _point p) const {
201  return PolLinie::abstand<_point>(p);
202  }
203 
205  Pos<2,double> result=SchnittPunkt(l2);
208 
209  double s=Len(lo-ru);
210  double slo=Len(lo-result);
211  double sru=Len(ru-result);
212  if (slo>s || sru>s) {
213  // außerhalb der Strecke
214  if (slo<sru) {
215  return lo;
216  } else {
217  return ru;
218  }
219  }
220  return result;
221  }
222 
223  bool IstAufStrecke(const Pos<2,double> &p) const {
224  return IstAufStrecke(DMatrix<2,1>(p));
225  }
226  bool IstAufStrecke(const DMatrix<2,1> &p) const {
227  DMatrix<2,1> lo(links,oben);
229 
230  double s=Len(lo-ru);
231  double slo=Len(lo-p);
232  double sru=Len(ru-p);
233  if (slo>s || sru>s) {
234  return false;
235  } else {
236  return true;
237  }
238  }
239 };
240 
241 static std::ostream& operator << (std::ostream &o, const Linie &l);
242 
243 #endif


ACT-CV - Machine Vision for Cognitive Modeling
© 2015 Marc Halbruegge (actcvlibrary@googlemail.com)