urgIntersection.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "urgIntersection.h"
00010
00011 using namespace VXV;
00012
00013 static const double ERROR_VALUE = 10.0;
00014
00015 typedef CoordinateCtrl::polygon_t crd_polygon_t;
00016
00022 typedef struct {
00023 double a;
00024 double b;
00025 double c;
00026 } lineParam_t;
00027
00028
00029
00030 static void createLine(lineParam_t *line,
00031 const Grid& p0, const Grid& p1) {
00032 line->a = p1.y - p0.y;
00033 line->b = p0.x - p1.x;
00034 line->c = -line->a * p0.x - line->b * p0.y;
00035 }
00036
00037
00038
00039 static bool onLine(const Grid& p0, const Grid& p1, double x, double y) {
00040 double large[2] = { p0.x, p0.y };
00041 double small[2] = { p1.x, p1.y };
00042 double value[2] = { x, y };
00043
00044 for (int i = 0; i <= 1; ++i) {
00045 if (large[i] < small[i]) {
00046 double tmp = large[i];
00047 large[i] = small[i];
00048 small[i] = tmp;
00049 }
00050 if ((value[i] < small[i]) || (value[i] > large[i])) {
00051 return false;
00052 }
00053 }
00054 return true;
00055 }
00056
00057
00058
00059 static int calcLength(const Grid& p0, const Grid& p1,
00060 const Grid& p2, const Grid& p3,
00061 const Grid& from) {
00062 lineParam_t line1, line2;
00063 createLine(&line1, p0, p1);
00064 createLine(&line2, p2, p3);
00065
00066 double t = line1.b * line2.a - line2.b * line1.a;
00067 if (fabs(t) < 0.00001) {
00068 return INT_MAX;
00069 }
00070 double x = (line1.c * line2.b - line2.c * line1.b) / t;
00071 double y = (line1.a * line2.c - line2.a * line1.c) / t;
00072
00073 if (!onLine(p0, p1, x, y) || !onLine(p2, p3, x, y)) {
00074 return INT_MAX;
00075 }
00076 return (int)sqrt((x - from.x)*(x - from.x) + (y - from.y)*(y - from.y));
00077 }
00078
00079
00080 int getLengthToEnvironment(const CoordinateCtrl::line_t& line,
00081 const std::vector<crd_polygon_t>& polygons) {
00082 double angle = line.position.zt.to_rad();
00083 Grid p0(line.position.x, line.position.y);
00084 Grid p1(line.position.x + (int)(line.length * cos(angle)),
00085 line.position.y + (int)(line.length * sin(angle)));
00086
00087 int length_min = line.length;
00088 for (std::vector<crd_polygon_t>::const_iterator lines = polygons.begin();
00089 lines != polygons.end(); ++lines) {
00090 Grid p2 = (*lines).back();
00091 for (unsigned int i = 0; i < lines->size(); ++i) {
00092
00093 Grid p3((*lines)[i].x, (*lines)[i].y);
00094
00095
00096 int length = 0;
00097 if ((length = calcLength(&p0, &p1, &p2, &p3, &p0)) >= 0) {
00098
00099 if (length < length_min) {
00100 length_min = length;
00101 }
00102 }
00103 p2 = p3;
00104 }
00105 }
00106
00107
00108 if (length_min + ERROR_VALUE < line.length) {
00109 length_min
00110 += (int)(2.0 * ERROR_VALUE * rand()/(RAND_MAX+1.0) - ERROR_VALUE);
00111 }
00112 return length_min;
00113 }
00114