манипулирование / деформация сетки на основе координат с использованием libigl

Я сейчас пользуюсь libigl манипулировать / деформировать простой (2D) квадрат, манипулируя его углами (см. начальное состояние ниже):

введите описание изображения здесь

После наложения смещения u (1,1) в нижний левый угол и обновления местоположений неугловых вершин с использованием бигармонической деформации я получаю следующее состояние (вдохновлено Бигармоническая деформация учебник ):

введите описание изображения здесь

Проблемы:

  • треугольники распределены неравномерно
  • Деформация изменила стороны, которые больше не являются прямыми

Тогда идеальным решением было бы что-то близкое к изображению ниже, без необходимости управлять каждой граничной вершиной:

введите описание изображения здесь

Вопросы:

  • Какой метод короля деформации я должен использовать для достижения такого результата?
  • Является ли libigl правильным инструментом для таких операций?

ПРИМЕЧАНИЕ: полная реализация:

#include <iostream>
#include <Eigen/Core>
#include <igl/colon.h>
#include <igl/harmonic.h>
#include <igl/viewer/Viewer.h>
#include <igl/triangle/triangulate.h>
#include "tutorial_shared_path.h"
using namespace Eigen;
using namespace std;

double step = 0.1;
// Input polygon
MatrixXd V; // corners location
MatrixXi E; // boundary edges
MatrixXd H; // 2D positions of points contained in holes of the triangulation

// Triangulated interior
MatrixXd D_bc; // displacements / corner
MatrixXd V2; // all vertexes location
MatrixXd U; // deformed vertexes
MatrixXi F2;
Eigen::VectorXi b; // index of corner vertices
int selected = 0; // index of currently selected corner

void update(igl::viewer::Viewer &viewer) {
cout << "D_bc " <<endl
<< D_bc <<endl;
// compute displacements
MatrixXd D;
igl::harmonic(V2,F2,b,D_bc,2.,D);
// compute solution as init state + displacements
U = V2+D;
viewer.data.set_vertices(U);

// display current selection
Eigen::MatrixXd points(1,3);
points << V(selected, 0) + D_bc(selected, 0), V(selected, 1) + D_bc(selected, 1), 0;
viewer.data.set_points(points,Eigen::RowVector3d(1,0,0));
}

bool key_down(igl::viewer::Viewer &viewer, unsigned char key, int mods) {
switch((int)key)
{
case 32: // space
selected = (selected + 1) % 4;
break;
case 6: // right
D_bc(selected, 0) += step;
break;
case 7: // left
D_bc(selected, 0) -= step;
break;
case 8: // down
D_bc(selected, 1) -= step;
break;
case 9: // top
D_bc(selected, 1) += step;
break;
default:
return false;
}
update(viewer);
return true;
}

int main(int argc, char *argv[])
{
// Create the boundary of a square
V.resize(4,2);
V << -1,-1, 1,-1, 1,1, -1,1;
E.resize(4,2);
E << 0,1, 1,2, 2,3, 3,0;
H.resize(0,2);
// Triangulate the interior
igl::triangle::triangulate(V,E,H,"a0.01q",V2,F2);

igl::colon<int>(0,V.rows()-1,b);

// Plot the generated mesh
igl::viewer::Viewer viewer;
viewer.data.set_mesh(V2,F2);

// set initial displacements / solution
D_bc = MatrixXd::Zero(V.rows(), V.cols());
U=V2;

viewer.callback_key_down = &key_down;
update(viewer);

// display legend
cout<<
"Press [space] to switch point."<<endl<<
"Use arrows to move current point."<<endl;

viewer.launch();
}

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]