File: Line_d.h

package info (click to toggle)
cgal 4.0-5
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 65,068 kB
  • sloc: cpp: 500,870; ansic: 102,544; sh: 321; python: 92; makefile: 75; xml: 2
file content (223 lines) | stat: -rw-r--r-- 7,493 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// Copyright (c) 2000,2001  
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel).  All rights reserved. 
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/next/Kernel_d/include/CGAL/Kernel_d/Line_d.h $
// $Id: Line_d.h 67093 2012-01-13 11:22:39Z lrineau $
// 
//
// Author(s)     : Michael Seel

#ifndef CGAL_LINE_D_H
#define CGAL_LINE_D_H

#include <CGAL/Kernel_d/Pair_d.h> 
#include <CGAL/Kernel_d/Segment_d.h> 
#include <CGAL/Kernel_d/Ray_d.h>
#include <CGAL/Dimension.h>

namespace CGAL {

template <class R>
std::istream& operator>>(std::istream&, Line_d<R>&);
template <class R>
std::ostream& operator<<(std::ostream&, const Line_d<R>&);

/*{\Manpage {Line_d}{R}{Lines in d-space}{l}}*/

template <class p_R>
class Line_d : public Handle_for< Pair_d<p_R> > { 
  typedef Pair_d<p_R>      Pair;
  typedef Handle_for<Pair> Base;
  typedef Line_d<p_R>      Self;

  using Base::ptr;

/*{\Mdefinition 
An instance of data type |Line_d| is an oriented line in
$d$-dimensional Euclidian space.}*/

public: 

