原理
等分点标注法首先需要计算两个点之间的间隔,以便后续的计算。首先确定起始点为起始坐标,计算该点与下一个点之间的距离是不是大于或者等于间隔,如果是,计算x,y值,并且将起始点的坐标改变为计算所得的x,y值;如果距离小于间隔,则用间隔减去这两个点之间的距离,并且将起始点坐标改变为下一个坐标点的坐标。这样来进行逐条线段的处理,得到标注点的坐标。
实现
#! /usr/bin/env python
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: 折线求等分带
# Author: yunhgu
# Date: 2021/10/27 11:46
# Description:
# -------------------------------------------------------------------------------
from math import sqrt, pow
import cv2
import numpy as np
# 等分点标注法
def polyline_get_dividing_points(points, num):
dividing_points = []
line_length = 0.0
# 计算总长
for index in range(len(points) - 1):
x0, y0 = points[index][0], points[index][1]
x1, y1 = points[index + 1][0], points[index + 1][1]
line_length += sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2))
# 计算每一段长度
distance = line_length / num
# 初始化当前长度
cur_distance = distance
# 起始点坐标
x1, y1 = points[0][0], points[0][1]
dividing_points.append([x1, y1])
out_point = 0
for index in range(1, len(points)):
x2, y2 = points[index][0], points[index][1]
while True:
line_distance = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2))
if line_distance >= cur_distance:
x = (x2 - x1) * cur_distance / line_distance + x1
y = (y2 - y1) * cur_distance / line_distance + y1
out_point += 1
if out_point > num - 1:
break
dividing_points.append([x, y])
# 改变起始点坐标
x1 = x
y1 = y
cur_distance = distance
# 当前线段长度不足时,考虑下一条线段
else:
# 改变起始点的坐标
x1 = x2
y1 = y2
cur_distance -= line_distance # 长度要减去之前线段的长度
break
# 加入尾点坐标
dividing_points.append([points[-1][0], points[-1][1]])
return dividing_points
# 等间隔标注法
def polyline_equally_spaced_points(points, space):
dividing_points = []
line_length = 0.0
# 计算总长
for index in range(len(points) - 1):
x0, y0 = points[index][0], points[index][1]
x1, y1 = points[index + 1][0], points[index + 1][1]
line_length += sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2))
# 计算每一段长度
division = line_length / space
distance = 0
if int(division) - division == 0:
distance = space / 2.0
else:
distance = (line_length - int(line_length / space) * space) / 2.0
# 起始点坐标
x1, y1 = points[0][0], points[0][1]
out_point = 0
for index in range(1, len(points)):
x2, y2 = points[index][0], points[index][1]
while True:
line_distance = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2))
if line_distance >= distance:
x = (x2 - x1) * distance / line_distance + x1
y = (y2 - y1) * distance / line_distance + y1
out_point += 1
dividing_points.append([x, y])
x1 = x
y1 = y
distance = space
else:
# 改变起始点的坐标
x1 = x2
y1 = y2
distance -= line_distance # 长度要减去之前线段的长度
break
return dividing_points
def draw(points):
img = np.zeros((1000, 1000, 3), np.uint8)
for point in points:
point = (int(point[0]), int(point[1]))
cv2.circle(img, point, 4, (0, 0, 255), -1)
cv2.imshow('a', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
test_points = [
[50, 50], [200, 100], [500, 700]
]
draw(test_points)
# result_points = polyline_get_dividing_points(test_points, 10)
# print(result_points)
result_points = polyline_equally_spaced_points(test_points, 20)
print(result_points)
draw(result_points)