/*========================================================================= Program: Visualization Toolkit Module: vtkContextPolygon.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkContextPolygon.h" #include #include #include "vtkTransform2D.h" //----------------------------------------------------------------------------- class vtkContextPolygonPrivate { public: std::vector points; }; //----------------------------------------------------------------------------- vtkContextPolygon::vtkContextPolygon() : d(new vtkContextPolygonPrivate) { } //----------------------------------------------------------------------------- vtkContextPolygon::vtkContextPolygon(const vtkContextPolygon &polygon) : d(new vtkContextPolygonPrivate) { d->points = polygon.d->points; } //----------------------------------------------------------------------------- vtkContextPolygon::~vtkContextPolygon() { delete d; } //----------------------------------------------------------------------------- void vtkContextPolygon::AddPoint(const vtkVector2f &point) { d->points.push_back(point); } //----------------------------------------------------------------------------- void vtkContextPolygon::AddPoint(float x, float y) { this->AddPoint(vtkVector2f(x, y)); } //----------------------------------------------------------------------------- vtkVector2f vtkContextPolygon::GetPoint(vtkIdType index) const { return d->points[index]; } //----------------------------------------------------------------------------- vtkIdType vtkContextPolygon::GetNumberOfPoints() const { return static_cast(d->points.size()); } //----------------------------------------------------------------------------- void vtkContextPolygon::Clear() { d->points.clear(); } //----------------------------------------------------------------------------- bool vtkContextPolygon::Contains(const vtkVector2f &point) const { float x = point.GetX(); float y = point.GetY(); // 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.GetY(), p2.GetY()) && y <= std::max(p1.GetY(),p2.GetY()) && p1.GetY() != p2.GetY()) { if (x <= std::max(p1.GetX(), p2.GetX()) ) { xintersection = (y - p1.GetY())*(p2.GetX() - p1.GetX())/(p2.GetY() - p1.GetY()) + p1.GetX(); if ( p1.GetX() == p2.GetX() || 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 { vtkContextPolygon transformed; transformed.d->points.resize(d->points.size()); transform->TransformPoints(reinterpret_cast(&d->points[0]), reinterpret_cast(&transformed.d->points[0]), static_cast(d->points.size())); return transformed; } //----------------------------------------------------------------------------- vtkContextPolygon& vtkContextPolygon::operator=(const vtkContextPolygon &other) { if(this != &other) { d->points = other.d->points; } return *this; }