The Fisrt Updated
This commit is contained in:
174
Milib.py.txt
Normal file
174
Milib.py.txt
Normal file
@@ -0,0 +1,174 @@
|
||||
import MilCon
|
||||
import typing
|
||||
import math
|
||||
|
||||
|
||||
class _HPos:
|
||||
x: str
|
||||
y: str
|
||||
z: str
|
||||
|
||||
class RelativePos:
|
||||
def __init__(self, x: str | int | float = "~", y: str | int | float = "~", z: str | int | float = "~"):
|
||||
self.x: str = str(x) if isinstance(x, (int, float)) else x
|
||||
self.y: str = str(y) if isinstance(y, (int, float)) else y
|
||||
self.z: str = str(z) if isinstance(z, (int, float)) else z
|
||||
def __str__(self):
|
||||
return f"{self.x} {self.y} {self.z}"
|
||||
@classmethod
|
||||
def FromString(cls, s: str):
|
||||
parts = s.split()
|
||||
if len(parts) != 3 or not all(p.startswith('~') for p in parts): raise ValueError("Catch A Error As RelativePos ~x ~y ~z")
|
||||
return cls(*parts)
|
||||
def ToAbsolute(self, reference: _HPos=None):
|
||||
def ParseCoord(coord: str, ref):
|
||||
if coord.startswith('~'): return ref + (float(coord[1:]) if len(coord) > 1 else 0.0)
|
||||
else: return float(coord)
|
||||
ref_x = reference.x if reference and reference.x.startswith('~') else 0.0
|
||||
ref_y = reference.y if reference and reference.y.startswith('~') else 0.0
|
||||
ref_z = reference.z if reference and reference.z.startswith('~') else 0.0
|
||||
abs_x = ParseCoord(self.x, ref_x)
|
||||
abs_y = ParseCoord(self.y, ref_y)
|
||||
abs_z = ParseCoord(self.z, ref_z)
|
||||
return RelativePos(abs_x, abs_y, abs_z)
|
||||
|
||||
class LocalCoordinatesPos:
|
||||
def __init__(self, x: str | int | float = "^", y: str | int | float = "^", z: str | int | float = "^"):
|
||||
self.x: str = str(x) if isinstance(x, (int, float)) else x
|
||||
self.y: str = str(y) if isinstance(y, (int, float)) else y
|
||||
self.z: str = str(z) if isinstance(z, (int, float)) else z
|
||||
def __str__(self):
|
||||
return f"{self.x} {self.y} {self.z}"
|
||||
@classmethod
|
||||
def FromString(cls, s: str):
|
||||
parts = s.split()
|
||||
if len(parts) != 3 or not all(p.startswith('^') for p in parts): raise ValueError("Catch A Error As LocalCoordinatesPos ^x ^y ^z")
|
||||
return cls(*parts)
|
||||
def ToAbsolute(self, reference: _HPos=None):
|
||||
def ParseCoord(coord: str, ref):
|
||||
if coord.startswith('^'): return ref + (float(coord[1:]) if len(coord) > 1 else 0.0)
|
||||
else: return float(coord)
|
||||
ref_x = reference.x if reference and reference.x.startswith('^') else 0.0
|
||||
ref_y = reference.y if reference and reference.y.startswith('^') else 0.0
|
||||
ref_z = reference.z if reference and reference.z.startswith('^') else 0.0
|
||||
abs_x = ParseCoord(self.x, ref_x)
|
||||
abs_y = ParseCoord(self.y, ref_y)
|
||||
abs_z = ParseCoord(self.z, ref_z)
|
||||
return LocalCoordinatesPos(abs_x, abs_y, abs_z)
|
||||
|
||||
class Delta:
|
||||
def __init__(self, x: int = 0, y: int = 0, z: int = 0):
|
||||
self.x, self.y, self.z = x, y, z
|
||||
def __str__(self):
|
||||
return f"{self.x} {self.y} {self.z}"
|
||||
class Command():
|
||||
def __init__(self, command):
|
||||
self.command = command
|
||||
def __str__(self):
|
||||
return self.command
|
||||
class ExecuteSubCommandRule(typing.TypedDict):
|
||||
mode: MilCon._execute_sub_commands
|
||||
text: Command
|
||||
|
||||
def _Bool2Str(self, value: bool):
|
||||
return "true" if value else "false"
|
||||
def _WithValue(self, value: str | int):
|
||||
return f" {value}" if value else ""
|
||||
|
||||
def _Pos1ToPos2(pos1: RelativePos, pos2: RelativePos, radios: int):
|
||||
abs_pos1 = pos1.ToAbsolute()
|
||||
abs_pos2 = pos2.ToAbsolute()
|
||||
x1, y1, z1 = abs_pos1.x, abs_pos1.y, abs_pos1.z
|
||||
x2, y2, z2 = abs_pos2.x, abs_pos2.y, abs_pos2.z
|
||||
delta_x = (x2 - x1) / (radios + 1)
|
||||
delta_y = (y2 - y1) / (radios + 1)
|
||||
delta_z = (z2 - z1) / (radios + 1)
|
||||
points = []
|
||||
for i in range(1, radios + 1):
|
||||
x = x1 + delta_x * i
|
||||
y = y1 + delta_y * i
|
||||
z = z1 + delta_z * i
|
||||
points.append(RelativePos(x, y, z))
|
||||
return points
|
||||
|
||||
def _Pos1ToPos2WithPoints(radios: int, radian: int, pos1: RelativePos, pos2: RelativePos, *poses: RelativePos):
|
||||
# 参数验证
|
||||
if radios <= len(poses) + 2:
|
||||
raise ValueError("radios must be greater than len(poses) + 2")
|
||||
if radian < 0:
|
||||
raise ValueError("radian must be non-negative")
|
||||
|
||||
# 转换为绝对坐标
|
||||
abs_pos1 = pos1.ToAbsolute()
|
||||
abs_poses = [p.ToAbsolute() for p in poses]
|
||||
abs_pos2 = pos2.ToAbsolute()
|
||||
|
||||
# 所有点按顺序排列
|
||||
all_points = [abs_pos1] + abs_poses + [abs_pos2]
|
||||
num_segments = len(all_points) - 1
|
||||
|
||||
# 计算每段的点数
|
||||
points_per_segment = (radios - num_segments + 1) // num_segments
|
||||
remainder = (radios - num_segments + 1) % num_segments
|
||||
|
||||
# 生成点
|
||||
points = []
|
||||
for i in range(num_segments):
|
||||
start = all_points[i]
|
||||
end = all_points[i + 1]
|
||||
|
||||
# 当前段的点数
|
||||
current_points = points_per_segment + (1 if i < remainder else 0)
|
||||
|
||||
# 计算增量
|
||||
delta_x = (float(end.x) - float(start.x)) / (current_points + 1)
|
||||
delta_y = (float(end.y) - float(start.y)) / (current_points + 1)
|
||||
delta_z = (float(end.z) - float(start.z)) / (current_points + 1)
|
||||
|
||||
# 生成当前段的点
|
||||
for j in range(1, current_points + 1):
|
||||
x = float(start.x) + delta_x * j
|
||||
y = float(start.y) + delta_y * j
|
||||
z = float(start.z) + delta_z * j
|
||||
|
||||
# 如果 radian 不为 0 且 poses 存在,则在中间点附近向外偏移
|
||||
if radian != 0 and len(poses) > 0 and i < len(poses):
|
||||
# 计算当前点与中间点的距离比例
|
||||
t = j / (current_points + 1)
|
||||
# 使用正弦函数生成弧形偏移
|
||||
offset = radian * math.sin(t * math.pi)
|
||||
|
||||
# 计算垂直于路径的方向(简单实现,可以改进为真正的 3D 垂直)
|
||||
# 这里假设偏移方向为 (1, 1, 1) 的某个分量,实际应根据路径方向计算
|
||||
x += offset * 0.577 # 0.577 ≈ 1 / sqrt(3)
|
||||
y += offset * 0.577
|
||||
z += offset * 0.577
|
||||
|
||||
points.append(RelativePos(x, y, z))
|
||||
|
||||
return points
|
||||
|
||||
'''def _Pos1ToPos2WithPoints(radios: int, pos1: RelativePos, pos2: RelativePos, *poses: RelativePos):
|
||||
if radios <= len(poses) + 2:
|
||||
raise ValueError("radios must be greater than len(poses) + 2")
|
||||
abs_pos1 = pos1.ToAbsolute()
|
||||
abs_poses = [p.ToAbsolute() for p in poses]
|
||||
abs_pos2 = pos2.ToAbsolute()
|
||||
all_points = [abs_pos1] + abs_poses + [abs_pos2]
|
||||
num_segments = len(all_points) - 1
|
||||
points_per_segment = (radios - num_segments + 1) // num_segments
|
||||
remainder = (radios - num_segments + 1) % num_segments
|
||||
points = []
|
||||
for i in range(num_segments):
|
||||
start = all_points[i]
|
||||
end = all_points[i + 1]
|
||||
current_points = points_per_segment + (1 if i < remainder else 0)
|
||||
delta_x = (float(end.x) - float(start.x)) / (current_points + 1)
|
||||
delta_y = (float(end.y) - float(start.y)) / (current_points + 1)
|
||||
delta_z = (float(end.z) - float(start.z)) / (current_points + 1)
|
||||
for j in range(1, current_points + 1):
|
||||
x = float(start.x) + delta_x * j
|
||||
y = float(start.y) + delta_y * j
|
||||
z = float(start.z) + delta_z * j
|
||||
points.append(RelativePos(x, y, z))
|
||||
return points'''
|
||||
Reference in New Issue
Block a user