/home/coin/SVN-release/OS-2.4.1/Couenne/src/branch/projections.cpp

Go to the documentation of this file.
00001 /* $Id: projections.cpp 490 2011-01-14 16:07:12Z pbelotti $
00002  *
00003  * Name:    projections.cpp
00004  * Authors: Pietro Belotti, Carnegie Mellon University
00005  * Purpose: tools for projecting points on lines/planes
00006  *
00007  * (C) Carnegie-Mellon University, 2006-10.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include "CouenneTypes.hpp"
00012 #include "CouennePrecisions.hpp"
00013 //#include "CouenneProjections.hpp"
00014 
00015 namespace Couenne {
00016 
00017 /*  compute projection of point (x0, y0) on the segment defined by
00018  *  line ax + by + c <>= 0 (sign provided by parameter sign) and
00019  *  bounds [lb, ub] on x. Return distance from segment, 0 if satisfied
00020  */
00021 
00022 CouNumber project (CouNumber a, CouNumber b, CouNumber c, 
00023                    CouNumber x0, CouNumber y0, 
00024                    CouNumber lb, CouNumber ub, int sign,
00025                    CouNumber *xp, CouNumber *yp) {
00026 
00027   /* compute projection of (x0,y0) onto line ax+by+c=0 */
00028   register CouNumber
00029     t  = - (a*x0 + b*y0 + c);
00030 
00031   /* projection coordinates */
00032   CouNumber xpr, ypr;
00033 
00034   /* does point lie on line? */
00035   if (fabs (t) < COUENNE_EPS) return 0.; 
00036 
00037   /* check if point satisfies inequality */
00038   if      (sign > 0) {if (t < 0.) return 0.;}
00039   else if (sign < 0) {if (t > 0.) return 0.;}
00040 
00041   /* t corresponding to intersection point */
00042   t /= sqrt (a*a + b*b);
00043 
00044   /* compute projection coordinates */
00045   xpr = x0 + a*t;
00046   ypr = y0 + b*t;
00047 
00048   /* don't need sign any longer, take its absolute value */
00049   if (t < 0.) t = -t;
00050 
00051   /* if projected point is outside [lb,ub], set xp to closest bound
00052      and yp accordingly, and compute distance to (x0,y0) */
00053   if ((xpr < lb) || (xpr > ub)) {
00054 
00055     if      (xpr < lb) xpr = lb; 
00056     else if (xpr > ub) xpr = ub; 
00057 
00058     ypr = (- c - a * xpr) / b - y0;
00059     xpr -= x0;
00060 
00061     t = sqrt (xpr * xpr + ypr * ypr);
00062   }
00063 
00064   /* update output parameters */
00065   if (xp) *xp = xpr;
00066   if (yp) *yp = ypr;
00067 
00068   /* return distance */
00069   return t;
00070 }
00071 
00072 
00078 CouNumber projectSeg (CouNumber x0,  CouNumber y0, 
00079                       CouNumber x1,  CouNumber y1, 
00080                       CouNumber x2,  CouNumber y2,
00081                       int sign, 
00082                       CouNumber *xp, CouNumber *yp) {
00083   CouNumber 
00084     dx = x2-x1,
00085     dy = y2-y1,
00086     a =  -dy, 
00087     b =  dx,
00088     c = x1*dy - y1*dx;
00089 
00090   return project (a, b, c, x0, y0, x1, x2, sign, xp, yp);
00091 }
00092 
00093 }
00094 
00095 /*
00096 int main (int argc, char **argv) {
00097 
00098   CouNumber 
00099     a = atof (argv [1]),
00100     b = atof (argv [2]),
00101     c = atof (argv [3]),
00102     x0 = atof (argv [4]),
00103     y0 = atof (argv [5]),
00104     lb = atof (argv [6]),
00105     ub = atof (argv [7]);
00106 
00107   int sign = atoi (argv [8]);
00108 
00109   char sig = (sign < 0) ? '<' : (sign > 0) ? '>' : ' ';
00110 
00111   printf ("projecting (%.3f,%.3f) on %.3f x + %.3f y + %.3f %c= 0, xp in [%.3f,%.3f]\n",
00112           x0, y0, a, b, c, sig, lb, ub);
00113 
00114   printf (" ==> distance is %.4f\n",
00115           project (a, b, c, x0, y0, lb, ub, sign));
00116 
00117 }
00118 */

Generated on Thu Nov 10 03:05:43 2011 by  doxygen 1.4.7