Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

_QGAR_angle.TCC

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------+
00002  | Library QgarLib, graphics analysis and recognition                  |
00003  | Copyright (C) 2002  Qgar Project, LORIA                             |
00004  |                                                                     |
00005  | This library is free software; you can redistribute it and/or       |
00006  | modify it under the terms of the GNU Lesser General Public          |
00007  | License version 2.1, as published by the Free Software Foundation.  |
00008  |                                                                     |
00009  | This library is distributed in the hope that it will be useful,     |
00010  | but WITHOUT ANY WARRANTY; without even the implied warranty of      |
00011  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                |
00012  | See the GNU Lesser General Public License for more details.         |
00013  |                                                                     |
00014  | The GNU Lesser General Public License is included in the file       |
00015  | LICENSE.LGPL, in the root directory of the Qgar packaging. See      |
00016  | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. |
00017  | To receive a paper copy, write to the Free Software Foundation,     |
00018  | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.       |
00019  |                                                                     |
00020  | Contact Project Qgar for any information:                           |
00021  |   LORIA - équipe Qgar                                               |
00022  |   B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France                |
00023  |   email: qgar-contact@loria.fr                                      |
00024  |   http://www.qgar.org/                                              |
00025  *---------------------------------------------------------------------*/
00026 
00027 
00028 /**
00029  * @file   _QGAR_angle.TCC
00030  * @brief  Implementation of global utilities for primitives.
00031  *
00032  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a>
00033  * @date   February 03, 2005  18:28
00034  * @since  Qgar 2.2
00035  */
00036 
00037 
00038 
00039 // QGAR
00040 #include <qgarlib/math.H>
00041 
00042 
00043 
00044 namespace qgar
00045 {
00046 
00047 
00048 /*
00049  *   O
00050  *    +---------------> X
00051  *    |\    |
00052  *    | \ <-'
00053  *    |  \    angle (in radians unless specified)
00054  *    |   \ 
00055  *    |
00056  *    v
00057  *
00058  *    Y
00059  *
00060  * - The origin of the coordinate system is at top left corner
00061  * - Angles are clockwise from the X axis
00062  */
00063 
00064 
00065 
00066 /* -------------------------------------------------------------------
00067  * ANGLE WITH THE X AXIS AND A VECTOR
00068  * -------------------------------------------------------------------
00069  *
00070  *                                        ----->/
00071  * O                          O          /     /
00072  *  +---------------> X        +---------|-------------> X
00073  *  |    \    |                |         |   /  |
00074  *  |     \ <-' angle          |   angle \_ /__/
00075  *  |      \                   |           /
00076  *  |       + aPt1             |          + aPt2
00077  *  |        \                 |         ^
00078  *  |         \                |        /
00079  *  |          v               |       /
00080  *  v           + aPt2         v      + aPt1
00081  *
00082  *  Y                          Y
00083  *
00084  * -------------------------------------------------------------------
00085  */
00086 
00087 // IN [0, 2PI[ RADIANS
00088 
00089 template <class T>
00090 double
00091 qgAngle(const GenPoint<T>& aPt1, const GenPoint<T>& aPt2)
00092 {
00093   double angle = atan2(static_cast<double>(aPt2.y() - aPt1.y()),
00094                        static_cast<double>(aPt2.x() - aPt1.x()));
00095 
00096   return (angle < 0.) ? (Math::QG_2PI + angle) : angle;
00097 }
00098 
00099 
00100 // IN [0, 360[ DEGREES
00101 
00102 template <class T>
00103 inline double
00104 qgAngleDegrees(const GenPoint<T>& aPt1, const GenPoint<T>& aPt2)
00105 {
00106   return qgRadiansToDegrees(qgAngle(aPt1, aPt2));
00107 }
00108 
00109 
00110 /* -------------------------------------------------------------------
00111  * ANGLE BETWEEN TWO VECTORS DETERMINED BY 3 POINTS
00112  * -------------------------------------------------------------------
00113  * 0
00114  *  +---------------------> X      +---------------------> X
00115  *  |                              |    ----
00116  *  |                              |   /    \
00117  *  | aPt1                         |   |     v
00118  *  |   +--------->+ aPt2          |   |  +------->+ aPt3
00119  *  |    \    |                    |   \ __\   
00120  *  |     \ <-'                    |        \
00121  *  |      \                       |         \
00122  *  |       v                      |          v   
00123  *  |        + aPt3                |           + aPt2
00124  *  v                              v
00125  *
00126  *  Y                              Y
00127  *
00128  * -------------------------------------------------------------------
00129  */
00130 
00131 
00132 // IN [0, 2PI[ RADIANS
00133 
00134 template <class T>
00135 inline double
00136 qgAngle(const GenPoint<T>& aPt1,
00137         const GenPoint<T>& aPt2,
00138         const GenPoint<T>& aPt3)
00139 {
00140   return qgAngle(aPt1, aPt2, aPt1, aPt3);
00141 }
00142 
00143 
00144 // IN [0, 360[ DEGREES
00145 
00146 template <class T>
00147 inline double
00148 qgAngleDegrees(const GenPoint<T>& aPt1,
00149                const GenPoint<T>& aPt2,
00150                const GenPoint<T>& aPt3)
00151 {
00152   return qgRadiansToDegrees(qgAngle(aPt1, aPt2, aPt3));
00153 }
00154 
00155 
00156 /* -------------------------------------------------------------------
00157  * ANGLE BETWEEN TWO VECTORS DETERMINED BY 4 POINTS
00158  * -------------------------------------------------------------------
00159  *
00160  * 0
00161  *  +----------------------> X      +-------------------------> X
00162  *  |                               |    ----
00163  *  |                               |   /    \
00164  *  |        aPt1                   |   |     v  aPt3
00165  *  |    \----+------>+ aPt2        |   |  \-----+------>+ aPt4
00166  *  |     \     |                   |   \ __\   
00167  *  | aPt3 +    |                   |        \
00168  *  |       <--'                   |         + aPt1
00169  *  |        \                      |          \
00170  *  |         v                     |           v   
00171  *  |          + aPt4               |            + aPt2
00172  *  v                               v
00173  *
00174  *  Y                               Y
00175  *
00176  * -------------------------------------------------------------------
00177  */
00178 
00179 // IN [0, 2PI[ RADIANS
00180 
00181 template <class T>
00182 double
00183 qgAngle(const GenPoint<T>& aPt1,
00184         const GenPoint<T>& aPt2,
00185         const GenPoint<T>& aPt3,
00186         const GenPoint<T>& aPt4)
00187 {
00188   double ang12 = qgAngle(aPt1, aPt2);
00189   double ang13 = qgAngle(aPt3, aPt4);
00190 
00191   return 
00192     (ang12 > ang13)
00193     ? (ang13 - ang12 + Math::QG_2PI)
00194     : (ang13 - ang12);
00195 }
00196 
00197 
00198 // IN [0, 360[ DEGREES
00199 
00200 template <class T>
00201 inline double
00202 qgAngleDegrees(const GenPoint<T>& aPt1,
00203                const GenPoint<T>& aPt2,
00204                const GenPoint<T>& aPt3,
00205                const GenPoint<T>& aPt4)
00206 {
00207   return qgRadiansToDegrees(qgAngle(aPt1, aPt2, aPt3, aPt4));
00208 }
00209 
00210 
00211 
00212 /* -------------------------------------------------------------------
00213  * ANGLE BETWEEN THE X AXIS AND A SEGMENT
00214  * -------------------------------------------------------------------
00215  *
00216  * O                          O
00217  *  +-----------------> X      +-----------------> X
00218  *  |    \    |                |    \    |
00219  *  |     \ <-' angle          |     \ <-' angle
00220  *  |      \                   |      \
00221  *  |       + aPt1             |       + aPt2
00222  *  |        \                 |        \
00223  *  |         \                |         \
00224  *  |          \               |          \
00225  *  v           + aPt2         v           + aPt1
00226  *
00227  *  Y                          Y
00228  *
00229  * -------------------------------------------------------------------
00230  */
00231 
00232 // IN [0, 2PI[ RADIANS
00233 
00234 template <class T>
00235 double
00236 qgSlope(const GenPoint<T>& aPt1, const GenPoint<T>& aPt2)
00237 {
00238   double s = qgAngle(aPt1, aPt2);
00239 
00240   return (s >= Math::QG_PI) ? (s - Math::QG_PI) : s;
00241 }
00242 
00243 
00244 // IN [0, 360[ DEGREES
00245 
00246 template <class T>
00247 inline double
00248 qgSlopeDegrees(const GenPoint<T>& aPt1, const GenPoint<T>& aPt2)
00249 {
00250   return qgRadiansToDegrees(qgSlope(aPt1, aPt2));
00251 }
00252 
00253 
00254 // -------------------------------------------------------------------
00255 
00256 
00257 } // namespace qgar