英文:
Computing curvatures with CGAL
问题
我试图理解如何使用CGAL计算SurfaceMesh
(以及高斯曲率)的主曲率。
首先,我没有看到是否有一个函数可以计算网格中所有顶点的曲率?
在Jet_fitting_3
中似乎有一个示例,但它非常复杂,涉及到多个附加的类...
据我了解,对于每个顶点,我需要:
- 收集周围的点
- 使用
monge_fit
获得蒙日形式
但示例然后使用comply_wrt_given_normal
修改法线,我不完全理解为什么需要这样做。
我可能也会忽略一个非常明显的函数,可以计算这个,正如我之前所说...毕竟这是一个非常重要的属性。
我成功编写的代码如下:
for (auto v : result.vertices())
{
adj.clear();
auto h = result.halfedge(v);
// 找到所有相邻的顶点
for (HalfedgeDescriptor he : result.halfedges_around_target(h))
adj.push_back(result.point(result.source(he)));
CGAL::Monge_via_jet_fitting<Kernel> monge_fit;
CGAL::Monge_via_jet_fitting<Kernel>::Monge_form monge_form;
monge_form = monge_fit(adj.begin(), adj.end(), 2, 1);
monge_form.comply_wrt_given_normal(vn.first[v]);
// 获取主曲率
double k1 = monge_form.principal_curvatures(0);
double k2 = monge_form.principal_curvatures(1);
}
然而,它在调用monge_fit
时引发异常,异常消息如下:
CGAL error: precondition violation!
Expression: nb_input_pts >= nb_d_jet_coeff
File: /opt/homebrew/include/CGAL/Monge_via_jet_fitting.h
Line: 297
Explanation:
Refer to the bug-reporting instructions at https://www.cgal.org/bug_report.html
libc++abi: terminating due to uncaught exception of type CGAL::Precondition_exception: CGAL ERROR: precondition violation!
Expr: nb_input_pts >= nb_d_jet_coeff
File: /opt/homebrew/include/CGAL/Monge_via_jet_fitting.h
Line: 297
所以,点的数量不足,我猜是这个问题?
然而,我不知道如何纠正这个问题... 任何提示都将不胜感激。
英文:
I am trying to understand how I can compute the principal curvatures of a SurfaceMesh
(and so the gaussian one) using CGAL.
First of all, since I didn't see it, is there any function that computes a curvature for all vertices in a mesh?
There seems to be an example in Jet_fitting_3
, but it's really convoluted, with several additional classes...
As far as I understand, I have to, for each vertex:
- gather points around it
- use
monge_fit
on them obtaining a monge form
But the example then modifies the normal with comply_wrt_given_normal
which I do not understand completely why it would be needed.
I might also be skipping over a quite obvious function that computes this, as I said before... after all it's really an important property.
The code I have succeeded to write is this:
for (auto v : result.vertices())
{
adj.clear();
auto h = result.halfedge(v);
// find all adjacent vertices
for (HalfedgeDescriptor he : result.halfedges_around_target(h))
adj.push_back(result.point(result.source(he)));
CGAL::Monge_via_jet_fitting<Kernel> monge_fit;
CGAL::Monge_via_jet_fitting<Kernel>::Monge_form monge_form;
monge_form = monge_fit(adj.begin(), adj.end(), 2, 1);
monge_form.comply_wrt_given_normal(vn.first[v]);
// get the principal curvatures
double k1 = monge_form.principal_curvatures(0);
double k2 = monge_form.principal_curvatures(1);
}
However, it raises an exception in calling monge_fit
, with the following text:
CGAL error: precondition violation!
Expression : nb_input_pts >= nb_d_jet_coeff
File : /opt/homebrew/include/CGAL/Monge_via_jet_fitting.h
Line : 297
Explanation:
Refer to the bug-reporting instructions at https://www.cgal.org/bug_report.html
libc++abi: terminating due to uncaught exception of type CGAL::Precondition_exception: CGAL ERROR: precondition violation!
Expr: nb_input_pts >= nb_d_jet_coeff
File: /opt/homebrew/include/CGAL/Monge_via_jet_fitting.h
Line: 297
So the number of points are not sufficient, I guess?
I don't know, however, how to correct this... any hints are more than welcome.
答案1
得分: 1
The method comply_wrt_given_normal
'orients' the fitted jet.
使用方法 comply_wrt_given_normal
用于调整拟合的曲线。
Fitting a jet by only giving points gives curvatures values and a normal vector that are valid up to a sign.
仅通过提供点来拟合曲线会产生曲率值和法向量,这些值有效,但带有符号。
If you care about the sign of the Gaussian curvature then you must call comply_wrt_given_normal
, else you can avoid calling it and use the absolute value of the curvature.
如果你关心高斯曲率的符号,那么你必须调用 comply_wrt_given_normal
,否则你可以避免调用它并使用曲率的绝对值。
Internally, comply_wrt_given_normal
just swap and multiply by -1 some coefficients of the jet.
在内部,comply_wrt_given_normal
只是交换并将曲线的一些系数乘以 -1。
Fitting a jet requires to solve a system of equations where the dimensions depend on the number of points and the order of the jet.
拟合曲线需要解决一个方程组,其维度取决于点的数量和曲线的阶数。
With a mesh, you have very few adjacent vertices so the system of equation is under-determined and cannot be solved, hence the error you get.
使用网格时,相邻顶点很少,因此方程组是欠定的,无法解决,这就是你遇到的错误。
I see 4 solutions
我看到有4种解决方案
- lower the degree of the jet: in the example https://doc.cgal.org/latest/Jet_fitting_3/index.html#Jet_fitting_3SingleEstimationaboutaPoint,
d_fitting
andd_monge
are set to4
, but since you are only interested in principal curvatures (2nd order derivatives of the surface), then you can set them to2
. Order2
may be sufficient for a few points, but it will depend on your mesh connectivity. - 降低曲线的阶数:在示例 https://doc.cgal.org/latest/Jet_fitting_3/index.html#Jet_fitting_3SingleEstimationaboutaPoint 中,
d_fitting
和d_monge
被设置为4
,但由于你只关心主曲率(表面的二阶导数),所以你可以将它们设置为2
。阶数2
对于少数点可能足够,但这将取决于你的网格连接性。 - increase the number of points: add other points to the vertices you already give to the jet fitting, like the center point of each adjacent triangles or incident edges. It's a little bit 'artificial' and it may produce different curvature values, but that can solve your issue. A complex but accurate solution would be to uniformly sample each adjacent triangles with a sufficiently high number of points.
- 增加点的数量:将其他点添加到你已经提供给曲线拟合的顶点中,例如每个相邻三角形或相邻边的中心点。这有点“人为”,可能会产生不同的曲率值,但可以解决你的问题。一个复杂但准确的解决方案是使用足够多的点均匀采样每个相邻的三角形。
- use another library if that is possible:
- 如果可能的话,使用另一个库:
- approximate yourself the Gaussian curvature 'manually' on each vertex. For a given vertex, compute the sum of angles between pair of incident and successive edges. Then the Gaussian curvature can be approximated by the difference between
2*pi
and this sum divided by the sum of areas of adjacent triangles (this is a formula I remembered from memory so it should be double checked). - 手动近似高斯曲率:对于给定的顶点,计算相邻和连续边对之间的角度之和。然后,高斯曲率可以通过
2*pi
与这个和的差除以相邻三角形的面积之和来近似计算(这是我记忆中的一个公式,应该双重检查)。
英文:
The method comply_wrt_given_normal
'orients' the fitted jet.
Fitting a jet by only giving points gives curvatures values and a normal vector that are valid up to a sign.
If you care about the sign of the Gaussian curvature then you must call comply_wrt_given_normal
, else you can avoid calling it and use the absolute value of the curvature.
Internally, comply_wrt_given_normal
just swap and multiply by -1 some coefficients of the jet.
Fitting a jet requires to solve a system of equations where the dimensions depend on the number of points and the order of the jet.
With a mesh, you have very few adjacent vertices so the system of equation is under-determined and cannot be solved, hence the error you get.
I see 4 solutions
- lower the degree of the jet: in the example https://doc.cgal.org/latest/Jet_fitting_3/index.html#Jet_fitting_3SingleEstimationaboutaPoint,
d_fitting
andd_monge
are set to4
, but since you are only interested in principal curvatures (2nd order derivatives of the surface), then you can set them to2
. Order2
may be sufficient for a few points, but it will depends on your mesh connectivity. - increase the number of points: add other points to the vertices you already give to the jet fitting, like the center point of each adjacent triangles or incident edges. It's a little bit 'artificial' and it may produces different curvatures values, but that can solve your issue. A complex but accurate solution would be to uniformly sample each adjacent triangles with a sufficiently high number of points.
- use another library if that is possible:
- approximate yourself the Gaussian curvature 'manually' on each vertex. For a given vertex, compute the sum of angles between pair of incident and successive edges. Then the Gaussian curvature can be approximated by the difference between
2*pi
and this sum divided by the sum of areas of adjacent triangles (this is a formula I remembered from memory so it should be double checked).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论