Back

LocalMinDistance

sofa::component::collision::detection::intersection::LocalMinDistance
BaseProximityIntersection
Doc (from source)

A set of methods to compute (for constraint methods) if two primitives are close enough to consider they collide Intersection methods using proximities. Filters are added to limit the number of contacts. The following pairs of collision models are supported: - Cube/Cube - Sphere/Sphere - Sphere/Point - Point/Point - Line/Line - Line/Point - Line/Sphere - Triangle/Point - Triangle/Sphere - Ray/Triangle - Ray/Sphere The following pairs of collision models are ignored: - Triangle/Line - Triangle/Triangle - Ray/Point - Ray/Line

Abstract (AI generated)

`LocalMinDistance` detects proximities between geometric primitives for collision detection with filtering mechanisms to limit contact numbers based on local geometry configurations.

Metadata
module
Sofa.Component.Collision.Detection.Intersection
namespace
sofa::component::collision::detection::intersection
include
sofa/component/collision/detection/intersection/LocalMinDistance.h
inherits
  • BaseProximityIntersection
description

The LocalMinDistance component in the SOFA framework is designed to detect and compute proximities between various geometric primitives, which are essential for defining collision detection and contact forces. It implements intersection methods with filtering mechanisms that limit the number of contacts based on local geometry configurations around intersected primitives.

Mathematical Description:

The component supports different types of primitive pairs such as Cubes, Spheres, Points, Lines, Triangles, and Rays, while ignoring certain pairs like Triangle/Triangle and Ray/Point intersections. Below are the governing equations for some key operations:

  1. Proximity Test
  2. For each pair (e.g., Sphere-Sphere, Line-Line), a proximity test is performed by computing geometric distances between points on primitives.

  3. Contact Detection and Computation

  4. The contact detection involves checking if the distance between points of intersecting primitives is less than an alarm distance defined as:
    $$\text{alarmDist} = \mathcal{D}_a + d_1 + d_2,$$
    where $\mathcal{D}_a$ is the alarm distance from the current intersection settings and $d_1$, $d_2$ are individual contact distances of the primitives involved.

  5. Validity Filtering

  6. To filter out spurious contacts based on local geometry, a validity test is performed which checks if the detected proximity lies within a geometric cone defined around each primitive's normal or tangent vectors:
    $$\text{valid} = (\mathbf{n}_{mean} ullet \mathbf{PQ}) < - heta_{cone} || PQ.norm(),$$
    where $\theta_{cone}$ is the filtering angle and $\mathbf{PQ}$ is the vector between the points on the intersecting primitives.

Key Equations:

  • Point-Line Intersection: For a point $P$ and a line defined by points $A$ and $B$, the parametric coordinate along the line ($eta$) and its validity are determined as follows:
    $$\mathbf{AB} = B - A, \quad \mathbf{AP} = P - A,$$
$$eta = rac{ extbf{AP} ullet extbf{AB}}{ extbf{AB} ullet extbf{AB}},$$

if $0 < \beta < 1$ and the distance between point $P$ and line is within alarmDist, a contact is detected.

  • Sphere-Triangle Intersection: For a sphere with center $C$ and radius $r$, and a triangle defined by points $A$, $B$, and $C$, the parametric coordinates ($\alpha, \beta$) are computed to determine if they lie within the alarm distance:
    $$\mathbf{AB} = B - A, \quad \mathbf{AC} = C - A, \quad \mathbf{AP} = P - A,$$
$$egin{pmatrix} AB ullet AB & AB ullet AC \\ AB ullet AC & AC ullet AC \end{pmatrix} \begin{pmatrix}\alpha \\ \beta\end{pmatrix} = \begin{pmatrix}AP ullet AB \\ AP ullet AC\end{pmatrix},$$

if $0 < \alpha, \beta < 1$ and the distance between point on sphere and triangle is within alarmDist, a contact is detected.

