通过两点,半径和是否顺时针计算圆心点坐标并得到圆弧上的点(python实现)

通过两点和半径可以确定一个或者两个圆心,具体的公式推导可以看看这位大佬的文章,已经讲的很详细了。

通过两点坐标,半径和弧线的顺时针逆时针方向得到圆心坐标,并且输出该圆弧中间的坐标点和近似切线角度。

在这里默认输入的两个点和半径是可以组成一个圆的。并且需要注意的是:不考虑特殊情况(如两点中间的距离等于直径,两点x值相等等),由于可以得到两个圆心,因此即使知道是顺时针或者逆时针方向,根据圆心的不同也能够得到两条圆弧(小圆弧和大圆弧)

我这里单纯取一个圆心输出弧线上的点坐标和切线角度。

import math

def get_circle_center(x1, y1, x2, y2, r):
    
    # 计算两点之间的距离
    d = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
    #print(d)

    if x1 == x2 and y1 == y2:
        print("no result")

    elif d / 2 == r:
        center_x = (x1 + x2) / 2
        center_y = (y1 + y2) / 2
        print("d == r")
    
    elif x1 == x2:
        center_y = (y1 + y2) / 2
        center_x = x1 + math.sqrt(r * r - ((y1 - y2) / 2) * ((y1 - y2) / 2))
    
    else:
        c1 = (y2 * y2  - y1 * y1 + x2 * x2 - x1 * x1) / (2 * (x2 - x1))
        c2 = (y2 - y1) / (x2 - x1)
        A = c2 * c2 + 1
        B = 2 * x1 * c1  - c1 * c1 - 2 * y1
        C = x1 * x1 - 2 * x1 * c1 + c1 * c1 + y1 * y1 + r * r
        print(B * B - 4 * A * C)

        center_y = (-B + math.sqrt(B * B - 4 * A * C)) / (2 * A)  #还有另外一个值:(-B - math.sqrt(B * B - 4 * A * C)) / (2 * A)
        center_x = c1 - c2 * center_y

    return center_x, center_y

def get_point(center_x, center_y, x1, y1, x2, y2, r, clockwise):
    start_angle = math.atan2(y1 - center_y, x1 - center_x)
    end_angle = math.atan2(y2 - center_y, x2 - center_x)

    #判断顺时针和逆时针
    if clockwise:
        if start_angle < end_angle:
            start_angle += 2 * math.pi
    else:
        if end_angle < start_angle:
            end_angle += 2 * math.pi
    # 计算角度差
    angle_diff = end_angle - start_angle
    '''
    if angle_diff < 0:
        angle_diff += 2 * math.pi
        print("angle_diff < 0")
    '''
    num_points = 100
    point_list = []
    for i in range(num_points + 1):
        angle = start_angle + i * angle_diff / num_points
        x = center_x + r * math.cos(angle)
        y = center_y + r * math.sin(angle)
        grad = math.atan2((center_y + r * math.sin(start_angle + (i + 1) * angle_diff / num_points)) - y, (center_x + r * math.cos(start_angle + (i + 1) * angle_diff / num_points)) - x)
        point_list.append((x, y, grad))
    size = len(point_list)
    return point_list, size
    

print (get_circle_center(0, 0, 0, 2, 1))
x0, y0 = get_circle_center(0, 0, 0, 2, 1)
clockwise = True  #true为顺时针,false为逆时针
print(get_point(x0, y0, 0, 0, 0, 2, 1, clockwise))

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值