12 #include <Eigen/Geometry> 41 return bool(cross % 2);
103 for (
size_t i = 0; i <
vertices_.size(); i++) {
108 return std::abs(area / 2.0);
113 Position centroid = Position::Zero();
115 vertices.push_back(vertices.at(0));
117 for (
size_t i = 0; i < vertices.size() - 1; i++) {
118 const double a = vertices[i].x() * vertices[i+1].y() - vertices[i+1].x() * vertices[i].y();
120 centroid.x() += a * (vertices[i].x() + vertices[i+1].x());
121 centroid.y() += a * (vertices[i].y() + vertices[i+1].y());
124 centroid /= (6.0 * area);
130 double minX = std::numeric_limits<double>::infinity();
131 double maxX = -std::numeric_limits<double>::infinity();
132 double minY = std::numeric_limits<double>::infinity();
133 double maxY = -std::numeric_limits<double>::infinity();
135 if (vertex.x() > maxX) maxX = vertex.x();
136 if (vertex.y() > maxY) maxY = vertex.y();
137 if (vertex.x() < minX) minX = vertex.x();
138 if (vertex.y() < minY) minY = vertex.y();
140 center.x() = (minX + maxX) / 2.0;
141 center.y() = (minY + maxY) / 2.0;
142 length.x() = (maxX - minX);
143 length.y() = (maxY - minY);
149 for (
unsigned int i = 0; i <
nVertices(); ++i)
157 for (
unsigned int i = 0; i < V.rows(); ++i)
158 k.row(i) << i, (i+1) % V.rows();
159 Eigen::RowVectorXd c = V.colwise().mean();
161 A = Eigen::MatrixXd::Constant(k.rows(), V.cols(), NAN);
164 for (
unsigned int ix = 0; ix < k.rows(); ++ix) {
165 Eigen::MatrixXd F(2, V.cols());
166 F.row(0) << V.row(k(ix, 0));
167 F.row(1) << V.row(k(ix, 1));
168 Eigen::FullPivLU<Eigen::MatrixXd> luDecomp(F);
169 if (luDecomp.rank() == F.rows()) {
170 A.row(rc) = F.colPivHouseholderQr().solve(Eigen::VectorXd::Ones(F.rows()));
176 b = Eigen::VectorXd::Ones(A.rows());
177 b = b + A * c.transpose();
186 const Vector orthogonal = thickness *
Vector(connection.y(), -connection.x()).normalized();
187 std::vector<Position> newVertices;
188 newVertices.reserve(4);
189 newVertices.push_back(
vertices_[0] + orthogonal);
190 newVertices.push_back(
vertices_[0] - orthogonal);
191 newVertices.push_back(
vertices_[1] - orthogonal);
192 newVertices.push_back(
vertices_[1] + orthogonal);
201 std::vector<Eigen::Array2i> neighbourIndices;
203 neighbourIndices.resize(n);
204 for (
unsigned int i = 0; i < n; ++i) {
205 neighbourIndices[i] << (i > 0 ? (i-1)%n : n-1), (i + 1) % n;
209 for (
unsigned int i = 0; i < neighbourIndices.size(); ++i) {
214 const double angle = acos(v1.dot(v2));
215 copy[i] += margin / sin(angle) * (v1 + v2);
225 std::vector<Polygon> polygons;
230 polygons.reserve(nPolygons);
234 polygons.push_back(*
this);
237 for (
size_t i = 0; i < nPolygons; ++i) {
239 polygons.push_back((polygon));
249 Eigen::Vector2d centerToVertex(radius, 0.0), centerToVertexTemp;
253 double theta = j * 2 * M_PI / (nVertices - 1);
254 Eigen::Rotation2D<double> rot2d(theta);
255 centerToVertexTemp = rot2d.toRotationMatrix() * centerToVertex;
256 polygon.
addVertex(center + centerToVertexTemp);
262 const Position center2,
const double radius,
265 if (center1 == center2)
return fromCircle(center1, radius, nVertices);
266 Eigen::Vector2d centerToVertex, centerToVertexTemp;
267 centerToVertex = center2 - center1;
268 centerToVertex.normalize();
269 centerToVertex *= radius;
272 for (
int j = 0; j < ceil(nVertices / 2.0); j++) {
273 double theta = M_PI_2 + j * M_PI / (ceil(nVertices / 2.0) - 1);
274 Eigen::Rotation2D<double> rot2d(theta);
275 centerToVertexTemp = rot2d.toRotationMatrix() * centerToVertex;
276 polygon.
addVertex(center1 + centerToVertexTemp);
278 for (
int j = 0; j < ceil(nVertices / 2.0); j++) {
279 double theta = 3 * M_PI_2 + j * M_PI / (ceil(nVertices / 2.0) - 1);
280 Eigen::Rotation2D<double> rot2d(theta);
281 centerToVertexTemp = rot2d.toRotationMatrix() * centerToVertex;
282 polygon.
addVertex(center2 + centerToVertexTemp);
289 std::vector<Position> vertices;
300 if (points.size() <= 3) {
303 std::vector<Position> pointsConvexHull(2 * points.size());
306 auto sortedPoints(points);
307 std::sort(sortedPoints.begin(), sortedPoints.end(),
sortVertices);
312 for (
size_t i = 0; i < sortedPoints.size(); ++i) {
313 while (k >= 2 &&
vectorsMakeClockwiseTurn(pointsConvexHull.at(k - 2), pointsConvexHull.at(k - 1), sortedPoints.at(i))) {
316 pointsConvexHull.at(k++) = sortedPoints.at(i);
320 for (
int i = sortedPoints.size() - 2, t = k + 1; i >= 0; i--) {
321 while (k >= t &&
vectorsMakeClockwiseTurn(pointsConvexHull.at(k - 2), pointsConvexHull.at(k - 1), sortedPoints.at(i))) {
324 pointsConvexHull.at(k++) = sortedPoints.at(i);
326 pointsConvexHull.resize(k - 1);
328 Polygon polygon(pointsConvexHull);
333 const Eigen::Vector2d& vector2)
335 return (vector1.x() < vector2.x()
336 || (vector1.x() == vector2.x() && vector1.y() < vector2.y()));
340 const Eigen::Vector2d& vector2)
342 return (vector1.x() * vector2.y() - vector1.y() * vector2.x());
346 const Eigen::Vector2d &pointA,
347 const Eigen::Vector2d &pointB)
const std::string & getFrameId() const
static Polygon convexHullOfTwoCircles(Position center1, Position center2, double radius, int nVertices=20)
const Position & operator[](size_t index) const
static double computeCrossProduct2D(const Eigen::Vector2d &vector1, const Eigen::Vector2d &vector2)
Position getCentroid() const
static Polygon monotoneChainConvexHullOfPoints(const std::vector< Position > &points)
void setTimestamp(uint64_t timestamp)
uint64_t timestamp_
Timestamp of the polygon (nanoseconds).
const Position & getVertex(size_t index) const
std::string frameId_
Frame id of the polygon.
void addVertex(const Position &vertex)
static Polygon fromCircle(Position center, double radius, int nVertices=20)
bool offsetInward(double margin)
bool isInside(const Position &point) const
std::vector< Position > vertices_
Vertices of the polygon.
std::vector< Polygon > triangulate(const TriangulationMethods &method=TriangulationMethods::FAN) const
static Polygon convexHull(Polygon &polygon1, Polygon &polygon2)
static bool sortVertices(const Eigen::Vector2d &vector1, const Eigen::Vector2d &vector2)
static double vectorsMakeClockwiseTurn(const Eigen::Vector2d &pointO, const Eigen::Vector2d &pointA, const Eigen::Vector2d &pointB)
void setFrameId(const std::string &frameId)
bool thickenLine(double thickness)
uint64_t getTimestamp() const
bool convertToInequalityConstraints(Eigen::MatrixXd &A, Eigen::VectorXd &b) const
const std::vector< Position > & getVertices() const
void getBoundingBox(Position ¢er, Length &length) const