Role in FEM Pipeline:

  • Collision Detection: This component primarily deals with collision detection by testing for proximities and computing contacts. It does not directly contribute to the governing equations such as mass matrix $M$, internal force vector $f_{int}$, or residual $R$; however, it indirectly affects these through constraint handling.

  • Constraint Handling: The detected contacts are used in enforcing constraints during the nonlinear solve step of the simulation pipeline. For example, if two primitives collide, this component determines the contact points and normals which are then used to enforce non-penetration conditions via Lagrange multipliers or penalty methods.

Numerical Methods:

  • Proximity Tests: The proximity tests employ simple geometric operations such as distance calculations and dot products to determine if primitives are within a specified alarm distance.

  • Validity Filters: Validity filters use local geometry information (normals, tangents) to ensure that only physically relevant contacts are considered. This involves computing the average normal or tangent vectors around the intersection point and checking if the detected proximity lies within an angular cone defined by these vectors.

Variational Framework Integration:

While LocalMinDistance itself is not directly part of the variational formulation, it supports a crucial step in enforcing physical consistency by accurately detecting contacts. This ensures that constraints such as non-penetration are properly modeled and enforced during nonlinear solution steps, thereby preserving the overall physical fidelity of deformable body simulations.

In summary, LocalMinDistance provides essential collision detection mechanisms with filtering to ensure accurate contact point determination, playing a key role in maintaining physical consistency in SOFA's simulation framework.

