From 1ace31dfdf1d990950510cc08afb7061100a93c3 Mon Sep 17 00:00:00 2001 From: Gabriel Pettier Date: Fri, 26 Aug 2011 15:20:07 +0200 Subject: [PATCH] fixed bezier curves to use any number of points, updated example --- examples/canvas/bezier.py | 20 +++++++------- kivy/graphics/vertex_instructions.pyx | 39 ++++++++++++--------------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/examples/canvas/bezier.py b/examples/canvas/bezier.py index 6cc87ae44..c45eab42c 100644 --- a/examples/canvas/bezier.py +++ b/examples/canvas/bezier.py @@ -7,11 +7,18 @@ from kivy.graphics import Color, Line, Bezier, Ellipse, Line class BezierTest(Widget): def __init__(self, *args, **kwargs): super(BezierTest, self).__init__(*args, **kwargs) - print self.width, self.height self.d = 10 self.points = [ 0, 0, - self.width, 0, + 0.1 * self.width, 0.2 * self.height, + 0.2 * self.width, 0.3 * self.height, + 0.3 * self.width, 0.3 * self.height, + 0.4 * self.width, 0.4 * self.height, + 0.5 * self.width, 0.5 * self.height, + 0.6 * self.width, 0.6 * self.height, + 0.7 * self.width, 0.6 * self.height, + 0.8 * self.width, 0.7 * self.height, + 0.9 * self.width, 0.8 * self.height, self.width, self.height, 0, self.height] @@ -31,13 +38,8 @@ class BezierTest(Widget): pos=(p[0] - self.d/2, p[1] - self.d/2), size=(self.d, self.d)) - Line(points=( - self.points[0], self.points[1], - self.points[2], self.points[3])) - - Line(points=( - self.points[4], self.points[5], - self.points[6], self.points[7])) + Color(1.0, 0.0, 1.0) + Line(points=self.points) def on_touch_down(self, touch): diff --git a/kivy/graphics/vertex_instructions.pyx b/kivy/graphics/vertex_instructions.pyx index cc1281fff..4cfe20113 100644 --- a/kivy/graphics/vertex_instructions.pyx +++ b/kivy/graphics/vertex_instructions.pyx @@ -86,7 +86,6 @@ cdef class Bezier(VertexInstruction): :Parameters: `points`: list List of points in the format (x1, y1, x2, y2...) - only the 4 first points are used, to build a cubic bezier curve. `segments`: int, default to 180 Define how much segment is needed for drawing the ellipse. The drawing will be smoother if you have lot of segment. @@ -101,41 +100,37 @@ cdef class Bezier(VertexInstruction): self.batch.set_mode('line_strip') cdef void build(self): - cdef int i, count = self._segments + cdef int x, i, j cdef float l - cdef list p = self.points - cdef list P, Q, R, S, T, U - cdef tuple A, B, C, D + cdef list T cdef vertex_t *vertices = NULL cdef unsigned short *indices = NULL - vertices = malloc(count * sizeof(vertex_t)) + vertices = malloc(self._segments * sizeof(vertex_t)) if vertices == NULL: raise MemoryError('vertices') - indices = malloc(count * sizeof(unsigned short)) + indices = malloc(self._segments * sizeof(unsigned short)) if indices == NULL: free(vertices) raise MemoryError('indices') - A, B, C, D = zip(self.points[:8:2], self.points[1:8:2]) - for i in xrange(count): - l = i / (1.0 * self._segments) + for x in xrange(self._segments): + l = x / (1.0 * self._segments) - P = [A[0] + (B[0] - A[0]) * l, A[1] + (B[1] - A[1]) * l] - Q = [B[0] + (C[0] - B[0]) * l, B[1] + (C[1] - B[1]) * l] - R = [C[0] + (D[0] - C[0]) * l, C[1] + (D[1] - C[1]) * l] + T = [zip(self.points[::2], self.points[1::2]),] + for i in range(1, len(self.points)/2): + T.append([]) + for j in xrange(len(self.points)/2 - i): + T[i].append([ + T[i-1][j][0] + (T[i-1][j+1][0] - T[i-1][j][0]) * l, + T[i-1][j][1] + (T[i-1][j+1][1] - T[i-1][j][1]) * l]) - S = [P[0] + (Q[0] - P[0]) * l, P[1] + (Q[1] - P[1]) * l] - T = [Q[0] + (R[0] - Q[0]) * l, Q[1] + (R[1] - Q[1]) * l] + vertices[x].x = T[-1][0][0] + vertices[x].y = T[-1][0][1] + indices[x] = x - U = [S[0] + (T[0] - S[0]) * l, S[1] + (T[1] - S[1]) * l] - - vertices[i].x = U[0] - vertices[i].y = U[1] - indices[i] = i - - self.batch.set_data(vertices, count, indices, count) + self.batch.set_data(vertices, self._segments, indices, self._segments) free(vertices) free(indices)