python检测线段是否含有勾
# -*- coding: utf-8 -*-#
import math
lines_dic = {
"正常": [
[[0, 0], [1, 1], [2, 2], [3, 3]],
[[0, 0], [1, 1], [1, 2], [3, 5]]
],
"勾": [
[[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [2, 1]],
[[1, 2], [0, 0], [1, 1], [2, 2], [3, 3], [4, 4]]
]
}
def get_point_line_distance(point, line):
"""
:param point: (x,y)
:param line: [(x1,y1),(x2,y2)]
:return:
"""
point_x = point[0]
point_y = point[1]
line_s_x = line[0][0]
line_s_y = line[0][1]
line_e_x = line[1][0]
line_e_y = line[1][1]
# 若直线与y轴平行,则距离为点的x坐标与直线上任意一点的x坐标差值的绝对值
if line_e_x - line_s_x == 0:
return math.fabs(point_x - line_s_x)
# 若直线与x轴平行,则距离为点的y坐标与直线上任意一点的y坐标差值的绝对值
if line_e_y - line_s_y == 0:
return math.fabs(point_y - line_s_y)
# 斜率
k = (line_e_y - line_s_y) / (line_e_x - line_s_x)
# 截距
b = line_s_y - k * line_s_x
return math.fabs(k * point_x - point_y + b) / math.pow(k * k + 1, 0.5)
def get_inflection_point(coordinates, line):
"""
:param coordinates: 线段坐标
:param line:线段开头和结尾
:return:获取拐点
"""
max_distance = -1
inflection_point = None
for index, point in enumerate(coordinates):
distance = get_point_line_distance(point, line)
if index != 0 and max_distance < distance or index == 0:
max_distance = distance
inflection_point = point
return inflection_point
def cal_ang(point_1, point_2, point_3):
"""
根据三点坐标计算夹角
:param point_1: 点1坐标
:param point_2: 点2坐标
:param point_3: 点3坐标
:return: 返回任意角的夹角值,这里只是返回点2的夹角
"""
a = math.sqrt((point_2[0] - point_3[0]) * (point_2[0] - point_3[0]) + (point_2[1] - point_3[1]) * (point_2[1] - point_3[1]))
b = math.sqrt((point_1[0] - point_3[0]) * (point_1[0] - point_3[0]) + (point_1[1] - point_3[1]) * (point_1[1] - point_3[1]))
c = math.sqrt((point_1[0] - point_2[0]) * (point_1[0] - point_2[0]) + (point_1[1] - point_2[1]) * (point_1[1] - point_2[1]))
A = math.degrees(math.acos((a * a - b * b - c * c) / (-2 * b * c)))
B = math.degrees(math.acos((b * b - a * a - c * c) / (-2 * a * c)))
C = math.degrees(math.acos((c * c - a * a - b * b) / (-2 * a * b)))
return B
def check_line_tick(coordinates):
"""
:param coordinates: 线段[[x,y],[x,y],[x,y]...]
:return:False/True
检测线段是否有勾
"""
line = [coordinates[0], coordinates[-1]]
inflection_point = get_inflection_point(coordinates, line)
if inflection_point in line:
return False
angle = cal_ang(line[0], inflection_point, line[1])
return angle < 90
if __name__ == '__main__':
for name, lines_list in lines_dic.items():
for lines in lines_list:
print(name, check_line_tick(lines))
不论你在什么时候开始,重要的是开始之后就不要停止。
不论你在什么时候结束,重要的是结束之后就不要悔恨。