基于3点构建圆/弧

# coding:utf-8
import numpy as np
from functools import partial
from shapely.geometry import Point, LineString
from shapely.affinity import rotate, scale
from shapely.ops import split, linemerge, snap
import geopandas as gpd

class arcBase3pnts():
    # 基于3点构建圆/弧
    
    def __init__(self, pnts):
        p1, p2, p3 = pnts
        self.p1 = p1
        self.p2 = p2
        self.p3 = p3
    
    def getCenterAndRadius(self):
        # pnts = [[x1,y1],[x2,y2],[x3,y3]]
        p1, p2, p3 = self.p1, self.p2, self.p3
        
        ls1, ls2 = LineString([p2, p3]), LineString([p1, p3])
        fx = partial(scale, xfact=3, yfact=3)
        ls1, ls2 = fx(ls1), fx(ls2)
        vs1, vs2 = rotate(ls1, 90), rotate(ls2, 90)
        
        cp = vs1.intersection(vs2)
        r = cp.distance(Point(p1))
        return cp, r 
            
    
    def getCircle(self):
        # pnts = [[x1,y1],[x2,y2],[x3,y3]]
        cp, r = self.getCenterAndRadius()
        
        return cp.buffer(r)
    
    def getArc(self):
        # 获取过三点的弧长
        # 要求弧长过点的顺序按照点的顺序,即中间点在弧长的中间部分
        p1, p2, p3 = self.p1, self.p2, self.p3
        circle = self.getCircle()
        ls3 = LineString([p1, p2])
        parts = split(circle, ls3)
        for part in parts:
            if part.distance(Point(p3)) < 1e-6:
                res = circle.boundary.intersection(part)
                tmp = []
                for i in range(len(res)):  # 处理可能出行的多线情况
                    if res[i].geom_type=="LineString":
                        tmp.append(res[i])
                res2 = linemerge(tmp)        
                break
        return res2
    
    def getLastArc(self):
        # 获取过后两个点之间的弧
        p2, p3 = self.p2, self.p3
        arc = self.getArc()
        pp2, pp3 = Point(p2), Point(p3)
        arc = snap(arc, pp3, tolerance=0.1)
        parcs = split(arc, pp3)
        index = 0 if parcs[0].distance(pp2)<parcs[0].distance(pp2) else 1
        return parcs[index]


if __name__ == "__main__":
    
    pnts = [0, 1], [1, 0], [np.sqrt(1/2), np.sqrt(1/2)]
    oarc = arcBase3pnts(pnts=pnts)
    arc = oarc.getArc()
    prc = oarc.getLastArc()

  

上一篇:韩顺平Java06(类与对象)


下一篇:贪心算法