def get_line_collision_point(line1, line2): p1, p2 = line1 p3, p4 = line2 """ returns collision between 2 lines defined by 2 points """ a1, b1, d1 = line_eq_calculus(p1, p2) a2, b2, d2 = line_eq_calculus(p3, p4) # == a, b, c, d = (a1, a2), (b1, b2), p3, (d1, d2) det_a_b = float(det(a, b)) # == if is_same(abs(det_a_b), 0.0): # if abs(det_a_b) == 0. : if is_same(a1 * p3[0] + b1 * p3[1], d1): # Tous les cas qui suivent sont equivalents : if is_on_segment(p3, p4, p1): return p1 elif is_on_segment(p3, p4, p2): return p2 elif is_on_segment(p1, p2, p3): return p3 elif is_on_segment(p1, p2, p4): return p4 return None else: x = det(d, b) / det_a_b y = det(a, d) / det_a_b return (x, y)
def actual_intersection(segments, i, j): segment = segments[i] other_segment = segments[j] if is_same(dot_product(points_diff(*segment), points_diff(*other_segment)), 0.0): return False for index1, p1 in enumerate(segment): for index2, p2 in enumerate(other_segment): if is_same(p1, p2): segment1 = segments[i - 1][index1], segments[(i + 1) % len(segments)][index1] segment2 = segments[j - 1][index2], segments[(j + 1) % len(segments)][index2] if have_common_point(segment1, segment2): return False if not segments_are_intersecting(segment1, segment2): return False # == if index1 == 0: connected_segment1 = segments[i - 1] else: connected_segment1 = segments[(i + 1) % len(segments)] if index2 == 0: connected_segment2 = segments[j - 1] else: connected_segment2 = segments[(j + 1) % len(segments)] if is_same( cross_product(points_diff(*connected_segment1), points_diff(*other_segment)), 0.0 ) or is_same(cross_product(points_diff(*connected_segment2), points_diff(*segment)), 0.0): return False center = p1 if _is_in_angle(segment1[0], center, segment1[1], segment2[0]) == _is_in_angle( segment1[0], center, segment1[1], segment2[1] ): return False for index1, p1 in enumerate(segment): if is_on_segment(other_segment[0], other_segment[1], p1): full_segment = (segments[i - 1][index1], segments[(i + 1) % len(segments)][index1]) if have_common_point(other_segment, full_segment): return False if not segments_are_intersecting(full_segment, other_segment): return False for index2, p2 in enumerate(other_segment): if is_on_segment(segment[0], segment[1], p2): full_segment = (segments[j - 1][index2], segments[(j + 1) % len(segments)][index2]) if have_common_point(segment, full_segment): return False if not segments_are_intersecting(full_segment, segment): return False return True
def get_collision_between_lines(line1, line2, precision=PRECISION): # get_line_vector_collision_point """ returns collision between 2 lines defined by a point and the direction vector """ point_1, director_1 = line1 point_2, director_2 = line2 # == if not is_same(det(director_1, director_2), 0, precision=precision): return tuple_sum( point_1, tuple_float_mult( director_1, det(points_diff(point_1, point_2), director_2) / float(det(director_1, director_2)) ), ) if is_same(det(points_diff(point_1, point_2), director_1), 0, precision=precision): return point_1 # ou point_2, c'est la meme chose : les droites sont confondues return None
def self_intersect_line(points, precision=PRECISION): for index in range(len(points))[:-2]: first_segment = (points[index], points[index + 1]) for index2 in range(len(points))[index + 1 : -1]: second_segment = (points[index2], points[index2 + 1]) collision_point = get_collision_between_segments(first_segment, second_segment, precision=precision) if collision_point and not is_same(collision_point, points[index2]): return True return False
def is_on_line(seg_start, seg_end, point, precision=PRECISION): if is_same(seg_start, point, precision=precision) or is_same(seg_end, point, precision=precision): return True if is_same(seg_start, seg_end, precision=precision): return False vector_from_start_to_end = points_diff(seg_start, seg_end) vector_from_start_to_point = points_diff(seg_start, point) angle = math.degrees( math.acos( min( 1.0, max( -1.0, dot_product(vector_from_start_to_end, vector_from_start_to_point) / (magnitude(vector_from_start_to_end) * magnitude(vector_from_start_to_point)), ), ) ) ) # == return ( is_same(angle, 0, precision=precision) or is_same(angle, 360.0, precision=precision) or is_same(angle, -360.0, precision=precision) )
def have_common_point(segment1, segment2): for _p1 in segment1: for _p2 in segment2: if is_same(_p1, _p2): return True return False