python进行点和线段、直线、多边形的交点、距离,垂直等处理——代码

相关内容目录:

目录

1.基本的点和线段,多边形的表示:

 2.已知两点的坐标,求直线的解析方程:

3.计算两直线的交点:

4.计算两直线的夹角:

5.获取直线 与 点的垂足

6.计算点到线段的距离最近点:

7.计算点到直线的距离:

8.计算任意凸多边形的面积:

9.计算圆和直线的交点:

10.判断点是否在多边形内:


1.基本的点和线段,多边形的表示:

import numpy as np
import math
import matplotlib.pyplot as plt
from shapely.geometry import LineString
from shapely.geometry import Point

point = [10,10]     # 点,x,y
line = [1,2,12,10]  # 线段或直线,x1,y1, x2,y2
polygon = [[0,0], [8,2], [12,9], [5,10]]  # 多边形,几个点的列表
line_area = polygon+[polygon[0]]
plt.plot([i[0] for i in line_area], [i[1] for i in line_area])
plt.scatter(point[0], point[1], s=100, c='r')
plt.plot(line[::2], line[1::2])
plt.show()

 

 2.已知两点的坐标,求直线的解析方程:

# 根据已知两点坐标,求过这两点的直线解析方程: a*x+b*y+c = 0  (a >= 0)
def getLinearEquation(p1x, p1y, p2x, p2y):
    sign = 1
    a = p2y - p1y
    if a < 0:
        sign = -1
        a = sign * a
    b = sign * (p1x - p2x)
    c = sign * (p1y * p2x - p1x * p2y)
    #return [a, b, c]
    #y=kx+bb
    k=-a/b 
    bb= -c/b
    return k,bb

3.计算两直线的交点:

def cross_point(line1,line2):   ##  计算两直线的交点
    [x1,y1,x2,y2]=line1#取四点坐标
    [x3,y3,x4,y4]=line2
    k1=(y2-y1)*1.0/(x2-x1)#计算k1,由于点均为整数,需要进行浮点数转化
    b1=y1*1.0-x1*k1*1.0#整型转浮点型是关键
    if (x4-x3)==0:#L2直线斜率不存在操作
        k2=None
        b2=0
    else:
        k2=(y4-y3)*1.0/(x4-x3)#斜率存在操作
        b2=y3*1.0-x3*k2*1.0
    if k2==None:
        x=x3
    else:
        x=(b2-b1)*1.0/(k1-k2)
    y=k1*x*1.0+b1*1.0
    return [x,y]

4.计算两直线的夹角:

##  计算两直线的夹角
def GetCrossAngle(line1, line2):
    [x1,y1,x2,y2]=line1
    [x3,y3,x4,y4]=line2
    arr_0 = np.array([(x2 - x1), (y2 - y1)])
    arr_1 = np.array([(x4 - x3), (y4 - y3)])
    cos_value = (float(arr_0.dot(arr_1)) / (np.sqrt(arr_0.dot(arr_0)) * np.sqrt(arr_1.dot(arr_1))))
    if cos_value>1:
        cos_value=1
    elif cos_value<-1:
        cos_value=-1
    return np.arccos(cos_value)

5.获取直线 与 点的垂足

## 获取直线 与 点的垂足
def get_foot(point, line):
    start_x, start_y = line[0], line[0]
    end_x, end_y = line[2], line[3]
    pa_x, pa_y = point

    p_foot = [0, 0]
    if line[0] == line[3]:
        p_foot[0] = line[0]
        p_foot[1] = point[1]
        return p_foot
    k = (end_y - start_y) * 1.0 / (end_x - start_x)
    a = k
    b = -1.0
    c = start_y - k * start_x
    p_foot[0] = (b * b * pa_x - a * b * pa_y - a * c) / (a * a + b * b)
    p_foot[1] = (a * a * pa_y - a * b * pa_x - b * c) / (a * a + b * b)
    return p_foot

6.计算点到线段的距离最近点:

