Commit d8c776b1 authored by Kyle Lutz's avatar Kyle Lutz Committed by Code Review
Browse files

Merge topic 'better-polygon-selection' into master

a44c5753 Improve polygon selection to handle concave selections
parents 65debdf7 a44c5753
......@@ -75,6 +75,40 @@ void vtkContextPolygon::Clear()
d->points.clear();
}
//-----------------------------------------------------------------------------
bool vtkContextPolygon::Contains(const vtkVector2f &point) const
{
float x = point.X();
float y = point.Y();
// http://en.wikipedia.org/wiki/Point_in_polygon RayCasting method
// shooting the ray along the x axis
bool inside = false;
float xintersection;
for(size_t i = 0; i < d->points.size(); i++)
{
const vtkVector2f &p1 = d->points[i];
const vtkVector2f &p2 = d->points[(i+1) % d->points.size()];
if (y > std::min(p1.Y(), p2.Y()) &&
y <= std::max(p1.Y(),p2.Y()) &&
p1.Y() != p2.Y())
{
if (x <= std::max(p1.X(), p2.X()) )
{
xintersection = (y - p1.Y())*(p2.X() - p1.X())/(p2.Y() - p1.Y()) + p1.X();
if ( p1.X() == p2.X() || x <= xintersection)
{
// each time we intersect we switch if we are in side or not
inside = !inside;
}
}
}
}
return inside;
}
//-----------------------------------------------------------------------------
vtkContextPolygon vtkContextPolygon::Transformed(vtkTransform2D *transform) const
{
......
......@@ -58,6 +58,10 @@ public:
// Clears all the points from the polygon.
void Clear();
// Description:
// Returns \c true if the polygon contains \p point.
bool Contains(const vtkVector2f &point) const;
// Description:
// Returns a new polygon with each point transformed by \p transform.
vtkContextPolygon Transformed(vtkTransform2D *transform) const;
......
......@@ -30,10 +30,6 @@
#include "vtkObjectFactory.h"
#include "vtkUnsignedCharArray.h"
#include "vtkLookupTable.h"
#include "vtkDelaunay2D.h"
#include "vtkPointSet.h"
#include "vtkPolygon.h"
#include "vtkTriangle.h"
#include <vector>
#include <algorithm>
......@@ -599,24 +595,6 @@ bool vtkPlotPoints::SelectPointsInPolygon(const vtkContextPolygon &polygon)
this->Selection->SetNumberOfValues(0);
}
// create delaunay triangulation of the input polygon
vtkNew<vtkPoints> points;
for(vtkIdType i = 0; i < polygon.GetNumberOfPoints(); i++)
{
const vtkVector2f point = polygon.GetPoint(i);
points->InsertNextPoint(point[0], point[1], 0.0);
}
vtkNew<vtkPolyData> inputPoints;
inputPoints->SetPoints(points.GetPointer());
vtkNew<vtkDelaunay2D> triangulator;
triangulator->SetInputData(inputPoints.GetPointer());
triangulator->Update();
// get triangulation
vtkPolyData *polyData = triangulator->GetOutput();
for(vtkIdType pointId = 0;
pointId < this->Points->GetNumberOfPoints();
pointId++)
......@@ -624,27 +602,10 @@ bool vtkPlotPoints::SelectPointsInPolygon(const vtkContextPolygon &polygon)
// get point location
double point[3];
this->Points->GetPoint(pointId, point);
point[2] = 0;
for(vtkIdType cellId = 0; cellId < polyData->GetNumberOfCells(); cellId++)
if (polygon.Contains(vtkVector2f(point[0], point[1])))
{
vtkCell *cell = polyData->GetCell(cellId);
vtkTriangle *triangle = vtkTriangle::SafeDownCast(cell);
if(triangle)
{
// get triangle point locations
double p1[3], p2[3], p3[3];
polyData->GetPoint(triangle->GetPointId(0), p1);
polyData->GetPoint(triangle->GetPointId(1), p2);
polyData->GetPoint(triangle->GetPointId(2), p3);
// check if the triangle contains point
if(vtkTriangle::PointInTriangle(point, p1, p2, p3, 1e-10))
{
this->Selection->InsertNextValue(pointId);
break;
}
}
this->Selection->InsertNextValue(pointId);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment