iMSTK
Interactive Medical Simulation Toolkit
imstkPbdDihedralConstraint.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkPbdDihedralConstraint.h"
8 
9 namespace imstk
10 {
11 void
13  const Vec3d& p0, const Vec3d& p1, const Vec3d& p2, const Vec3d& p3,
14  const PbdParticleId& pIdx0, const PbdParticleId& pIdx1,
15  const PbdParticleId& pIdx2, const PbdParticleId& pIdx3,
16  const double k)
17 {
18  m_particles[0] = pIdx0;
19  m_particles[1] = pIdx1;
20  m_particles[2] = pIdx2;
21  m_particles[3] = pIdx3;
22 
23  setStiffness(k);
24 
25  const Vec3d n1 = (p2 - p0).cross(p3 - p0).normalized();
26  const Vec3d n2 = (p3 - p1).cross(p2 - p1).normalized();
27 
28  m_restAngle = atan2(n1.cross(n2).dot(p3 - p2), (p3 - p2).norm() * n1.dot(n2));
29 }
30 
31 bool
33  double& c, std::vector<Vec3d>& dcdx)
34 {
35  const Vec3d& p0 = bodies.getPosition(m_particles[0]);
36  const Vec3d& p1 = bodies.getPosition(m_particles[1]);
37  const Vec3d& p2 = bodies.getPosition(m_particles[2]);
38  const Vec3d& p3 = bodies.getPosition(m_particles[3]);
39 
40  const Vec3d e = p3 - p2;
41  const Vec3d e1 = p3 - p0;
42  const Vec3d e2 = p0 - p2;
43  const Vec3d e3 = p3 - p1;
44  const Vec3d e4 = p1 - p2;
45  // To accelerate, all normal (area) vectors and edge length should be precomputed in parallel
46  Vec3d n1 = e1.cross(e);
47  Vec3d n2 = e.cross(e3);
48  const double A1 = n1.norm();
49  const double A2 = n2.norm();
50  n1 /= A1;
51  n2 /= A2;
52 
53  const double l = e.norm();
54  if (l < 1.0e-16)
55  {
56  return false;
57  }
58 
59  dcdx[0] = -(l / A1) * n1;
60  dcdx[1] = -(l / A2) * n2;
61  dcdx[2] = (e.dot(e1) / (A1 * l)) * n1 + (e.dot(e3) / (A2 * l)) * n2;
62  dcdx[3] = (e.dot(e2) / (A1 * l)) * n1 + (e.dot(e4) / (A2 * l)) * n2;
63 
64  c = atan2(n1.cross(n2).dot(e), l * n1.dot(n2)) - m_restAngle;
65 
66  return true;
67 }
68 } // namespace imstk
std::pair< int, int > PbdParticleId
Index pair that refers to a particle in a PbdState. Index 0 is the body id, Index 1 is the particle i...
std::vector< PbdParticleId > m_particles
body, particle index
Compound Geometry.
void initConstraint(const Vec3d &p0, const Vec3d &p1, const Vec3d &p2, const Vec3d &p3, const PbdParticleId &pIdx0, const PbdParticleId &pIdx1, const PbdParticleId &pIdx2, const PbdParticleId &pIdx3, const double k)
initConstraint p3 / | \ / | \ p0 | p1 \ | / \ | / p2
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
Definition: imstkPbdBody.h:229
bool computeValueAndGradient(PbdState &bodies, double &c, std::vector< Vec3d > &dcdx) override
Compute value and gradient of the constraint.