Continuous Collision Detection

ipctk.is_step_collision_free(mesh: ipctk.CollisionMesh, vertices_t0: typing.Annotated[numpy.typing.NDArray[numpy.float64], "[m, n]", "flags.f_contiguous"], vertices_t1: typing.Annotated[numpy.typing.NDArray[numpy.float64], "[m, n]", "flags.f_contiguous"], min_distance: typing.SupportsFloat = 0.0, broad_phase: ipctk.BroadPhase = None, narrow_phase_ccd: ipctk.NarrowPhaseCCD = <ipctk.TightInclusionCCD object at 0x7f12d0c565b0>) bool

Determine if the step is collision free.

Note

Assumes the trajectory is linear.

Parameters:
mesh

The collision mesh.

vertices_t0

Surface vertex vertices at start as rows of a matrix.

vertices_t1

Surface vertex vertices at end as rows of a matrix.

min_distance

The minimum distance allowable between any two elements.

broad_phase

Broad phase to use.

narrow_phase_ccd

The narrow phase CCD algorithm to use.

Returns:

True if <b>any</b> collisions occur.

ipctk.compute_collision_free_stepsize(mesh: ipctk.CollisionMesh, vertices_t0: typing.Annotated[numpy.typing.NDArray[numpy.float64], "[m, n]", "flags.f_contiguous"], vertices_t1: typing.Annotated[numpy.typing.NDArray[numpy.float64], "[m, n]", "flags.f_contiguous"], min_distance: typing.SupportsFloat = 0.0, broad_phase: ipctk.BroadPhase = None, narrow_phase_ccd: ipctk.NarrowPhaseCCD = <ipctk.TightInclusionCCD object at 0x7f12bfc294b0>) float

Computes a maximal step size that is collision free.

Note

Assumes the trajectory is linear. When using SweepAndTiniestQueue broad phase, tolerance and max_iterations are extracted from TightInclusionCCD if provided, otherwise defaults are used.

Parameters:
mesh

The collision mesh.

vertices_t0

Vertex vertices at start as rows of a matrix. Assumes vertices_t0 is intersection free.

vertices_t1

Surface vertex vertices at end as rows of a matrix.

min_distance

The minimum distance allowable between any two elements.

broad_phase

Broad phase to use.

narrow_phase_ccd

The narrow phase CCD algorithm to use.

Returns:

A step-size \(\in [0, 1]\) that is collision free. A value of 1.0 if a full step and 0.0 is no step.

Narrow Phase CCD

class ipctk.NarrowPhaseCCD

Bases: pybind11_object

Public Methods:

__init__(self)

point_point_ccd(self, p0_t0, p1_t0, p0_t1, p1_t1)

point_edge_ccd(self, p_t0, e0_t0, e1_t0, ...)

point_triangle_ccd(self, p_t0, t0_t0, t1_t0, ...)

edge_edge_ccd(self, ea0_t0, ea1_t0, eb0_t0, ...)

Inherited from pybind11_object

Private Methods:

_pybind11_conduit_v1_


__annotations__ = {}
__init__(self)
__module__ = 'ipctk'
_pybind11_conduit_v1_()
edge_edge_ccd(self, ea0_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], ea1_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], eb0_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], eb1_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], ea0_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], ea1_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], eb0_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], eb1_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], min_distance: SupportsFloat = 0.0, tmax: SupportsFloat = 1.0) tuple[bool, float]
point_edge_ccd(self, p_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], e0_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], e1_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], p_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], e0_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], e1_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], min_distance: SupportsFloat = 0.0, tmax: SupportsFloat = 1.0) tuple[bool, float]
point_point_ccd(self, p0_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], p1_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], p0_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], p1_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], min_distance: SupportsFloat = 0.0, tmax: SupportsFloat = 1.0) tuple[bool, float]
point_triangle_ccd(self, p_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], t0_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], t1_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], t2_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], p_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], t0_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], t1_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], t2_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[3, 1]'], min_distance: SupportsFloat = 0.0, tmax: SupportsFloat = 1.0) tuple[bool, float]

Tight Inclusion CCD

class ipctk.TightInclusionCCD

Bases: NarrowPhaseCCD

Public Data Attributes:

DEFAULT_TOLERANCE

DEFAULT_MAX_ITERATIONS

DEFAULT_CONSERVATIVE_RESCALING

SMALL_TOI

tolerance

Solver tolerance.

max_iterations

Maximum number of iterations.

conservative_rescaling

Conservative rescaling of the time of impact.

Public Methods:

__init__(self[, tolerance, max_iterations, ...])

Construct a new AdditiveCCD object.

Inherited from NarrowPhaseCCD

__init__(self)

point_point_ccd(self, p0_t0, p1_t0, p0_t1, p1_t1)

point_edge_ccd(self, p_t0, e0_t0, e1_t0, ...)

point_triangle_ccd(self, p_t0, t0_t0, t1_t0, ...)

edge_edge_ccd(self, ea0_t0, ea1_t0, eb0_t0, ...)

Inherited from pybind11_object

DEFAULT_CONSERVATIVE_RESCALING = 0.8
DEFAULT_MAX_ITERATIONS = 10000000
DEFAULT_TOLERANCE = 1e-06
SMALL_TOI = 1e-06
__annotations__ = {}
__init__(self, tolerance: SupportsFloat = 1e-06, max_iterations: SupportsInt = 10000000, conservative_rescaling: SupportsFloat = 0.8)

Construct a new AdditiveCCD object.

Parameters:
conservative_rescaling: SupportsFloat = 0.8

The conservative rescaling of the time of impact.

