3

我目前正在使用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();
}
4

0 回答 0