def get_nearest_point(point, line): ##  计算点到线段的最近点
    pt1_x, pt1_y = line[0], line[1]
    pt2_x, pt2_y = line[2], line[3]
    point_x, point_y = point[0], point[1]
    if (pt2_x - pt1_x )!=0:
        k = ( pt2_y - pt1_y ) / (pt2_x - pt1_x )
    elif min(pt1_y, pt2_y)<point[1]<max(pt1_y, pt2_y):
        return get_foot(point, line)
    else :
        l1 = np.hypot(pt1_y-point[1], pt1_x-point[0])
        l2 = np.hypot(pt2_y-point[1], pt2_x-point[0])
        return (pt1_x, pt1_y) if l1<l2 else (pt2_x, pt2_y)
    #该直线方程为:
    #y = k* ( x - pt1_x) + pt1_y
    #其垂线的斜率为 - 1 / k,
    #垂线方程为:
    #y = (-1/k) * (x - point_x) + point_y
    #联立两直线方程解得:
    x  =  ( k**2 * pt1_x + k * (point_y - pt1_y ) + point_x ) / ( k**2 + 1)
    y  =  k * ( x - pt1_x) + pt1_y
    return (x, y)

7.计算点到直线的距离:

def get_distance_point2line(point, line):   ##  计算点到直线的距离
    """
    Args:
        point: [x0, y0]
        line: [x1, y1, x2, y2]
    """
    line_point1, line_point2 = np.array(line[0:2]), np.array(line[2:])
    vec1 = line_point1 - point
    vec2 = line_point2 - point
    m=np.linalg.norm(line_point1 - line_point2)
    if m==0:
        print('error')
        return 0
    else:
        distance = np.abs(np.cross(vec1, vec2)) / m
    return distance

8.计算任意凸多边形的面积:

def polygon_area(polygon):  ##计算多边形面积
    """
    compute polygon area
    polygon: list with shape [n, 2], n is the number of polygon points
    """
    area = 0
    q = polygon[-1]
    for p in polygon:
        area += p[0] * q[1] - p[1] * q[0]
        q = p
    return abs(area) / 2.0

9.计算圆和直线的交点:

def LineIntersectCircle(p,lsp,lep):     ##  计算圆和直线的交点,输出一个[[x,y],]
# p is the circle parameter, lsp and lep is the two end of the line
    x0,y0,r0 = p
    p = Point(x0,y0)
    c = p.buffer(r0).boundary
    l = LineString([lsp, lep])
    i = c.intersection(l)
    intersection = []
    if i.type=='Point':
        intersection.append(i.coords[0])
    elif i.type=='MultiPoint':
        for m in range(len(i.geoms)):
            intersection.append(i.geoms[m].coords[0])
            #print(i.geoms[m].coords[0])
    else:
        print('圆和直线没有交点', i.type)
    return intersection

10.判断点是否在多边形内:

def isInPolygon(point, polygon):    ##  检测点是否在多边形内,输入([x,y], polygon_list也就是点组成的list)
    # 使用水平射线检测
    x,y=point[0], point[1]
    nCross = 0
    for i in range(len(polygon)):
        p1 = polygon[i]
        p2 = polygon[(i+1)%len(polygon)]
        # 特殊情况:边界p1p2 与 y=p0.y平行,不计数
        if (p1[1] == p2[1]):continue
        # 交点在p1p2延长线上,注意是小于,不计数
        if (y < min(p1[1], p2[1])):continue
        # 交点在p1p2延长线上,注意是大于等于,不计数  
        if (y >= max(p1[1], p2[1])):continue
        # 求交点的 X 坐标;根据相似三角形计算
        crossx = (y-p1[1])*(p2[0]-p1[0])/(p2[1]-p1[1])+p1[0]
       # 只统计单边交点  
        if (crossx >= x):
            nCross=nCross+1
    min_dis = get_dis_point2polygon(point, polygon)
    if abs(min_dis)<1e-2:  ##  求点到哪个边距离最小,是否为0,为0则表示在边界上
        return 1
    return (nCross % 2 == 1)

来源:nature1949

物联沃分享整理
物联沃-IOTWORD物联网 » python进行点和线段、直线、多边形的交点、距离,垂直等处理——代码

发表评论