  typedef CGAL::Dynamic_dimension_tag Ambient_dimension;
  typedef CGAL::Dimension_tag<1>      Feature_dimension;

/*{\Mtypes 5}*/
typedef p_R R;
/*{\Mtypemember the representation type.}*/
typedef typename p_R::RT RT;
/*{\Mtypemember the ring type.}*/
typedef typename p_R::FT FT;
/*{\Mtypemember the field type.}*/
typedef typename p_R::LA LA;
/*{\Mtypemember the linear algebra layer.}*/

typedef typename Vector_d<R>::Base_vector Base_vector;

friend class Ray_d<R>; 
friend class Segment_d<R>; 

private:
Line_d(const Base& b) : Base(b) {}
public: 
/*{\Mcreation 3}*/

Line_d() : Base( Pair() ) {}
/*{\Mcreate introduces a variable |\Mvar| of type |\Mname| and 
initializes it to some line in $d$ - dimensional space }*/

Line_d(const Point_d<R>& p, const Point_d<R>& q)
/*{\Mcreate introduces a line through |p| and |q| and oriented
from |p| to |q|. \precond $p$ and $q$ are distinct and have the same 
dimension.}*/
 : Base( Pair(p,q) )
{ CGAL_assertion_msg(!ptr()->is_degenerate(), 
    "Line_d::constructor: the two points must be different." );
  CGAL_assertion_msg((p.dimension()==q.dimension()), 
    "Line_d::constructor: the two points must have the same dimension." );
}

Line_d(const Point_d<R>& p, const Direction_d<R>& dir)
/*{\Mcreate introduces a line through |p| with direction |dir|.
\precond |p| and |dir| have the same dimension, |dir| is not trivial. }*/
  : Base( Pair(p,p+dir.vector()) )
{ CGAL_assertion_msg((p.dimension()==dir.dimension()), 
    "Line_d::constructor: the p and dir must have the same dimension." );
  CGAL_assertion_msg(!dir.is_degenerate(), 
    "Line_d::constructor: dir must be non-degenerate." );
}

Line_d(const Segment_d<R>& s) 
/*{\Mcreate introduces a variable |\Mvar| of type |\Mname| and 
initializes it to the line through |s.source()| and |s.target()|
with direction from |s.source()| to |s.target()|.
\precond $s$ is not degenerate. }*/
  : Base( s ) 
{ CGAL_assertion_msg((!s.is_degenerate()), 
    "Line_d::constructor: segment is trivial.");
}

Line_d(const Ray_d<R>& r) : Base(r) {}
/*{\Mcreate introduces a variable |\Mvar| of type |\Mname| and 
initializes it to the line through |r.point(1)| and |r.point(2)|. }*/

Line_d(const Line_d<R>& l) : Base(l) {}

/*{\Moperations 3 3}*/

int dimension() const { return (ptr()->_p[0].dimension()); }
/*{\Mop returns the dimension of the underlying space.}*/

Point_d<R> point(int i) const 
/*{\Mop returns an arbitrary point on |l|.  It holds that |point(i) ==
point(j)|, iff |i==j|. Furthermore, |l| is directed from |point(i)| to
|point(j)|, for all |i < j|.}*/
{ return (ptr()->_p[i%2]); }

Line_d<R> opposite() const 
/*{\Mop returns the line |(point(2),point(1))|. }*/
{ return Line_d<R>(point(1),point(0)); }

Direction_d<R> direction() const 
/*{\Mop  returns the direction of |\Mvar|. }*/
{ return ptr()->direction(); }

Line_d<R> transform(const Aff_transformation_d<R> & t) const
/*{\Mop returns $t(l)$. }*/
{ return Line_d<R>(point(0).transform(t),point(1).transform(t)); }

Line_d<R> operator+(const Vector_d<R>& v) const
/*{\Mbinop returns |\Mvar+v|, i.e., |\Mvar| translated by vector $v$.}*/ 
{ return Line_d<R>(point(0)+v,point(1)+v); }

Point_d<R> projection(const Point_d<R>& p) const
/*{\Mop returns the point of intersection of |\Mvar| with the hyperplane 
that is orthogonal to |\Mvar| through |p|. }*/
{ Vector_d<R> v = direction().vector();
  Point_d<R> q = point(0);
  FT lambda = ((p-q) * v) / (v*v);
  Point_d<R> res = q + lambda * v;
  return res;
}

bool has_on(const Point_d<R>& p) const 
/*{\Mopl returns true if $p$ lies on |\Mvar| and false otherwise. }*/
{ typename R::Position_on_line_d pos; FT dummy;
  return pos(p,point(0),point(1),dummy); }

bool operator==(const Line_d<R>& l1) const
{ if ( this->identical(l1) ) return true;
  if ( dimension() != l1.dimension() ) return false;
  return has_on(l1.point(0)) && 
         direction() == l1.direction(); 
}

bool operator!=(const Line_d<R>& l1) const
{ return !operator==(l1); }

friend std::istream& operator>> <> 
(std::istream&, Line_d<R>&);
friend std::ostream& operator<< <> 
(std::ostream&, const Line_d<R>&);

}; // end of class

/*{\Mtext \headerline{Non-Member Functions} }*/

template <class R>
bool weak_equality(const Line_d<R>& l1, const Line_d<R>& l2)
/*{\Mfunc Test for equality as unoriented lines.}*/
{ if (l1.identical(l2)) return true;
  if (l1.dimension()!=l2.dimension()) return false;
  return (l1.has_on(l2.point(0)) && 
          l1.has_on(l2.point(1))); 
}

template <class R>
bool parallel(const Line_d<R>& l1, const Line_d<R>& l2)
/*{\Mfunc returns true if |l1| and |l2| are parallel as unoriented lines
and false otherwise. }*/
{ return (l1.direction() == l2.direction() ||
          l1.direction() == -l2.direction()); }

template <class R>
std::istream& operator>>(std::istream& I, Line_d<R>& l) 
{ l.copy_on_write(); l.ptr()->read(I); 
  CGAL_assertion_msg(l.point(0)!=l.point(1),
    "Line_d::operator>>: trivial line.");
  CGAL_assertion_msg(l.point(0).dimension()==l.point(1).dimension(),
    "Line_d::operator>>: dimensions disagree.");
  return I; 
}

template <class R>
std::ostream& operator<<(std::ostream& O, const Line_d<R>& l)
{ l.ptr()->print(O,"Line_d"); return O; }

/*{\Mimplementation 
Lines are implemented by a pair of points as an item type.  All
operations like creation, initialization, tests, direction
calculation, input and output on a line $l$ take time
$O(|l.dimension()|)$. |dimension()|, coordinate and point access, and
identity test take constant time.  The operations for intersection
calculation also take time $O(|l.dimension()|)$. The space requirement
is $O(|l.dimension()|)$.}*/


} //namespace CGAL
#endif // CGAL_LINE_D_H
//----------------------- end of file ----------------------------------