Diretório de artigos
1 Problema de casco convexo
Em termos simples, dado um conjunto de pontos em um plano, encontrar um polígono convexo mínimo contendo todos os pontos é o problema do casco convexo.
A Enciclopédia Convex Hull_Baidu (baidu.com) explica o casco convexo da seguinte forma:
Convex Hull é um conceito em geometria computacional (gráficos).
Em um espaço vetorial real V, para um dado conjunto X, a interseção S de todos os conjuntos convexos contendo X é chamada de casca convexa de X. O casco convexo de X pode ser construído pela combinação convexa de todos os pontos (X1,...Xn) em X.
No espaço euclidiano bidimensional , o casco convexo pode ser imaginado como um elástico que apenas envolve todos os pontos.
Em termos soltos, dado um conjunto de pontos em um plano bidimensional, o casco convexo é um polígono convexo formado pela conexão dos pontos mais externos , que podem conter todos os pontos do conjunto.
Alguns blogs sobre cascos convexos:
Explicação detalhada do casco convexo
Casco Convexo - Cinco Soluções
2 implementação de código
Calcula o casco convexo 2D de um conjunto de pontos e gera as coordenadas do ponto do casco convexo.
Conforme mostrado na figura abaixo: os pontos verdes são os pontos convexos do casco, os pontos vermelhos são os pontos dentro do casco convexo e a linha roxa é o contorno do casco convexo.
2.1 Extrair pontos de casco convexos em array Array
Código:
#include <iostream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/convex_hull_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
int main()
{
//定义二维点数组,并赋初值
Point_2 points[10] = {
Point_2(1,1),Point_2(2,5), Point_2(3,2),Point_2(4,1), Point_2(5,5),Point_2(5,7),Point_2(6,3),Point_2(7,5), Point_2(8,2), Point_2(10,4) };
//定义凸包点数组,用于接收提取的凸包点
Point_2 result[10];
//执行凸包提取
Point_2 *ptr = CGAL::convex_hull_2(points, points + 10, result);
//输出凸包点
std::cout << ptr - result << " 个凸包点:" << std::endl;
for (int i = 0; i < ptr - result; i++) {
std::cout << result[i] << std::endl;
}
return 0;
}
Resultado de saída:
6 个凸包点:
1 1
4 1
8 2
10 4
5 7
2 5
Descrição da função do casco convexo convex_hull_2
:
convex_hull_2(ForwardIterator first, ForwardIterator last,
OutputIterator result )
{
return convex_hull_points_2(first, last, result);
}
A função de casco convexo convex_hull_2
aceita três argumentos. Os dois primeiros são parâmetros de entrada, que são points
o ponteiro inicial e o ponteiro final do array de entrada, respectivamente; o terceiro parâmetro é o parâmetro de saída, que é result
o ponteiro inicial do array de resultado. A função retorna um ponteiro para o array de resultados, logo após o último ponto convexo do casco escrito (representado pela caixa tracejada na imagem abaixo), por ptr
Receive, então a diferença do ponteiro ptr-result
nos diz quantos pontos estão no casco convexo.
2.2 Extrair pontos convexos do casco no vetor
O seguinte usa o vetor na biblioteca de modelos padrão STL em vez da matriz para extrair o casco convexo
Código:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/convex_hull_2.h>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
typedef std::vector<Point_2> Points;
int main()
{
Points points; //输入向量
points.push_back(Point_2(1, 1));
points.push_back(Point_2(2, 5));
points.push_back(Point_2(3, 2));
points.push_back(Point_2(4, 1));
points.push_back(Point_2(5, 5));
points.push_back(Point_2(5, 7));
points.push_back(Point_2(6, 3));
points.push_back(Point_2(7, 5));
points.push_back(Point_2(8, 2));
points.push_back(Point_2(10, 4));
Points result; //凸包向量
CGAL::convex_hull_2(points.begin(), points.end(), std::back_inserter(result));
std::cout << result.size() << "个凸包点" << std::endl;
for (auto val : result)
{
std::cout << val << std::endl;
}
return 0;
}
Resultado de saída:
6个凸包点
1 1
4 1
8 2
10 4
5 7
2 5
Usando Array e usando Vector, os resultados são os mesmos nos dois sentidos, mas o último é mais conciso.