def compute_minimal_distance_between_circles(): """ compute the minimal distance between 2 circles here the minimal distance overlaps the intersection of the circles the points are rendered to indicate the locations """ # required for precise rendering of the circles display.Context.SetDeviationCoefficient(0.0001) L = gp_Pnt(4, 10, 0) M = gp_Pnt(10, 16, 0) Laxis = gp_Ax2() Maxis = gp_Ax2() Laxis.SetLocation(L) Maxis.SetLocation(M) r1 = 12.0 r2 = 15.0 Lcircle = gp_Circ(Laxis, r1) Mcircle = gp_Circ(Maxis, r2) l_circle, m_circle = make_edge(Lcircle), make_edge(Mcircle) display.DisplayShape([l_circle, m_circle]) # compute the minimal distance between 2 circles # the minimal distance here matches the intersection of the circles dss = BRepExtrema_DistShapeShape(l_circle, m_circle) print("intersection parameters on l_circle:", [dss.ParOnEdgeS1(i) for i in range(1, dss.NbSolution() + 1)]) print("intersection parameters on m_circle:", [dss.ParOnEdgeS2(i) for i in range(1, dss.NbSolution() + 1)]) for i in range(1, dss.NbSolution() + 1): pnt = dss.PointOnShape1(i) display.DisplayShape(make_vertex(pnt))
class DistanceShapeToShape(object): """ Calculate minimum distance between two shapes. If geometry is provided it will be converted to a shape. :param shape1: The first shape or geometry. :type shape1: afem.topology.entities.Shape or afem.geometry.entities.Geometry :param shape2: The second or geometry. :type shape2: afem.topology.entities.Shape or afem.geometry.entities.Geometry Usage: >>> from afem.topology import * >>> v1 = VertexByPoint((0., 0., 0.)).vertex >>> v2 = VertexByPoint((10., 0., 0.)).vertex >>> tool = DistanceShapeToShape(v1, v2) >>> tool.nsol 1 >>> tool.dmin 10.0 """ def __init__(self, shape1, shape2, deflection=1.0e-7): shape1 = Shape.to_shape(shape1) shape2 = Shape.to_shape(shape2) self._tool = BRepExtrema_DistShapeShape(shape1.object, shape2.object, deflection, Extrema_ExtFlag_MIN) @property def is_done(self): """ :return: *True* if algorithm is done, *False* if not. :rtype: bool """ return self._tool.IsDone() @property def nsol(self): """ :return: The number of solutions satisfying the minimum distance. :rtype: """ return self._tool.NbSolution() @property def dmin(self): """ :return: The minimum distance. :rtype: float """ return self._tool.Value() @property def inner_solution(self): """ :return: *True* if one of the shapes is a solid and the other is completely or partially inside the solid. :rtype: bool """ return self._tool.InnerSolution() def point_on_shape1(self, n=1): """ The point for the *n-th* solution on the first shape. :param int n: The index. :return: The point. :rtype: afem.geometry.entities.Point """ gp_pnt = self._tool.PointOnShape1(n) return Point(gp_pnt.X(), gp_pnt.Y(), gp_pnt.Z()) def point_on_shape2(self, n=1): """ The point for the *n-th* solution on the second shape. :param int n: The index. :return: The point. :rtype: afem.geometry.entities.Point """ gp_pnt = self._tool.PointOnShape2(n) return Point(gp_pnt.X(), gp_pnt.Y(), gp_pnt.Z()) def support_type_shape1(self, n=1): """ The type of support for the *n-th* solution on the first shape. :param int n: The index. :return: The support type. :rtype: OCCT.BRepExtrema.BRepExtrema_SupportType """ return self._tool.SupportTypeShape1(n) def is_vertex_shape1(self, n=1): """ Check if support type is a vertex for the first shape. :param int n: The index. :return: *True* if a vertex, *False* otherwise. :rtype: bool """ return self.support_type_shape1(n) == BRepExtrema_IsVertex def is_on_edge_shape1(self, n=1): """ Check if support type is on an edge for the first shape. :param int n: The index. :return: *True* if on an edge, *False* otherwise. :rtype: bool """ return self.support_type_shape1(n) == BRepExtrema_IsOnEdge def is_in_face_shape1(self, n=1): """ Check if support type is in a face for the first shape. :param int n: The index. :return: *True* if in a face, *False* otherwise. :rtype: bool """ return self.support_type_shape1(n) == BRepExtrema_IsInFace def support_type_shape2(self, n=1): """ The type of support for the *n-th* solution on the second shape. :param int n: The index. :return: The support type. :rtype: OCCT.BRepExtrema.BRepExtrema_SupportType """ return self._tool.SupportTypeShape2(n) def is_vertex_shape2(self, n=1): """ Check if support type is a vertex for the second shape. :param int n: The index. :return: *True* if a vertex, *False* otherwise. :rtype: bool """ return self.support_type_shape2(n) == BRepExtrema_IsVertex def is_on_edge_shape2(self, n=1): """ Check if support type is on an edge for the second shape. :param int n: The index. :return: *True* if on an edge, *False* otherwise. :rtype: bool """ return self.support_type_shape2(n) == BRepExtrema_IsOnEdge def is_in_face_shape2(self, n=1): """ Check if support type is in a face for the second shape. :param int n: The index. :return: *True* if in a face, *False* otherwise. :rtype: bool """ return self.support_type_shape2(n) == BRepExtrema_IsInFace def support_on_shape1(self, n=1): """ Get the shape where the *n-th* solution is on the first shape. :param int n: The index. :return: The support shape. :rtype: afem.topology.entities.Shape """ return Shape.wrap(self._tool.SupportOnShape1(n)) def support_on_shape2(self, n=1): """ Get the shape where the *n-th* solution is on the second shape. :param int n: The index. :return: The support shape. :rtype: afem.topology.entities.Shape """ return Shape.wrap(self._tool.SupportOnShape2(n)) def par_on_edge_shape1(self, n=1): """ Get the parameter of the *n-th* solution if it is on an edge of the first shape. :param int n: The index. :return: The parameter. :rtype: float """ return self._tool.ParOnEdgeS1(n, 0.) def par_on_edge_shape2(self, n=1): """ Get the parameter of the *n-th* solution if it is on an edge of the second shape. :param int n: The index. :return: The parameter. :rtype: float """ return self._tool.ParOnEdgeS2(n, 0.) def par_on_face_shape1(self, n=1): """ Get the parameters of the *n-th* solution if it is in a face of the first shape. :param int n: The index. :return: The parameters. :rtype: tuple(float, float) """ return self._tool.ParOnFaceS1(n, 0., 0.) def par_on_face_shape2(self, n=1): """ Get the parameters of the *n-th* solution if it is in a face of the second shape. :param int n: The index. :return: The parameters. :rtype: tuple(float, float) """ return self._tool.ParOnFaceS2(n, 0., 0.) def normal_on_shape1(self, n=1): """ Get a unit normal on the first shape where the *n-th* solution is located if it is in a face. :param int n: The index. :return: The unit normal. :rtype: afem.geometry.entities.Direction :raise ValueError: If the solution is not in a face. """ if not self.is_in_face_shape1(n): raise ValueError('The solution is not in a face.') face = self.support_on_shape1(n) u, v = self.par_on_face_shape1(n) adp_srf = FaceAdaptorSurface.by_face(face) return Direction.by_vector(adp_srf.norm(u, v)) def normal_on_shape2(self, n=1): """ Get a unit normal on the second shape where the *n-th* solution is located if it is in a face. :param int n: The index. :return: The unit normal. :rtype: afem.geometry.entities.Direction :raise ValueError: If the solution is not in a face. """ if not self.is_in_face_shape2(n): raise ValueError('The solution is not in a face.') face = self.support_on_shape2(n) u, v = self.par_on_face_shape2(n) adp_srf = FaceAdaptorSurface.by_face(face) return Direction.by_vector(adp_srf.norm(u, v))