CGAL中判断Surface_mesh的一条边是凸边(Convex)还是凹边(Concave)

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/compute_face_normal.h>
#include <CGAL/Vector_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_3 Point;
typedef K::Vector_3 Vector;
typedef CGAL::Surface_mesh<Point> Mesh;

#include <cmath>

float angle_between_vectors(const Vector& v1, const Vector& v2) {
    float dot_product = v1 * v2;
    float magnitude_v1 = v1.squared_length();
    float magnitude_v2 = v2.squared_length();
    float cosine_angle = dot_product / (sqrt(magnitude_v1) * sqrt(magnitude_v2));
    return acos(cosine_angle);
}

bool is_concave_edge(Mesh& mesh, typename Mesh::Edge_index edge) {
    // 获取边的两个相邻面
    typename Mesh::Halfedge_index he = mesh.halfedge(edge);
    typename Mesh::Face_index face1 = mesh.face(he);
    typename Mesh::Face_index face2 = mesh.face(mesh.opposite(he));
    
    // 计算两个面的法线
    Vector normal1 = CGAL::Polygon_mesh_processing::compute_face_normal(mesh, face1);
    Vector normal2 = CGAL::Polygon_mesh_processing::compute_face_normal(mesh, face2);
    
    // 计算法线之间的角度
    float angle = angle_between_vectors(normal1, normal2);
    
    // 如果角度大于180度,则为凹边
    return angle > K::pi();
}

// 最后,你可以在主函数中使用这个函数来判断特定面的特定边:
int main() {
    Mesh mesh;
    // 假设mesh已经被加载或构建
    
    typename Mesh::Face_index face = /* 获取特定面的索引 */;
    int edge_index = /* 获取特定边的索引 */;
    
    if (is_concave_edge(mesh, face, edge_index)) {
        std::cout << "The edge is concave." << std::endl;
    } else {
        std::cout << "The edge is convex." << std::endl;
    }
    
    return 0;
}

以上代码摘自Kimi的回答。自己补充了部分注释。

==================================================

另外在一段vcglib的代码中,找到了接口的另一种实现方式,如下

	bool IsConcaveEdge(const FaceType& f0, int IndexE)
	{
		// 对三角面片来说,邻接面有三个,对应IndexE的值为{0,1,2}
		FaceType* f1 = f0.cFFp(IndexE); // cFFp 是面(Face)的邻接信息属性,这里指的是边IndexE对应的邻接面
		if (f1 == &f0)
		{
			return false;
		}
		CoordType N0 = f0.cN();			// cN()返回面的法向量
		CoordType N1 = f1->cN();
		// f0.cP1(IndexE) 获取面 f0 中边 IndexE 的第二个端点的坐标。
	    // f0.cP0(IndexE) 获取面 f0 中边 IndexE 的第一个端点的坐标。
		CoordType EdgeDir = f0.cP1(IndexE) - f0.cP0(IndexE);
		EdgeDir.Normalize();
		CoordType Cross = N0 ^ N1;
        // 计算两邻接面法向量的向量积与Edge方向向量的点乘
        // 当两个邻接面共面的时候,是否会有问题??
        // 应该不会。共面时Cross为0向量,点乘结果为0.此时的边无凹凸之分。 
		return ((Cross * EdgeDir) < LimitConcave);
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值