折线求等分点

原理

等分点标注法首先需要计算两个点之间的间隔,以便后续的计算。首先确定起始点为起始坐标,计算该点与下一个点之间的距离是不是大于或者等于间隔,如果是,计算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)

效果

原始:

image

添加等分点后:

image

posted @ 2021-10-27 16:55  不能说的秘密  阅读(303)  评论(0编辑  收藏  举报