Source code for pyrobopath.collision_detection.simple_collision_models
from __future__ import annotations
import numpy as np
from pyrobopath.tools.types import NDArray
from pyrobopath.tools.geometry import orientation, on_segment
from .collision_model import CollisionModel
[docs]
class LineCollisionModel(CollisionModel):
def __init__(self, base: NDArray):
super().__init__()
self._base = base
@property
def base(self) -> NDArray:
return self._base
@base.setter
def base(self, value: NDArray):
self._base = value
def in_collision(self, other: CollisionModel) -> bool:
if not isinstance(other, LineCollisionModel):
raise NotImplementedError
p1, q1 = np.round(self.base, 5), np.round(self.translation, 5)
p2, q2 = np.round(other.base, 5), np.round(other.translation, 5)
o1 = orientation(p1, q1, p2)
o2 = orientation(p1, q1, q2)
o3 = orientation(p2, q2, p1)
o4 = orientation(p2, q2, q1)
# General case
if (o1 != o2) and (o3 != o4):
return True
# Special Cases
# p1, q1 and p2 are collinear and p2 lies on segment p1q1
if (o1 == 0) and on_segment(p1, p2, q1):
return True
# p1, q1 and q2 are collinear and q2 lies on segment p1q1
if (o2 == 0) and on_segment(p1, q2, q1):
return True
# p2, q2 and p1 are collinear and p1 lies on segment p2q2
if (o3 == 0) and on_segment(p2, p1, q2):
return True
# p2, q2 and q1 are collinear and q1 lies on segment p2q2
if (o4 == 0) and on_segment(p2, q1, q2):
return True
return False
[docs]
class LollipopCollisionModel(LineCollisionModel):
def __init__(self, base: NDArray, radius: float):
super().__init__(base)
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
self._radius = value
def in_collision(self, other: CollisionModel) -> bool:
if not isinstance(other, LollipopCollisionModel):
raise NotImplementedError
if super().in_collision(other):
return True
tip_to_tip = np.linalg.norm(self.translation - other.translation)
return bool(tip_to_tip < (self.radius + other.radius))