__module__ = 'ipctk'
_pybind11_conduit_v1_()
property conservative_rescaling : float

Conservative rescaling of the time of impact.

property max_iterations : int

Maximum number of iterations.

property tolerance : float

Solver tolerance.

Additive CCD

class ipctk.AdditiveCCD

Bases: NarrowPhaseCCD

Public Data Attributes:

DEFAULT_CONSERVATIVE_RESCALING

conservative_rescaling

The conservative rescaling value used to avoid taking steps exactly to impact.

Public Methods:

__init__(self[, max_iterations, ...])

Construct a new AdditiveCCD object.

Inherited from NarrowPhaseCCD

__init__(self)

point_point_ccd(self, p0_t0, p1_t0, p0_t1, p1_t1)

point_edge_ccd(self, p_t0, e0_t0, e1_t0, ...)

point_triangle_ccd(self, p_t0, t0_t0, t1_t0, ...)

edge_edge_ccd(self, ea0_t0, ea1_t0, eb0_t0, ...)

Inherited from pybind11_object

DEFAULT_CONSERVATIVE_RESCALING = 0.9
__annotations__ = {}
__init__(self, max_iterations: SupportsFloat = 10000000, conservative_rescaling: SupportsFloat = 0.9)

Construct a new AdditiveCCD object.

Parameters:
conservative_rescaling: SupportsFloat = 0.9

The conservative rescaling of the time of impact.

__module__ = 'ipctk'
_pybind11_conduit_v1_()
property conservative_rescaling : float

The conservative rescaling value used to avoid taking steps exactly to impact.

Inexact CCD

Note

This method is disabled by default. To enable it, set the IPC_TOOLKIT_WITH_INEXACT_CCD CMake option to ON.

ipctk.inexact_point_edge_ccd_2D(p_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]'], e0_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]'], e1_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]'], p_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]'], e0_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]'], e1_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]'], conservative_rescaling: SupportsFloat) tuple[bool, float]

Inexact continuous collision detection between a point and an edge in 2D.

Parameters:
p_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]']

Initial position of the point

e0_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]']

Initial position of the first endpoint of the edge

e1_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]']

Initial position of the second endpoint of the edge

p_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]']

Final position of the point

e0_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]']

Final position of the first endpoint of the edge

e1_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[2, 1]']

Final position of the second endpoint of the edge

conservative_rescaling: SupportsFloat

Conservative rescaling of the time of impact

Returns:

True if a collision was detected, false otherwise. Output time of impact

Return type:

Tuple of

Nonlinear CCD

class ipctk.NonlinearTrajectory

Bases: pybind11_object

Public Methods:

__init__(self)

__call__(self, t)

Compute the point's position at time t

max_distance_from_linear(self, t0, t1)

Compute the maximum distance from the nonlinear trajectory to a linearized trajectory

Inherited from pybind11_object

Private Methods:

_pybind11_conduit_v1_


__annotations__ = {}
__call__(self, t: SupportsFloat) Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

Compute the point’s position at time t

__init__(self)
__module__ = 'ipctk'
_pybind11_conduit_v1_()
max_distance_from_linear(self, t0: SupportsFloat, t1: SupportsFloat) float

Compute the maximum distance from the nonlinear trajectory to a linearized trajectory

Parameters:
t0: SupportsFloat

Start time of the trajectory

t1: SupportsFloat

End time of the trajectory

class ipctk.IntervalNonlinearTrajectory

Bases: NonlinearTrajectory

Public Methods:

__init__(self)

__call__(*args, **kwargs)

Overloaded function.

max_distance_from_linear(self, t0, t1)

Compute the maximum distance from the nonlinear trajectory to a linearized trajectory

Inherited from NonlinearTrajectory

__init__(self)

__call__(self, t)

Compute the point's position at time t

max_distance_from_linear(self, t0, t1)

Compute the maximum distance from the nonlinear trajectory to a linearized trajectory

Inherited from pybind11_object

__annotations__ = {}
__call__(*args, **kwargs)

Overloaded function.

  1. __call__(self: ipctk.IntervalNonlinearTrajectory, t: typing.SupportsFloat) -> typing.Annotated[numpy.typing.NDArray[numpy.float64], “[m, 1]”]

Compute the point’s position at time t

  1. __call__(self: ipctk.IntervalNonlinearTrajectory, t: filib::Interval) -> typing.Annotated[numpy.typing.NDArray[filib::Interval], “[m, 1]”]

Compute the point’s position over a time interval t

__init__(self)
__module__ = 'ipctk'
_pybind11_conduit_v1_()
max_distance_from_linear(self, t0: SupportsFloat, t1: SupportsFloat) float

Compute the maximum distance from the nonlinear trajectory to a linearized trajectory

Note

This uses interval arithmetic to compute the maximum distance. If you know a tighter bound on the maximum distance, it is recommended to override this function.

Parameters:
t0: SupportsFloat

Start time of the trajectory

t1: SupportsFloat

End time of the trajectory

Miscellaneous

ipctk.point_static_plane_ccd(p_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], p_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], plane_origin: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], plane_normal: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]'], conservative_rescaling: SupportsFloat = 0.8) tuple[bool, float]

Compute the time of impact between a point and a static plane in 3D using continuous collision detection.

Parameters:
p_t0: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

The initial position of the point.

p_t1: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

The final position of the point.

plane_origin: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

The origin of the plane.

plane_normal: Annotated[numpy.typing.NDArray[numpy.float64], '[m, 1]']

The normal of the plane.

conservative_rescaling: SupportsFloat = 0.8

Conservative rescaling of the time of impact.

Returns:

True if a collision was detected, false otherwise. Output time of impact

Return type:

Tuple of