rotate: add origin property + example in examples/canvas/rotation.py

This commit is contained in:
Mathieu Virbel 2013-05-05 10:08:21 +02:00
parent 5f70470117
commit 0c3c3e4f31
3 changed files with 82 additions and 5 deletions

View File

@ -0,0 +1,25 @@
from kivy.app import App
from kivy.lang import Builder
kv = '''
FloatLayout:
Button:
text: 'hello world'
size_hint: None, None
pos_hint: {'center_x': .5, 'center_y': .5}
canvas.before:
PushMatrix
Rotate:
angle: 45
origin: self.center
canvas.after:
PopMatrix
'''
class RotationApp(App):
def build(self):
return Builder.load_string(kv)
RotationApp().run()

View File

@ -60,7 +60,9 @@ cdef class Transform(MatrixInstruction):
cdef class Rotate(Transform):
cdef float _angle
cdef tuple _axis
cdef tuple _origin
cdef void apply(self)
cdef void compute(self)
cdef class Scale(Transform):
cdef float _x, _y, _z

View File

@ -561,32 +561,64 @@ cdef class Rotate(Transform):
afterwards with e.g.::
rot.angle = 90
rot.axis = (0,0,1)
rot.axis = (0, 0, 1)
'''
def __init__(self, *args, **kwargs):
Transform.__init__(self, **kwargs)
self._origin = (0, 0, 0)
# compatibility mode from version < 1.7
if len(args) == 4:
self.set(args[0], args[1], args[2], args[3])
self._angle = args[0]
self._axis = args[1:]
else:
self.set(0, 0, 0, 1)
self._angle = 0
self._axis = (0, 0, 1)
if 'axis' in kwargs:
self._axis = kwargs['axis']
if 'angle' in kwargs:
self._angle = kwargs['angle']
if 'origin' in kwargs:
self._origin = kwargs['origin']
self.compute()
def set(self, float angle, float ax, float ay, float az):
'''Set the angle and axis of rotation
>>> rotationobject.set(90, 0, 0, 1)
.. deprecated:: 1.7.0
The set() method doesn't use the new :data:`origin` property.
'''
self._angle = angle
self._axis = (ax, ay, az)
self.matrix = Matrix().rotate(radians(self._angle), ax, ay, az)
cdef void compute(self):
cdef float angle = self._angle
cdef float ax, ay, az, ox, oy, oz
ax, ay, az = self._axis
ox, oy, oz = self._origin
cdef Matrix matrix
matrix = Matrix().translate(ox, oy, oz)
matrix = matrix.multiply(Matrix().rotate(
radians(self._angle), ax, ay, az))
matrix = matrix.multiply(Matrix().translate(-ox, -oy, -oz))
self.matrix = matrix
property angle:
'''Property for getting/settings the angle of the rotation
'''
def __get__(self):
return self._angle
def __set__(self, a):
self.set(a, *self._axis)
self._angle = a
self.compute()
property axis:
'''Property for getting/settings the axis of the rotation
@ -596,8 +628,26 @@ cdef class Rotate(Transform):
def __get__(self):
return self._axis
def __set__(self, axis):
self.set(self._angle, *axis)
self._axis = axis
self.compute()
property origin:
'''Origin of the rotation
.. versionadded:: 1.7.0
The format of the origin can be either (x, y) or (x, y, z)
'''
def __get__(self):
return self._origin
def __set__(self, origin):
if len(origin) == 3:
self._origin = tuple(origin)
elif len(origin) == 2:
self._origin = (origin[0], origin[1], 0.)
else:
raise Exception('invalid number of components in origin')
self.compute()
cdef class Scale(Transform):