Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <stdint.h>
00031
00032 #include <swri_geometry_util/intersection.h>
00033
00034 #define HAVE_INT64_T_64 # Prevents conflict with OpenCV typedef of int64
00035 #include <geos/geom/CoordinateArraySequence.h>
00036 #include <geos/geom/GeometryFactory.h>
00037 #include <geos/geom/Polygon.h>
00038 #undef HAVE_INT64_T_64
00039
00040 namespace swri_geometry_util
00041 {
00042 bool LineIntersection(
00043 cv::Vec2d p1,
00044 cv::Vec2d p2,
00045 cv::Vec2d p3,
00046 cv::Vec2d p4,
00047 cv::Vec2d& c)
00048 {
00049 double d = (p1[0] - p2[0]) * (p3[1] - p4[1]) - (p1[1] - p2[1]) * (p3[0] - p4[0]);
00050 if (d == 0)
00051 {
00052 return false;
00053 }
00054
00055 double n_a = (p1[0] * p2[1] - p1[1] * p2[0]) * (p3[0] - p4[0]) - (p1[0] - p2[0]) * (p3[0] * p4[1] - p3[1] * p4[0]);
00056 double n_b = (p1[0] * p2[1] - p1[1] * p2[0]) * (p3[1] - p4[1]) - (p1[1] - p2[1]) * (p3[0] * p4[1] - p3[1] * p4[0]);
00057
00058 c[0] = n_a / d;
00059 c[1] = n_b / d;
00060
00061 return true;
00062 }
00063
00064 bool PolygonsIntersect(
00065 const std::vector<cv::Vec2d>& a,
00066 const std::vector<cv::Vec2d>& b)
00067 {
00068
00069 geos::geom::CoordinateSequence* a_coords = new geos::geom::CoordinateArraySequence();
00070 for (size_t i = 0; i < a.size(); i++)
00071 {
00072 a_coords->add(geos::geom::Coordinate(a[i][0], a[i][1]));
00073 }
00074 a_coords->add(a_coords->front());
00075
00076 geos::geom::LinearRing* a_ring = geos::geom::GeometryFactory::getDefaultInstance()->createLinearRing(a_coords);
00077 geos::geom::Polygon* a_polygon = geos::geom::GeometryFactory::getDefaultInstance()->createPolygon(a_ring, 0);
00078 a_polygon->normalize();
00079
00080
00081 geos::geom::CoordinateSequence* b_coords = new geos::geom::CoordinateArraySequence();
00082 for (size_t i = 0; i < b.size(); i++)
00083 {
00084 b_coords->add(geos::geom::Coordinate(b[i][0], b[i][1]));
00085 }
00086 b_coords->add(b_coords->front());
00087
00088 geos::geom::LinearRing* b_ring = geos::geom::GeometryFactory::getDefaultInstance()->createLinearRing(b_coords);
00089 geos::geom::Polygon* b_polygon = geos::geom::GeometryFactory::getDefaultInstance()->createPolygon(b_ring, 0);
00090 b_polygon->normalize();
00091
00092 bool intersects = a_polygon->intersects(b_polygon);
00093
00094
00095 delete a_polygon;
00096 delete b_polygon;
00097
00098 return intersects;
00099 }
00100
00101 double PolygonIntersectionArea(
00102 const std::vector<cv::Vec2d>& a,
00103 const std::vector<cv::Vec2d>& b)
00104 {
00105 double area = 0;
00106
00107 geos::geom::CoordinateSequence* a_coords = new geos::geom::CoordinateArraySequence();
00108 for (size_t i = 0; i < a.size(); i++)
00109 {
00110 a_coords->add(geos::geom::Coordinate(a[i][0], a[i][1]));
00111 }
00112 a_coords->add(a_coords->front());
00113
00114 geos::geom::LinearRing* a_ring = geos::geom::GeometryFactory::getDefaultInstance()->createLinearRing(a_coords);
00115 geos::geom::Polygon* a_polygon = geos::geom::GeometryFactory::getDefaultInstance()->createPolygon(a_ring, 0);
00116 a_polygon->normalize();
00117
00118
00119 geos::geom::CoordinateSequence* b_coords = new geos::geom::CoordinateArraySequence();
00120 for (size_t i = 0; i < b.size(); i++)
00121 {
00122 b_coords->add(geos::geom::Coordinate(b[i][0], b[i][1]));
00123 }
00124 b_coords->add(b_coords->front());
00125
00126 geos::geom::LinearRing* b_ring = geos::geom::GeometryFactory::getDefaultInstance()->createLinearRing(b_coords);
00127 geos::geom::Polygon* b_polygon = geos::geom::GeometryFactory::getDefaultInstance()->createPolygon(b_ring, 0);
00128 b_polygon->normalize();
00129
00130 if (a_polygon->intersects(b_polygon))
00131 {
00132 area = a_polygon->intersection(b_polygon)->getArea();
00133 }
00134
00135
00136 delete a_polygon;
00137 delete b_polygon;
00138
00139 return area;
00140 }
00141 }