因为数学能力有限,只能借助 AI 了。

随着 chatGPT5 的发布,终于可以把从零开始写数控系统 0.6:圆弧插补(上)扩展到全象限了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# Python3
from decimal import *
import math

class Circle(object):
def __init__(self, g=3, start=(0, 0), end=(0, 0), offset=(0, 0), r=0) -> None:
self.start = tuple(map(lambda x: Decimal(str(x)).quantize(Decimal("0.000")), start))
self.end = tuple(map(lambda n: Decimal(str(n)).quantize(Decimal("0.000")), end))
self.g = g
if offset != (0, 0):
self.offset = tuple(map(lambda x: Decimal(str(x)).quantize(Decimal("0.000")), offset))
else:
self.r = Decimal(str(r))
self.zoom = Decimal(1000)
self.delta = Decimal(1) / self.zoom
self.__getCenter()

def __str__(self) -> str:
return "start=({:,.3f},{:,.3f}); end=({:,.3f},{:,.3f}); center=({:,.3f},{:,.3f}); radius={:,.3f}".format(
float(self.start[0]), float(self.start[1]),
float(self.end[0]), float(self.end[1]),
float(self.x0), float(self.y0), float(self.r),
)

def __getCenter(self) -> tuple:
if "offset" in dir(self):
self.x0 = self.start[0] + self.offset[0]
self.y0 = self.start[1] + self.offset[1]
self.r = math.sqrt((self.end[0] - self.x0) ** 2 + (self.end[1] - self.y0) ** 2)
self.r = Decimal(str(self.r))
else:
xs, ys = self.start[0], self.start[1]
xe, ye = self.end[0], self.end[1]
c1 = (xs**2 - xe**2 + ys**2 - ye**2) / (2 * xs - 2 * xe)
c2 = (ys - ye) / (xs - xe)
a = 1 + c2**2
b = 2 * (xe - c1) * c2 - 2 * ye
c = (xe - c1) ** 2 + ye**2 - self.r**2
y0 = (-b + Decimal(str(math.sqrt(b**2 - 4 * a * c)))) / (2 * a)
x0 = c1 - c2 * y0
xm = (xs + xe) / 2
ym = (ys + ye) / 2
if xm > x0 and ym > y0:
self.y0 = y0
self.x0 = x0
else:
self.y0 = (-b - Decimal(str(math.sqrt(b**2 - 4 * a * c)))) / (2 * a)
self.x0 = c1 - c2 * self.y0

def __offset(self) -> None:
self.__xs = self.start[0] - self.x0
self.__ys = self.start[1] - self.y0
self.__xe = self.end[0] - self.x0
self.__ye = self.end[1] - self.y0
self.f = 0
self.step = abs(self.__xs - self.__xe) + abs(self.__ys - self.__ye)
self.step = self.step * self.zoom

@staticmethod
def __getQD(point) -> int:
match (point[0] >= 0, point[1] >= 0):
case (1, 1):
return 1
case (0, 1):
return 2
case (0, 0):
return 3
case (1, 0):
return 4

def __compensation(self) -> None:
# 动态象限判断
qd = Circle.__getQD((self.__x, self.__y))
match (self.g, self.f >= 0, qd):
case (3, 1, 1) | (3, 0, 2) | (2, 0, 3) | (2, 1, 4):
self.f = self.f - 2 * self.__x + self.delta
self.__x -= self.delta
case (3, 0, 1) | (3, 1, 4) | (2, 0, 2) | (2, 1, 3):
self.f = self.f + 2 * self.__y + self.delta
self.__y += self.delta
case (3, 1, 3) | (3, 0, 4) | (2, 1, 2) | (2, 0, 1):
self.f = self.f + 2 * self.__x + self.delta
self.__x += self.delta
case (3, 0, 3) | (3, 1, 2) | (2, 1, 1) | (2, 0, 4):
self.f = self.f - 2 * self.__y + self.delta
self.__y -= self.delta

def __iter__(self):
self.__offset()
self.__x = self.__xs
self.__y = self.__ys
return self

def __next__(self):
if self.step:
self.__compensation()
self.step -= 1
return (float(self.__x + self.x0), float(self.__y + self.y0))
else:
if self.__x + self.x0 != self.end[0] or self.__y + self.y0 != self.end[1]:
print("圆弧错误,请检查输入代码")
raise StopIteration

小试牛刀

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
c1 = Circle(g=2, start=(-4, 0), end=(0, 4), r=4)
print(c1)

# Output: start=(-4.000,0.000); end=(0.000,-4.000); center=(-4.000,-4.000); radius=4.000

for i in c1:
print(i)
# Output:
# (-3.999, 0.0)
# (-3.999, 0.001)
# (-3.999, 0.002)
# ...
# (0.0, -3.998)
# (0.0, -3.999)
# (0.0, -4.0)

网站地图 | 状态监测 | 图片加密&解密 | File Server | 博友圈 | 博客说
Copyright 2022-2025 | Powered by Hexo 7.3.0 & Stellar 1.33.1
总访问量次 |