Data Fields
NameTypeDefaultHelp
d_filterIntersection bool Activate LMD filter
d_angleCone double Filtering cone extension angle
d_coneFactor double Factor for filtering cone angle computation
d_useLMDFilters bool Use external cone computation
Methods
void init () virtual
bool testIntersection (collision::geometry::Cube & , collision::geometry::Cube & , const core::collision::Intersection * currentIntersection) virtual
bool testIntersection (collision::geometry::Point & , collision::geometry::Point & , const core::collision::Intersection * currentIntersection)
bool testIntersection (collision::geometry::Sphere & , collision::geometry::Point & , const core::collision::Intersection * currentIntersection)
bool testIntersection (collision::geometry::Sphere & , collision::geometry::Sphere & , const core::collision::Intersection * currentIntersection) virtual
bool testIntersection (collision::geometry::Line & , collision::geometry::Point & , const core::collision::Intersection * currentIntersection)
bool testIntersection (collision::geometry::Line & , collision::geometry::Sphere & , const core::collision::Intersection * currentIntersection)
bool testIntersection (collision::geometry::Line & , collision::geometry::Line & , const core::collision::Intersection * currentIntersection)
bool testIntersection (collision::geometry::Triangle & , collision::geometry::Point & , const core::collision::Intersection * currentIntersection)
bool testIntersection (collision::geometry::Triangle & , collision::geometry::Sphere & , const core::collision::Intersection * currentIntersection)
bool testIntersection (collision::geometry::Ray & , collision::geometry::Sphere & , const core::collision::Intersection * currentIntersection)
bool testIntersection (collision::geometry::Ray & , collision::geometry::Triangle & , const core::collision::Intersection * currentIntersection)
int computeIntersection (collision::geometry::Cube & , collision::geometry::Cube & , OutputVector * , const core::collision::Intersection * currentIntersection) virtual
int computeIntersection (collision::geometry::Point & , collision::geometry::Point & , OutputVector * , const core::collision::Intersection * currentIntersection)
int computeIntersection (collision::geometry::Sphere & , collision::geometry::Point & , OutputVector * , const core::collision::Intersection * currentIntersection)
int computeIntersection (collision::geometry::Sphere & , collision::geometry::Sphere & , OutputVector * , const core::collision::Intersection * currentIntersection) virtual
int computeIntersection (collision::geometry::Line & , collision::geometry::Point & , OutputVector * , const core::collision::Intersection * currentIntersection)
int computeIntersection (collision::geometry::Line & , collision::geometry::Sphere & , OutputVector * , const core::collision::Intersection * currentIntersection)
int computeIntersection (collision::geometry::Line & , collision::geometry::Line & , OutputVector * , const core::collision::Intersection * currentIntersection)
int computeIntersection (collision::geometry::Triangle & , collision::geometry::Point & , OutputVector * , const core::collision::Intersection * currentIntersection)
int computeIntersection (collision::geometry::Triangle & , collision::geometry::Sphere & , OutputVector * , const core::collision::Intersection * currentIntersection)
int computeIntersection (collision::geometry::Ray & , collision::geometry::Sphere & , OutputVector * , const core::collision::Intersection * currentIntersection)
int computeIntersection (collision::geometry::Ray & , collision::geometry::Triangle & , OutputVector * , const core::collision::Intersection * currentIntersection)
bool testValidity (collision::geometry::Sphere & , const type::Vec3 & )
bool testValidity (collision::geometry::Point & , const type::Vec3 & )
bool testValidity (collision::geometry::Line & , const type::Vec3 & )
bool testValidity (collision::geometry::Triangle & , const type::Vec3 & )
{
  "name": "LocalMinDistance",
  "namespace": "sofa::component::collision::detection::intersection",
  "module": "Sofa.Component.Collision.Detection.Intersection",
  "include": "sofa/component/collision/detection/intersection/LocalMinDistance.h",
  "doc": "A set of methods to compute (for constraint methods) if two primitives are close enough to consider they collide\n\nIntersection methods using proximities. Filters are added to limit the number of contacts.\nThe following pairs of collision models are supported:\n- Cube/Cube\n- Sphere/Sphere\n- Sphere/Point\n- Point/Point\n- Line/Line\n- Line/Point\n- Line/Sphere\n- Triangle/Point\n- Triangle/Sphere\n- Ray/Triangle\n- Ray/Sphere\nThe following pairs of collision models are ignored:\n- Triangle/Line\n- Triangle/Triangle\n- Ray/Point\n- Ray/Line",
  "inherits": [
    "BaseProximityIntersection"
  ],
  "templates": [],
  "data_fields": [
    {
      "name": "d_filterIntersection",
      "type": "bool",
      "xmlname": "filterIntersection",
      "help": "Activate LMD filter"
    },
    {
      "name": "d_angleCone",
      "type": "double",
      "xmlname": "angleCone",
      "help": "Filtering cone extension angle"
    },
    {
      "name": "d_coneFactor",
      "type": "double",
      "xmlname": "coneFactor",
      "help": "Factor for filtering cone angle computation"
    },
    {
      "name": "d_useLMDFilters",
      "type": "bool",
      "xmlname": "useLMDFilters",
      "help": "Use external cone computation"
    }
  ],
  "links": [],
  "methods": [
    {
      "name": "init",
      "return_type": "void",
      "params": [],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Cube &"
        },
        {
          "name": "",
          "type": "collision::geometry::Cube &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Line &"
        },
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Line &"
        },
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Line &"
        },
        {
          "name": "",
          "type": "collision::geometry::Line &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Triangle &"
        },
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Triangle &"
        },
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Ray &"
        },
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testIntersection",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Ray &"
        },
        {
          "name": "",
          "type": "collision::geometry::Triangle &"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Cube &"
        },
        {
          "name": "",
          "type": "collision::geometry::Cube &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": true,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Line &"
        },
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Line &"
        },
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Line &"
        },
        {
          "name": "",
          "type": "collision::geometry::Line &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Triangle &"
        },
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Triangle &"
        },
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Ray &"
        },
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "computeIntersection",
      "return_type": "int",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Ray &"
        },
        {
          "name": "",
          "type": "collision::geometry::Triangle &"
        },
        {
          "name": "",
          "type": "OutputVector *"
        },
        {
          "name": "currentIntersection",
          "type": "const core::collision::Intersection *"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testValidity",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Sphere &"
        },
        {
          "name": "",
          "type": "const type::Vec3 &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testValidity",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Point &"
        },
        {
          "name": "",
          "type": "const type::Vec3 &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testValidity",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Line &"
        },
        {
          "name": "",
          "type": "const type::Vec3 &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    },
    {
      "name": "testValidity",
      "return_type": "bool",
      "params": [
        {
          "name": "",
          "type": "collision::geometry::Triangle &"
        },
        {
          "name": "",
          "type": "const type::Vec3 &"
        }
      ],
      "is_virtual": false,
      "is_pure_virtual": false,
      "is_static": false,
      "access": "public"
    }
  ],
  "description": "Intersection methods using proximities with filters to limit the number of contacts.",
  "parameters": [
    {
      "name": "filterIntersection",
      "description": "Activate Local Min Distance (LMD) filter",
      "type": "bool"
    },
    {
      "name": "angleCone",
      "description": "Filtering cone extension angle",
      "type": "double"
    },
    {
      "name": "coneFactor",
      "description": "Factor for filtering cone angle computation",
      "type": "double"
    },
    {
      "name": "useLMDFilters",
      "description": "Use external cone computation for LMD filters",
      "type": "bool"
    }
  ],
  "supported_collision_pairs": [
    {
      "pair": "Cube/Cube"
    },
    {
      "pair": "Sphere/Sphere"
    },
    {
      "pair": "Sphere/Point"
    },
    {
      "pair": "Point/Point"
    },
    {
      "pair": "Line/Line"
    },
    {
      "pair": "Line/Point"
    },
    {
      "pair": "Line/Sphere"
    },
    {
      "pair": "Triangle/Point"
    },
    {
      "pair": "Triangle/Sphere"
    },
    {
      "pair": "Ray/Triangle"
    },
    {
      "pair": "Ray/Sphere"
    }
  ],
  "ignored_collision_pairs": [
    {
      "pair": "Triangle/Line"
    },
    {
      "pair": "Triangle/Triangle"
    },
    {
      "pair": "Ray/Point"
    },
    {
      "pair": "Ray/Line"
    }
  ],
  "maths": "The `LocalMinDistance` component in the SOFA framework is designed to detect and compute proximities between various geometric primitives, which are essential for defining collision detection and contact forces. It implements intersection methods with filtering mechanisms that limit the number of contacts based on local geometry configurations around intersected primitives.\n\n### Mathematical Description:\n\nThe component supports different types of primitive pairs such as Cubes, Spheres, Points, Lines, Triangles, and Rays, while ignoring certain pairs like Triangle/Triangle and Ray/Point intersections. Below are the governing equations for some key operations:\n\n1. **Proximity Test**\n   - For each pair (e.g., Sphere-Sphere, Line-Line), a proximity test is performed by computing geometric distances between points on primitives.\n   \n2. **Contact Detection and Computation**\n   - The contact detection involves checking if the distance between points of intersecting primitives is less than an alarm distance defined as:\n     \\[\\text{alarmDist} = \\mathcal{D}_a + d_1 + d_2,\\]\n   where $\\mathcal{D}_a$ is the alarm distance from the current intersection settings and $d_1$, $d_2$ are individual contact distances of the primitives involved.\n\n3. **Validity Filtering**\n   - To filter out spurious contacts based on local geometry, a validity test is performed which checks if the detected proximity lies within a geometric cone defined around each primitive's normal or tangent vectors:\n     \\[\\text{valid} = (\\mathbf{n}_{mean} \bullet \\mathbf{PQ}) < -\theta_{cone} || PQ.norm(),\\]\n   where $\\theta_{cone}$ is the filtering angle and $\\mathbf{PQ}$ is the vector between the points on the intersecting primitives.\n\n### Key Equations:\n- **Point-Line Intersection:** For a point $P$ and a line defined by points $A$ and $B$, the parametric coordinate along the line ($\beta$) and its validity are determined as follows:\n  \\[\\mathbf{AB} = B - A, \\quad \\mathbf{AP} = P - A,\\]\n  \\[\beta = \frac{\textbf{AP} \bullet \textbf{AB}}{\textbf{AB} \bullet \textbf{AB}},\\]\n  if $0 < \\beta < 1$ and the distance between point $P$ and line is within alarmDist, a contact is detected.\n\n- **Sphere-Triangle Intersection:** For a sphere with center $C$ and radius $r$, and a triangle defined by points $A$, $B$, and $C$, the parametric coordinates ($\\alpha, \\beta$) are computed to determine if they lie within the alarm distance:\n  \\[\\mathbf{AB} = B - A, \\quad \\mathbf{AC} = C - A, \\quad \\mathbf{AP} = P - A,\\]\n  \\[\begin{pmatrix}\n    AB \bullet AB & AB \bullet AC \\\\ \n    AB \bullet AC & AC \bullet AC\n   \\end{pmatrix}\n   \\begin{pmatrix}\\alpha \\\\ \\beta\\end{pmatrix} =\n   \\begin{pmatrix}AP \bullet AB \\\\ AP \bullet AC\\end{pmatrix},\\]\n  if $0 < \\alpha, \\beta < 1$ and the distance between point on sphere and triangle is within alarmDist, a contact is detected.\n\n### Role in FEM Pipeline:\n- **Collision Detection:** This component primarily deals with collision detection by testing for proximities and computing contacts. It does not directly contribute to the governing equations such as mass matrix $M$, internal force vector $f_{int}$, or residual $R$; however, it indirectly affects these through constraint handling.\n\n- **Constraint Handling:** The detected contacts are used in enforcing constraints during the nonlinear solve step of the simulation pipeline. For example, if two primitives collide, this component determines the contact points and normals which are then used to enforce non-penetration conditions via Lagrange multipliers or penalty methods.\n\n### Numerical Methods:\n- **Proximity Tests:** The proximity tests employ simple geometric operations such as distance calculations and dot products to determine if primitives are within a specified alarm distance.\n\n- **Validity Filters:** Validity filters use local geometry information (normals, tangents) to ensure that only physically relevant contacts are considered. This involves computing the average normal or tangent vectors around the intersection point and checking if the detected proximity lies within an angular cone defined by these vectors.\n\n### Variational Framework Integration:\nWhile `LocalMinDistance` itself is not directly part of the variational formulation, it supports a crucial step in enforcing physical consistency by accurately detecting contacts. This ensures that constraints such as non-penetration are properly modeled and enforced during nonlinear solution steps, thereby preserving the overall physical fidelity of deformable body simulations.\n\nIn summary, `LocalMinDistance` provides essential collision detection mechanisms with filtering to ensure accurate contact point determination, playing a key role in maintaining physical consistency in SOFA's simulation framework.",
  "abstract": "`LocalMinDistance` detects proximities between geometric primitives for collision detection with filtering mechanisms to limit contact numbers based on local geometry configurations.",
  "sheet": "# LocalMinDistance\n\n## Overview\nThe `LocalMinDistance` component is designed to detect proximities and compute contacts between various geometric primitives (Cubes, Spheres, Points, Lines, Triangles, Rays) for collision detection. It includes filtering mechanisms to limit the number of contacts based on local geometry configurations.\n\n## Parameters and Data\n- **filterIntersection (`bool`)**: Activates LMD filter.\n- **angleCone (`double`)**: Filtering cone extension angle.\n- **coneFactor (`double`)**: Factor for filtering cone angle computation.\n- **useLMDFilters (`bool`)**: Uses external cone computation.\n\n## Dependencies and Connections\nThis component typically requires other collision models (e.g., Cube, Sphere, Point) to function. It fits into the scene graph by connecting with these models to perform proximity tests and contact computations."
}