ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

点和线的扇形缓冲区生成

2021-09-17 11:33:56  阅读:161  来源: 互联网

标签:elif tangle angle 点和线 np length 扇形 缓冲区 pi


# coding:utf-8
# 扇形缓冲区
from shapely.ops import substring
from shapely.geometry import LineString, Polygon
from math import pi
import numpy as np
import logging
logging.basicConfig(level=logging.WARNING,
                    format='%(asctime)s-%(filename)s[line:%(lineno)d]-%(levelname)s:%(message)s',
                    datefmt='%H:%M:%S')


def pnt2polar(p):
    # 平面点转极坐标
    x, y = p
    length = np.sqrt(x * x + y * y)
    x = round(x, 6)
    y = round(y, 6)
    alpha = np.arctan(abs(y / x)) if x != 0. else 0.
    if x > 0:
        if y > 0:
            angle = alpha
        elif y == 0:
            angle = 0
        else:
            angle = pi * 2 - alpha
    elif x == 0:
        if y > 0:
            angle = pi / 2
        elif y == 0:
            angle = 0
        else:
            angle = 3 * pi / 2
    else:
        if y > 0:
            angle = pi - alpha
        elif y == 0:
            angle = pi
        else:
            angle = pi + alpha

    return round(length, 3), round(angle, 3)


def polar2pnt(p):
    # 极坐标转平面坐标
    length, angle = p
    eps = 1e-8

    if length == 0:
        x, y = 0
    else:
        if angle < eps:
            x = length
            y = 0
        elif angle - 3 * pi / 2 > eps:
            x = length * np.cos(2 * pi - angle)
            y = -length * np.sin(2 * pi - angle)
        elif angle - 3 * pi / 2 == eps:
            x = 0
            y = length
        elif angle - pi > eps:
            x = -length * np.cos(angle - pi)
            y = -length * np.sin(angle - pi)
        elif angle - pi == eps:
            x = -length
            y = 0
        elif angle - pi / 2 > eps:
            x = -length * np.cos(pi - angle)
            y = length * np.sin(pi - angle)
        elif angle - pi / 2 == eps:
            x = 0
            y = -length
        else:
            x = length * np.cos(angle)
            y = length * np.sin(angle)

    return round(x, 3), round(y, 3)


def arcPointBuffer(p, r, fangle, tangle):
    # p 是目标点
    # r 是缓冲半径
    # fangle, tangle 是扇形角度
    # 0 -> 2*pi x轴正方向,逆时针

    if tangle > fangle:
        angles = np.linspace(fangle, tangle, num=64)
    else:
        angles = np.linspace(fangle, 2*pi, num=32)
        angles_ = np.linspace(0, tangle, num=32)
        angles = np.r_[angles, angles_]
    polars = np.c_[[r] * 64, angles]
    vector = [polar2pnt(_) for _ in polars]

    x, y = np.array(p).tolist()
    vector = [[x+i, y+j] for i, j in vector]

    ply = [[x, y]] + vector + [[x, y]]

    return Polygon(ply)


def arcLineBuffer(geom, r, arc):
    # 在线的终点进行arcBuffer
    # geom
    # r 缓冲半径
    # arc 扇形圆心角

    length = geom.length
    if length < r:
        fl = geom
    else:
        fl = substring(geom, length-r, length)

    ps, pe = fl.coords[0], fl.coords[-1]
    vec = pe[0]-ps[0], pe[1]-ps[1]
    logging.warning(f"vec:{vec}")
    lgth, angle = pnt2polar(vec)

    fangle = angle - arc/2
    tangle = angle + arc/2
    if fangle < 0:
        fangle = 2*pi - (arc/2 - angle)
    if tangle > 2*pi:
        tangle = tangle - pi*2
    logging.warning(f"angle:{angle:.3f}")
    logging.warning(f"ftangle:{fangle:.3f},{tangle:.3f}")
    res = arcPointBuffer(pe, lgth, fangle, tangle)
    return res


if __name__ == '__main__':

    ls = LineString([[0, 0], [10, 0]])
    arc = pi/4
    res = arcLineBuffer(ls, 2, arc)
    res = arcPointBuffer((10, 0), 1, 0, arc)

  

标签:elif,tangle,angle,点和线,np,length,扇形,缓冲区,pi
来源: https://www.cnblogs.com/ddzhen/p/15303887.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有