这是我的第一篇博客,在这里我首先对具有开元思想的人表示感谢,是你们的奉献才能让我慢慢的入门。
在常规的laplacian坐标计算中,都习惯性的以顶点为单位,根据laplacian坐标的公式计算,虽然都可以计算出来但是计算量较大。这里提出的laplacian坐标计算方法最小单位为三角形或者四边形,在目前的扫描文件中通常都是用的三角形,故文中的代码都以三角形进行探讨。
static //代码效果参考:http://www.lyjsj.net.cn/wx/art_24197.html
void LaplacianMatrix(SystemData sys){
float v1【3】, v2【3】, v3【3】, v4【3】, no【3】;
float w2, w3, w4;
int i, j, fi;
bool has_4_vert;
unsigned int idv1, idv2, idv3, idv4;
for (fi = 0; fi total_faces; fi++) { //所有面的个数
const unsigned int vidf = sys->faces【fi】;
idv1 = vidf【0】;
idv2 = vidf【1】;
idv3 = vidf【2】;
idv4 = vidf【3】; //面中各个顶点对应顶点的序列
has_4_vert = vidf【3】 ? 1 : 0; //*判断是四边形还是三边形
if (has_4_vert) {
normal_quad_v3(no,//代码效果参考:http://www.lyjsj.net.cn/wz/art_24195.html
sys->co【idv1】, sys->co【idv2】, sys->co【idv3】, sys->co【idv4】);add_v3_v3(sys->no【idv4】, no);
i = 4;
}
else {
normal_tri_v3(no, sys->co【idv1】, sys->co【idv2】, sys->co【idv3】); //计算三角形的法线
i = 3;
}
add_v3_v3(sys->no【idv1】, no); //点的法线与面的法线相加
add_v3_v3(sys->no【idv2】, no);
add_v3_v3(sys->no【idv3】, no);
for (j = 0; j < i; j++) {
idv1 = vidf【j】;
idv2 = vidf【(j + 1) % i】;
idv3 = vidf【(j + 2) % i】;
idv4 = has_4_vert ? vidf【(j + 3) % i】 : 0;
copy_v3_v3(v1, sys->co【idv1】);
copy_v3_v3(v2, sys->co【idv2】);
copy_v3_v3(v3, sys->co【idv3】);
if (has_4_vert) {
copy_v3_v3(v4, sys->co【idv4】);
}
if (has_4_vert) {
w2 = (cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2)) / 2.0f;
w3 = (cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3)) / 2.0f;
w4 = (cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1)) / 2.0f;
sys->delta【idv1】【0】 -= v4【0】 w4;
sys->delta【idv1】【1】 -= v4【1】 w4;
sys->delta【idv1】【2】 -= v4【2】 w4;
nlRightHandSideAdd(0, idv1, -v4【0】 w4);
nlRightHandSideAdd(1, idv1, -v4【1】 w4);
nlRightHandSideAdd(2, idv1, -v4【2】 w4);
nlMatrixAdd(idv1, idv4, -w4);
}
else {
w2 = cotan_weight(v3, v1, v2); //非顶点的夹角,为laplacian坐标的计算做准备
w3 = cotan_weight(v2, v3, v1);
w4 = 0.0f;
}
sys->delta【idv1】【0】 += v1【0】 (w2 + w3 + w4); //计算laplacian坐标的规律,中心点以外的两个顶点夹角的正切值,相加与当前中心点,相减于另外两个顶点
sys->delta【idv1】【1】 += v1【1】 (w2 + w3 + w4); //于对角正切值的乘积,是以三角形为计算中心
sys->delta【idv1】【2】 += v1【2】 (w2 + w3 + w4);
sys->delta【idv1】【0】 -= v2【0】 w2;
sys->delta【idv1】【1】 -= v2【1】 w2;
sys->delta【idv1】【2】 -= v2【2】 w2;
sys->delta【idv1】【0】 -= v3【0】 w3;
sys->delta【idv1】【1】 -= v3【1】 w3;
sys->delta【idv1】【2】 -= v3【2】 * w3;
nlMatrixAdd(idv1, idv2, -w2);
nlMatrixAdd(idv1, idv3, -w3);
nlMatrixAdd(idv1, idv1, w2 + w3 + w4);
}
}
}
上面laplacian坐标的计算即为三角形为最小单位,所以运算速度会较以点为单位的计算方式好些。