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

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

Generated on Thu Aug 5 03:02:56 2010 by  doxygen 1.4.7