iMSTK
Interactive Medical Simulation Toolkit
imstkPbdEdgeEdgeConstraint.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 "imstkPbdEdgeEdgeConstraint.h"
8 
9 namespace imstk
10 {
11 void
13  const PbdParticleId& ptA1, const PbdParticleId& ptA2,
14  const PbdParticleId& ptB1, const PbdParticleId& ptB2,
15  double stiffnessA, double stiffnessB)
16 {
17  m_particles[0] = ptA1;
18  m_particles[1] = ptA2;
19  m_particles[2] = ptB1;
20  m_particles[3] = ptB2;
21 
22  m_stiffness[0] = stiffnessA;
23  m_stiffness[1] = stiffnessB;
24 }
25 
26 bool
28  double& c, std::vector<Vec3d>& dcdx)
29 {
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  const Vec3d& x3 = bodies.getPosition(m_particles[3]);
34 
35  const double a = (x3 - x2).dot(x1 - x0);
36  const double b = (x1 - x0).dot(x1 - x0);
37  const double cc = (x0 - x2).dot(x1 - x0);
38  const double d = (x3 - x2).dot(x3 - x2);
39  const double e = a;
40  const double f = (x0 - x2).dot(x3 - x2);
41 
42  const double det = a * e - d * b;
43  double s = 0.5;
44  double t = 0.5;
45  if (fabs(det) > 1e-12)
46  {
47  s = (cc * e - b * f) / det;
48  t = (cc * d - a * f) / det;
49  if (s < 0 || s > 1.0 || t < 0 || t > 1.0)
50  {
51  c = 0.0;
52  return false;
53  }
54  }
55 
56  // Two closest points on the line segments
57  const Vec3d P = x0 + t * (x1 - x0);
58  const Vec3d Q = x2 + s * (x3 - x2);
59 
60  // Distance between nearest points on line segments
61  Vec3d n = (Q - P);
62  const double l = n.norm();
63  n /= l;
64 
65  if (l <= 0.0)
66  {
67  c = 0.0;
68  return false;
69  }
70 
71  // A
72  dcdx[0] = (1 - t) * n;
73  dcdx[1] = t * n;
74  // B
75  dcdx[2] = -(1 - s) * n;
76  dcdx[3] = -s * n;
77 
78  c = l;
79 
80  return true;
81 }
82 } // namespace imstk
bool computeValueAndGradient(PbdState &bodies, double &c, std::vector< Vec3d > &dcdx) override
Compute value and gradient of constraint function.
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
void initConstraint(const PbdParticleId &ptA1, const PbdParticleId &ptA2, const PbdParticleId &ptB1, const PbdParticleId &ptB2, double stiffnessA, double stiffnessB)
Initialize constraint.
Compound Geometry.
Provides interface for accessing particles from a 2d array of PbdBody,Particles.
Definition: imstkPbdBody.h:229