顶点Path
仿照Qt中的PainterPath,实现顶点Path,用来绘制图形。
# 基本接口
class VertexPath:
def begin_path(self, pos = None, path_attr = PathAttr()):
def new_path(self, pos = None, path_attr = PathAttr()):
def end_path(self, pos = None):
def move_to(self, pos):
def quad_to(self, ctr_point, end_pos, samples = 16):
def cubic_to(self, ctr_point1, ctr_point2, end_pos, samples=32):
def circle_to(self, center, normal, radius, samples = 32, rot_offset_deg=0):
def arc_to(self, center, normal, angle_deg, samples = 32, bin=None, start = None):
def rect_to(self, center, width, height, h_axis, normal=None):
def rounded_rect_to(self, center, width, height, h_axis, normal=None, radii=(0.2,), samples = 8):
def polygon_to(self, points):
def ellipse_to(self, center, width, height, h_axis, normal=None, samples=64):
# 完整代码
######## Util ########
def vec_mul(v1, v2):
return Vector(x * y for x, y in zip(v1, v2))
def rotation_between(v1, v2, normal=None):
ang = math.degrees(v1.angle(v2))
if normal is not None and abs(ang-180) < 0.0001:
return Quaternion(normal, math.radians(ang))
return v1.rotation_difference(v2)
######## Util ########
class VertexPath:
class PathAttr:
def __init__(self, closed = True):
self.closed = closed
def __init__(self):
self.direction = None
self.pos = None
self.vert_series = VertexSeries()
self.cur_verts = []
self.began = False
self.path_attrs = []
def begin_path(self, pos = None, path_attr = PathAttr()):
if self.began:
print('path already began')
return
self.began = True
self.vert_series.add_verts(self.cur_verts)
if pos is not None:
self.move_to(pos)
self.path_attrs.append(path_attr)
return self
def new_path(self, pos = None, path_attr = PathAttr()):
self.end_path()
self.begin_path(pos, path_attr)
return self
def end_path(self, pos = None):
if not self.began:
print('path has not began yet')
return
if pos is not None:
self.move_to(pos)
self.began = False
self.cur_verts = []
return self
def ensure_began(self):
if not self.began:
print('path has not began yet')
return False
return True
def update_pos(self, pos):
last_pos = self.pos
self.pos = pos
if last_pos is not None:
self.direction = (Vector(self.pos) - Vector(last_pos)).normalized().to_tuple()
def move_to(self, pos):
if not self.ensure_began():
return
assert pos is not None
self.cur_verts.append(pos)
self.update_pos(pos)
return self
def quad_to(self, ctr_point, end_pos, samples = 16):
if not self.ensure_began():
return
if self.pos is None:
self.update_pos( (0, 0, 0) )
delta_t = 1.0