Kivy - Bezier
在本章中,我们将创建一个 Kivy 应用,它将以交互方式沿着点列表绘制一条贝塞尔线。如果使用以下代码段计算出的 x 和 y 坐标绘制一条闭合线,则生成的图形类似于吃豆人角色 −
from math import cos, sin, radians x = y = 300 z = 200 self.points = [x, y] for i in range(45, 360, 45): i = radians(i) self.points.extend([x + cos(i) * z, y + sin(i) * z]) with self.layout.canvas: Color(1.0, 0.0, 1.0) self.line = Line( points=self.points + self.points[:2], dash_offset=10, dash_length=100 )
它生成如下的线条图案 −
然后,我们利用相同的点列表绘制一条贝塞尔线。
Color(1.0, 0.0, 1.0) self.line = Line( points=self.points + self.points[:2], dash_offset=0, dash_length=100 )
Line 和 Beizer 将显示为 −
现在我们要动态构建这两条曲线。 我们使用两个滑块来更改直线指令和贝塞尔指令的虚线长度和偏移值,因为每个滑块的值属性随着 以下事件处理程序 −
def _set_bezier_dash_offset(self, instance, value): # effect to reduce length while increase offset self.bezier.dash_length = 100 - value self.bezier.dash_offset = value def _set_line_dash_offset(self, instance, value): # effect to reduce length while increase offset self.line.dash_length = 100 - value self.line.dash_offset = value
因此,更改滑块值以查看两条曲线如何动态重绘。
示例
下面给出了完整代码 −
from kivy.app import App from kivy.uix.floatlayout import FloatLayout from kivy.uix.label import Label from kivy.uix.slider import Slider from kivy.graphics import Color, Bezier, Line from kivy.core.window import Window Window.size = (720,400) class Main(App): title='Bezier Example' def _set_bezier_dash_offset(self, instance, value): # effect to reduce length while increase offset self.bezier.dash_length = 100 - value self.bezier.dash_offset = value def _set_line_dash_offset(self, instance, value): # effect to reduce length while increase offset self.line.dash_length = 100 - value self.line.dash_offset = value def build(self): from math import cos, sin, radians x = y = 300 z = 200 # Pacman ! self.points = [x, y] for i in range(45, 360, 45): i = radians(i) self.points.extend([x + cos(i) * z, y + sin(i) * z]) print (self.points) self.layout = FloatLayout() with self.layout.canvas: Color(1.0, 0.0, 0.0) self.bezier = Bezier( points=self.points, segments=150, loop=True, dash_length=100, dash_offset=10 ) Color(1.0, 0.0, 1.0) self.line = Line( points=self.points + self.points[:2], dash_offset=10, dash_length=100) l1=Label( text='Beizer offset', pos_hint={'x':.1}, size_hint=(.1, None), height=50 ) self.layout.add_widget(l1) s1 = Slider( y=0, pos_hint={'x': .3}, size_hint=(.7, None), height=50 ) self.layout.add_widget(s1) s1.bind(value=self._set_bezier_dash_offset) l2=Label( text='Line offset', y=50, pos_hint={'x':.1}, size_hint=(.1, None), height=50 ) self.layout.add_widget(l2) s2 = Slider( y=50, pos_hint={'x': .3}, size_hint=(.7, None), height=50 ) self.layout.add_widget(s2) s2.bind(value=self._set_line_dash_offset) return self.layout if __name__ == '__main__': Main().run()
输出
下面的屏幕截图显示了两个不同滑块位置&minus的曲线;