projections.cpp
Go to the documentation of this file.
1 /* $Id: projections.cpp 490 2011-01-14 16:07:12Z pbelotti $
2  *
3  * Name: projections.cpp
4  * Authors: Pietro Belotti, Carnegie Mellon University
5  * Purpose: tools for projecting points on lines/planes
6  *
7  * (C) Carnegie-Mellon University, 2006-10.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CouenneTypes.hpp"
12 #include "CouennePrecisions.hpp"
13 //#include "CouenneProjections.hpp"
14 
15 namespace Couenne {
16 
17 /* compute projection of point (x0, y0) on the segment defined by
18  * line ax + by + c <>= 0 (sign provided by parameter sign) and
19  * bounds [lb, ub] on x. Return distance from segment, 0 if satisfied
20  */
21 
23  CouNumber x0, CouNumber y0,
24  CouNumber lb, CouNumber ub, int sign,
25  CouNumber *xp, CouNumber *yp) {
26 
27  /* compute projection of (x0,y0) onto line ax+by+c=0 */
28  register CouNumber
29  t = - (a*x0 + b*y0 + c);
30 
31  /* projection coordinates */
32  CouNumber xpr, ypr;
33 
34  /* does point lie on line? */
35  if (fabs (t) < COUENNE_EPS) return 0.;
36 
37  /* check if point satisfies inequality */
38  if (sign > 0) {if (t < 0.) return 0.;}
39  else if (sign < 0) {if (t > 0.) return 0.;}
40 
41  /* t corresponding to intersection point */
42  t /= sqrt (a*a + b*b);
43 
44  /* compute projection coordinates */
45  xpr = x0 + a*t;
46  ypr = y0 + b*t;
47 
48  /* don't need sign any longer, take its absolute value */
49  if (t < 0.) t = -t;
50 
51  /* if projected point is outside [lb,ub], set xp to closest bound
52  and yp accordingly, and compute distance to (x0,y0) */
53  if ((xpr < lb) || (xpr > ub)) {
54 
55  if (xpr < lb) xpr = lb;
56  else if (xpr > ub) xpr = ub;
57 
58  ypr = (- c - a * xpr) / b - y0;
59  xpr -= x0;
60 
61  t = sqrt (xpr * xpr + ypr * ypr);
62  }
63 
64  /* update output parameters */
65  if (xp) *xp = xpr;
66  if (yp) *yp = ypr;
67 
68  /* return distance */
69  return t;
70 }
71 
72 
79  CouNumber x1, CouNumber y1,
81  int sign,
82  CouNumber *xp, CouNumber *yp) {
83  CouNumber
84  dx = x2-x1,
85  dy = y2-y1,
86  a = -dy,
87  b = dx,
88  c = x1*dy - y1*dx;
89 
90  return project (a, b, c, x0, y0, x1, x2, sign, xp, yp);
91 }
92 
93 }
94 
95 /*
96 int main (int argc, char **argv) {
97 
98  CouNumber
99  a = atof (argv [1]),
100  b = atof (argv [2]),
101  c = atof (argv [3]),
102  x0 = atof (argv [4]),
103  y0 = atof (argv [5]),
104  lb = atof (argv [6]),
105  ub = atof (argv [7]);
106 
107  int sign = atoi (argv [8]);
108 
109  char sig = (sign < 0) ? '<' : (sign > 0) ? '>' : ' ';
110 
111  printf ("projecting (%.3f,%.3f) on %.3f x + %.3f y + %.3f %c= 0, xp in [%.3f,%.3f]\n",
112  x0, y0, a, b, c, sig, lb, ub);
113 
114  printf (" ==> distance is %.4f\n",
115  project (a, b, c, x0, y0, lb, ub, sign));
116 
117 }
118 */
ULong x2
Definition: OSdtoa.cpp:1776
void fint fint fint real * a
ULong * x0
Definition: OSdtoa.cpp:1776
ULong x1
Definition: OSdtoa.cpp:1776
CouNumber project(CouNumber a, CouNumber b, CouNumber c, CouNumber x0, CouNumber y0, CouNumber lb, CouNumber ub, int sign, CouNumber *xp=NULL, CouNumber *yp=NULL)
Compute projection of point (x0, y0) on the segment defined by line ax + by + c &lt;&gt;= 0 (sign provided ...
Definition: projections.cpp:22
#define COUENNE_EPS
CouNumber projectSeg(CouNumber x0, CouNumber y0, CouNumber x1, CouNumber y1, CouNumber x2, CouNumber y2, int sign, CouNumber *xp=NULL, CouNumber *yp=NULL)
Compute projection of point (x0, y0) on the segment defined by two points (x1,y1), (x2, y2) – sign provided by parameter sign.
Definition: projections.cpp:78
double CouNumber
main number type in Couenne
static char * t
Definition: OSdtoa.cpp:3645
return b
Definition: OSdtoa.cpp:1719
real c