iMSTK
Interactive Medical Simulation Toolkit
imstkPbdPointEdgeConstraint.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 "imstkPbdPointEdgeConstraint.h"
8 
9 namespace imstk
10 {
11 void
13  const PbdParticleId& ptA1,
14  const PbdParticleId& ptB1, const PbdParticleId& ptB2,
15  double stiffnessA, double stiffnessB)
16 {
17  m_particles[0] = ptA1;
18  m_particles[1] = ptB1;
19  m_particles[2] = ptB2;
20 
21  m_stiffness[0] = stiffnessA;
22  m_stiffness[1] = stiffnessB;
23 }
24 
25 bool
27  double& c, std::vector<Vec3d>& dcdx)
28 {
29  // Just project x0 onto x3-x2. Get the normal component for distance to line
30  const Vec3d& x0 = bodies.getPosition(m_particles[0]);
31  const Vec3d& x1 = bodies.getPosition(m_particles[1]);
32  const Vec3d& x2 = bodies.getPosition(m_particles[2]);
33 
34  const Vec3d ab = x2 - x1;
35  const double length = ab.norm();
36  if (length == 0.0)
37  {
38  // There is no distance between the edge, can't do anything
39  c = 0.0;
40  return false;
41  }
42  const Vec3d dir1 = ab / length;
43 
44  // Project onto the line
45  const Vec3d diff = x0 - x1;
46  const double p = dir1.dot(diff);
47  if (p < 0.0 || p > length)
48  {
49  c = 0.0;
50  return false;
51  }
52 
53  // If contacting point near a boundary ignore constraint
55  {
56  const int maxId = ((1.0 - p) < p) ? 2 : 1;
57  if (bodies.getInvMass(m_particles[maxId]) == 0.0)
58  {
59  c = 0.0;
60  return false;
61  }
62  }
63 
64  // Remove tangent component to get normal
65  const Vec3d diff1 = diff - p * dir1;
66  const double l = diff1.norm();
67  if (l == 0.0)
68  {
69  // The point is on the line
70  c = 0.0;
71  return false;
72  }
73  const Vec3d n = diff1 / l;
74  const double u = p / length;
75 
76  dcdx[0] = -n;
77  dcdx[1] = (1.0 - u) * n;
78  dcdx[2] = u * n;
79 
80  c = l;
81 
82  return true;
83 }
84 } // 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 PbdParticleId &ptA1, const PbdParticleId &ptB1, const PbdParticleId &ptB2, double stiffnessA, double stiffnessB)
Initialize the constraint.
bool computeValueAndGradient(PbdState &bodies, double &c, std::vector< Vec3d > &dcdx) override
Compute value and gradient of constraint function.
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
Definition: imstkPbdBody.h:229