Estrada de aprendizagem CGAL (2): extração de casco convexo de ponto plano (Casco Convexo)

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.
insira a descrição da imagem aqui

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_2aceita três argumentos. Os dois primeiros são parâmetros de entrada, que são pointso ponteiro inicial e o ponteiro final do array de entrada, respectivamente; o terceiro parâmetro é o parâmetro de saída, que é resulto 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 ptrReceive, então a diferença do ponteiro ptr-resultnos diz quantos pontos estão no casco convexo.

insira a descrição da imagem aqui

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.

Acho que você gosta

Origin blog.csdn.net/weixin_46098577/article/details/122620862
Recomendado
Clasificación