1 /****************************************************************************
2 * VCGLib                                                            o o     *
3 * Visual and Computer Graphics Library                            o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2004-2016                                           \/)\/    *
6 * Visual Computing Lab                                            /\/|      *
7 * ISTI - Italian National Research Council                           |      *
8 *                                                                    \      *
9 * All rights reserved.                                                      *
10 *                                                                           *
11 * This program is free software; you can redistribute it and/or modify      *
12 * it under the terms of the GNU General Public License as published by      *
13 * the Free Software Foundation; either version 2 of the License, or         *
14 * (at your option) any later version.                                       *
15 *                                                                           *
16 * This program is distributed in the hope that it will be useful,           *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
20 * for more details.                                                         *
21 *                                                                           *
22 ****************************************************************************/
23 /****************************************************************************
24   History
25 
26 $Log: not supported by cvs2svn $
27 
28 ****************************************************************************/
29 
30 
31 
32 #ifndef __VCGLIB_RAY2
33 #define __VCGLIB_RAY2
34 
35 #include <vcg/space/point2.h>
36 
37 namespace vcg {
38 
39 /** \addtogroup space */
40 /*@{*/
41 /**
42 Templated class for 3D rays.
43   This is the class for infinite rays in 3D space. A Ray is stored just as two Point3:
44 	an origin and a direction (not necessarily normalized).
45 	@param RayScalarType (template parameter) Specifies the type of scalar used to represent coords.
46 	@param NORM: if on, the direction is always Normalized
47 */
48 template <class RayScalarType, bool NORM=false>
49 class Ray2
50 {
51 public:
52 
53 	/// The scalar type
54 	typedef RayScalarType ScalarType;
55 
56 	/// The point type
57 	typedef Point2<RayScalarType> PointType;
58 
59 	/// The ray type
60 	typedef Ray2<RayScalarType,NORM> RayType;
61 
62 private:
63 
64 	/// Origin
65 	PointType _ori;
66 
67 	/// Direction (not necessarily normalized, unless so specified by NORM)
68 	PointType _dir;
69 
70 public:
71 
72 //@{
73 	 /** @name Members to access the origin or direction
74 	   Direction() cannot be assigned directly.
75 		 Use SetDirection() or Set() instead.
76 	**/
77 		///
Origin()78   inline const PointType &Origin() const { return _ori; }
Origin()79   inline PointType &Origin() { return _ori; }
Direction()80   inline const PointType &Direction() const { return _dir; }
81 		/// sets the origin
SetOrigin(const PointType & ori)82 	inline void SetOrigin( const PointType & ori )
83 	{	_ori=ori; }
84 		/// sets the direction
SetDirection(const PointType & dir)85 	inline void SetDirection( const PointType & dir)
86 	{	_dir=dir; if (NORM) _dir.Normalize();  }
87 		/// sets origin and direction.
Set(const PointType & ori,const PointType & dir)88 	inline void Set( const PointType & ori, const PointType & dir )
89 	{	SetOrigin(ori); SetDirection(dir); }
90 //@}
91 
92 //@{
93 	 /** @name Constructors
94 	**/
95  		/// The empty constructor
Ray2()96 	Ray2() {};
97 		/// The (origin, direction) constructor
Ray2(const PointType & ori,const PointType & dir)98 	Ray2(const PointType &ori, const PointType &dir) {SetOrigin(ori); SetDirection(dir);};
99 //@}
100 
101 		/// Operator to compare two rays
102 	inline bool operator == ( RayType const & p ) const
103 	{	return _ori==p._ori && _dir==p._dir; }
104 		/// Operator to dispare two rays
105 	inline bool operator != ( RayType const & p ) const
106 	{	return _ori!=p._ori || _dir!=p._dir; }
107 		/// Projects a point on the ray
Projection(const PointType & p)108 	inline ScalarType Projection( const  PointType &p ) const
109 	{ if (NORM) return ScalarType((p-_ori)*_dir);
110 		else      return ScalarType((p-_ori)*_dir/_dir.SquaredNorm());
111 	}
112 	  /// returns wheter this type is normalized or not
IsNormalized()113 	static bool IsNormalized() {return NORM;};
114 	  /// calculates the point of parameter t on the ray.
P(const ScalarType t)115 	inline PointType P( const ScalarType t ) const
116 	{ return _ori + _dir * t; }
117 		/// normalizes direction field (returns a Normalized Ray)
Normalize()118 	inline Ray2<ScalarType,true> &Normalize()
119 	{ if (!NORM) _dir.Normalize(); return *((Ray2<ScalarType,true>*)this);}
120 		/// normalizes direction field (returns a Normalized Ray) - static version
Normalize(RayType & p)121 	static Ray2<ScalarType,true> &Normalize(RayType &p)
122 	{ p.Normalize(); return *((Ray2<ScalarType,true>*)(&p));}
123 	  /// importer for different ray types (with any scalar type or normalization beaviour)
124 	template <class Q, bool K>
Import(const Ray2<Q,K> & b)125 	inline void Import( const Ray2<Q,K> & b )
126 	{ _ori.Import( b.Origin() );	_dir.Import( b.Direction() );
127 	  if ((NORM) && (!K)) _dir.Normalize();
128 		//printf("(=)%c->%c ",(!NORM)?'N':'n', NORM?'N':'n');
129 	}
130 		/// constructs a new ray importing it from an existing one
131 	template <class Q, bool K>
Construct(const Ray2<Q,K> & b)132 	static RayType Construct( const Ray2<Q,K> & b )
133 	{ RayType res; res.Import(b);  return res;
134 	}
ClosestPoint(const PointType & p)135 	PointType ClosestPoint(const PointType & p) const{
136 	return P(Projection(p));
137 	}
138 	  /// flips the ray
Flip()139 	inline void Flip(){
140 		_dir=-_dir;
141 	};
142 
143 //@{
144 	 /** @name Linearity for 3d rays
145    (operators +, -, *, /) so a ray can be set as a linear combination
146 	 of several rays. Note that the result of any operation returns
147 	 a non-normalized ray; however, the command r0 = r1*a + r2*b is licit
148 	 even if r0,r1,r2 are normalized rays, as the normalization will
149 	 take place within the final assignement operation.
150 	**/
151 	inline Ray2<ScalarType,false> operator + ( RayType const & p) const
152 	{return Ray2<ScalarType,false> ( _ori+p.Origin(), _dir+p.Direction() );}
153 	inline Ray2<ScalarType,false> operator - ( RayType const & p) const
154 	{return Ray2<ScalarType,false> ( _ori-p.Origin(), _dir-p.Direction() );}
155 	inline Ray2<ScalarType,false> operator * ( const ScalarType s ) const
156 	{return Ray2<ScalarType,false> ( _ori*s, _dir*s );}
157 	inline Ray2<ScalarType,false> operator / ( const ScalarType s ) const
158 	{ScalarType s0=((ScalarType)1.0)/s; return RayType( _ori*s0, _dir*s0 );}
159 //@}
160 
161 
162 //@{
163 	 /** @name Automatic normalized to non-normalized
164 	 "Ray2dN r0 = r1" is equivalent to
165 	 "Ray2dN r0 = r1.Normalize()" if r1 is a Ray2d
166 	**/
167 		/// copy constructor that takes opposite beaviour
Ray2(const Ray2<ScalarType,!NORM> & r)168 	Ray2(const Ray2<ScalarType,!NORM > &r)
169 	{ Import(r); };
170 		/// assignment
171 	inline RayType & operator = ( Ray2<ScalarType,!NORM> const &r)
172 	{ Import(r); return *this; };
173 //@}
174 
175 }; // end class definition
176 
177 typedef Ray2<short>  Ray2s;
178 typedef Ray2<int>    Ray2i;
179 typedef Ray2<float>  Ray2f;
180 typedef Ray2<double> Ray2d;
181 
182 typedef Ray2<short ,true> Ray2sN;
183 typedef Ray2<int   ,true> Ray2iN;
184 typedef Ray2<float ,true> Ray2fN;
185 typedef Ray2<double,true> Ray2dN;
186 
187 	  /// returns closest point
188 template <class ScalarType, bool NORM>
ClosestPoint(Ray2<ScalarType,NORM> r,const Point2<ScalarType> & p)189 Point2<ScalarType> ClosestPoint( Ray2<ScalarType,NORM> r, const Point2<ScalarType> & p)
190 {
191 	ScalarType t = r.Projection(p);
192 	if (t<0) return r.Origin();
193 	return r.P(t);
194 }
195 
196 /*@}*/
197 
198 } // end namespace
199 #endif
200