Example #1
0
void SurfacePins::add_elastic_gradient_block_diagonal(RawArray<SymmetricMatrix<T,m>> dFdX) const {
  GEODE_ASSERT(dFdX.size()==mass.size());
  for (int i=0;i<particles.size();i++) {
    int p = particles[i];
    dFdX[p] -= scaled_outer_product(k[i],info[i].normal); // Ignores a curvature term if the closest point is on an edge or vertex
  }
}
Example #2
0
template<class TV> static Matrix<T,TV::m+1> affine_register_helper(RawArray<const TV> X0, RawArray<const TV> X1, RawArray<const T> mass) {
  typedef typename TV::Scalar T;
  static const int d = TV::m;
  const int n = X0.size();
  GEODE_ASSERT(n==X1.size() && (mass.size()==0 || mass.size()==n));
  const bool weighted = mass.size() == n;
  const T total = weighted ? mass.sum() : n;
  if (!total)
    return Matrix<T,d+1>::identity_matrix();

  // Compute centers of mass
  TV c0, c1;
  if (weighted) {
    for (int i=0;i<n;i++) {
      c0 += mass[i]*X0[i];
      c1 += mass[i]*X1[i];
    }
  } else {
    c0 = X0.sum();
    c1 = X1.sum();
  }
  c0 /= total;
  c1 /= total;

  // Compute covariances
  SymmetricMatrix<T,d> cov00 = scaled_outer_product(-total,c0);
  Matrix<T,d> cov01 = outer_product(-total*c1,c0);
  if (weighted)
    for(int i=0;i<n;i++) {
      cov00 += scaled_outer_product(mass[i],X0[i]);
      cov01 += outer_product(mass[i]*X1[i],X0[i]);
    }
  else
    for (int i=0;i<n;i++) {
      cov00 += outer_product(X0[i]);
      cov01 += outer_product(X1[i],X0[i]);
    }

  // Compute transform
  const Matrix<T,d> A = cov01*cov00.inverse();
  const TV t = c1-A*c0;
  auto tA = Matrix<T,d+1>::from_linear(A);
  tA.set_translation(t);
  return tA;
}