开罗三角形渐变

时间:2014-08-06 00:36:01

标签: python cairo pycairo

我正试图渲染一个可爱的小直角三角形,带有斜边,我想围绕它的质心旋转。为此,我使用cairocffi在python中工作,cairocffi是cairo C库的python实现。

为了达到这个目的,我使用了3个从边缘定向并指向质心的线性渐变。通过这样做,我实现了以下目标:

enter image description here http://i.imgur.com/WswcCg6.png

此图像显示左侧的最终产品,以及我用于在右侧实现的构造线和阴影三角形线段。

我遇到的问题是在不同旋转角度下渐变的渲染行为不一致,因此当我将动画的图像串在一起时,渐变"抖动"在三角形内。您可以在以下链接中找到演示此行为的视频。如您所见,三角形边缘平滑流动,只有渐变抖动。

http://videobam.com/sXAoI#

我用来实现此目的的代码如下。非常感谢任何有关可能出现问题的帮助。

 import math
 import cairocffi as cairo
 import array

 def prism90(size, angle):

     DIMENSION = size
     height = 0.44

     data = array.array('c', chr(0) * DIMENSION * DIMENSION * 4)
     stride = DIMENSION * 4 
     surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, DIMENSION, DIMENSION, data, stride)
     # Context
     ctx = cairo.Context(surface)
     ctx.scale (DIMENSION, DIMENSION)
     # black background for .png
     ctx.rectangle (0, 0, 1, 1)
     ctx.set_source_rgba(0.0, 0.0, 0.0, 1.0)
     ctx.fill ()

     ctx.translate(0.5, 0.5)
     ctx.rotate(math.radians(angle))
     ctx.set_operator(cairo.OPERATOR_ADD)

     trigons = [
               [(0,0),(0,-height+height/2),( height,height/2)],
               [(0,0),(0,-height+height/2),(-height,height/2)],
               [(0,0),(height,   height/2),(-height,height/2)],
               ]

     gradients = [
                 ( height/2, 0, 0, height-height/2),
                 (-height/2, 0, 0, height-height/2),
                 (        0, height-height/2, 0, 0),
                 ]

     steps       = 3
     stop_start  = 0.01
     stop_inc    = 0.025
     alpha_start = 0.3
     alpha_inc   = 0.15
     shade       = 0.6

     for index, (points, gradient) in enumerate(zip(trigons, gradients)):

         if index == 2: # deeper gradient for hypotenuse trigon
             steps = steps*2-1
             alpha_start = 0.4
             alpha_inc = 0.05

         gradient = cairo.LinearGradient(*gradient)
         for step in xrange(0, steps, 1):
             stop = stop_start+stop_inc*step
             alpha = alpha_start+alpha_inc*step
             gradient.add_color_stop_rgba(stop, shade, shade, shade, alpha)


         ctx.set_source(gradient)
         ctx.move_to(*points[0])
         ctx.line_to(*points[1]) 
         ctx.line_to(*points[2]) 
         ctx.close_path()
         ctx.fill()
         shade = shade +0.1

     cols = [(1,0,0), (0,1,0), (0,0,1)]
     for grad, col in zip(gradients, cols):
         ctx.set_line_width(1./size*1)
         ctx.set_source_rgb(*col)
         ctx.move_to(grad[0], grad[1])
         ctx.line_to(grad[2], grad[3])
         ctx.stroke()

     surface.flush()
     surface.write_to_png ("prism90_"+str(angle)+".png")
     surface.finish()

     return data.tostring()

 angle = 0
 prism = prism90(250,angle)

0 个答案:

没有答案