mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 15:42:02 +00:00
Merge pull request #2910 from yandex/fix-point-in-poligon
Fix point in poligon
This commit is contained in:
commit
edd37cf617
@ -108,7 +108,8 @@ private:
|
||||
inner,
|
||||
outer,
|
||||
singleLine,
|
||||
pairOfLinesSinglePolygon,
|
||||
pairOfLinesSingleConvexPolygon,
|
||||
pairOfLinesSingleNonConvexPolygons,
|
||||
pairOfLinesDifferentPolygons,
|
||||
complexPolygon
|
||||
};
|
||||
@ -180,6 +181,9 @@ private:
|
||||
/// Returns a list of half-planes were formed from intersection edges without box edges.
|
||||
inline std::vector<HalfPlane> findHalfPlanes(const Box & box, const Polygon & intersection);
|
||||
|
||||
/// Check that polygon.outer() is convex.
|
||||
inline bool isConvex(const Polygon & polygon);
|
||||
|
||||
using Distance = typename boost::geometry::default_comparable_distance_result<Point, Segment>::type;
|
||||
|
||||
/// min(distance(point, edge) : edge in polygon)
|
||||
@ -306,9 +310,10 @@ bool PointInPolygonWithGrid<CoordinateType>::contains(CoordinateType x, Coordina
|
||||
return false;
|
||||
case CellType::singleLine:
|
||||
return cell.half_planes[0].contains(x, y);
|
||||
case CellType::pairOfLinesSinglePolygon:
|
||||
case CellType::pairOfLinesSingleConvexPolygon:
|
||||
return cell.half_planes[0].contains(x, y) && cell.half_planes[1].contains(x, y);
|
||||
case CellType::pairOfLinesDifferentPolygons:
|
||||
case CellType::pairOfLinesSingleNonConvexPolygons:
|
||||
return cell.half_planes[0].contains(x, y) || cell.half_planes[1].contains(x, y);
|
||||
case CellType::complexPolygon:
|
||||
return boost::geometry::within(Point(x, y), polygons[cell.index_of_inner_polygon]);
|
||||
@ -335,6 +340,35 @@ PointInPolygonWithGrid<CoordinateType>::distance(
|
||||
return distance;
|
||||
}
|
||||
|
||||
template <typename CoordinateType>
|
||||
bool PointInPolygonWithGrid<CoordinateType>::isConvex(const PointInPolygonWithGrid<CoordinateType>::Polygon & polygon)
|
||||
{
|
||||
const auto & outer = polygon.outer();
|
||||
/// Segment or point.
|
||||
if (outer.size() < 4)
|
||||
return false;
|
||||
|
||||
auto vecProduct = [](const Point & from, const Point & to) { return from.x() * to.y() - from.y() * to.x(); };
|
||||
auto getVector = [](const Point & from, const Point & to) -> Point
|
||||
{
|
||||
return Point(to.x() - from.x(), to.y() - from.y());
|
||||
};
|
||||
|
||||
Point first = getVector(outer[0], outer[1]);
|
||||
Point prev = first;
|
||||
|
||||
for (auto i : ext::range(1, outer.size() - 1))
|
||||
{
|
||||
Point cur = getVector(outer[i], outer[i + 1]);
|
||||
if (vecProduct(prev, cur) < 0)
|
||||
return false;
|
||||
|
||||
prev = cur;
|
||||
}
|
||||
|
||||
return vecProduct(prev, first) >= 0;
|
||||
}
|
||||
|
||||
template <typename CoordinateType>
|
||||
std::vector<typename PointInPolygonWithGrid<CoordinateType>::HalfPlane>
|
||||
PointInPolygonWithGrid<CoordinateType>::findHalfPlanes(
|
||||
@ -423,7 +457,8 @@ void PointInPolygonWithGrid<CoordinateType>::addCell(
|
||||
}
|
||||
else if (half_planes.size() == 2)
|
||||
{
|
||||
cells[index].type = CellType::pairOfLinesSinglePolygon;
|
||||
cells[index].type = isConvex(intersection) ? CellType::pairOfLinesSingleConvexPolygon
|
||||
: CellType::pairOfLinesSingleNonConvexPolygons;
|
||||
cells[index].half_planes[0] = half_planes[0];
|
||||
cells[index].half_planes[1] = half_planes[1];
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
1314 1314
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user