gyorgyf@5: #Copyright 2006 DR0ID http://mypage.bluewin.ch/DR0ID gyorgyf@5: # gyorgyf@5: # gyorgyf@5: # gyorgyf@5: """ gyorgyf@5: Allow to draw some gradients relatively easy. gyorgyf@5: """ gyorgyf@5: gyorgyf@5: __author__ = "$Author: DR0ID $" gyorgyf@5: __version__= "$Revision: 109 $" gyorgyf@5: __date__ = "$Date: 2007-08-09 20:33:32 +0200 (Do, 09 Aug 2007) $" gyorgyf@5: gyorgyf@5: import pygame gyorgyf@5: import math gyorgyf@5: gyorgyf@5: BLEND_MODES_AVAILABLE = False gyorgyf@5: vernum = pygame.vernum gyorgyf@5: if vernum[0]>=1 and vernum[1]>=8: gyorgyf@5: BLEND_MODES_AVAILABLE = True gyorgyf@5: gyorgyf@5: gyorgyf@5: class ColorInterpolator(object): gyorgyf@5: ''' gyorgyf@5: ColorInterpolator(distance, color1, color2, rfunc, gfunc, bfunc, afunc) gyorgyf@5: gyorgyf@5: interpolates a color over the distance using different functions for r,g,b,a gyorgyf@5: separately (a= alpha). gyorgyf@5: ''' gyorgyf@5: def __init__(self, distance, color1, color2, rfunc, gfunc, bfunc, afunc): gyorgyf@5: object.__init__(self) gyorgyf@5: gyorgyf@5: self.rInterpolator = FunctionInterpolator(color1[0], color2[0], distance, rfunc) gyorgyf@5: self.gInterpolator = FunctionInterpolator(color1[1], color2[1], distance, gfunc) gyorgyf@5: self.bInterpolator = FunctionInterpolator(color1[2], color2[2], distance, bfunc) gyorgyf@5: if len(color1)==4 and len(color2)==4: gyorgyf@5: self.aInterpolator = FunctionInterpolator(color1[3], color2[3], distance, afunc) gyorgyf@5: else: gyorgyf@5: self.aInterpolator = FunctionInterpolator(255, 255, distance, afunc) gyorgyf@5: gyorgyf@5: def eval(self, x): gyorgyf@5: ''' gyorgyf@5: eval(x) -> color gyorgyf@5: gyorgyf@5: returns the color at the position 0<=x<=d (actually not bound to this interval). gyorgyf@5: ''' gyorgyf@5: ## print "colorInterp x", x, self.rInterpolator.eval(x), self.gInterpolator.eval(x), self.bInterpolator.eval(x) gyorgyf@5: return [self.rInterpolator.eval(x), gyorgyf@5: self.gInterpolator.eval(x), gyorgyf@5: self.bInterpolator.eval(x), gyorgyf@5: self.aInterpolator.eval(x)] gyorgyf@5: gyorgyf@5: gyorgyf@5: gyorgyf@5: class FunctionInterpolator(object): gyorgyf@5: ''' gyorgyf@5: FunctionINterpolator(startvalue, endvalue, trange, func) gyorgyf@5: gyorgyf@5: interpolates a function y=f(x) in the range trange with gyorgyf@5: startvalue = f(0) gyorgyf@5: endvalue = f(trange) gyorgyf@5: using the function func gyorgyf@5: ''' gyorgyf@5: def __init__(self, startvalue, endvalue, trange, func): gyorgyf@5: object.__init__(self) gyorgyf@5: # function gyorgyf@5: self.func = func gyorgyf@5: # y-scaling gyorgyf@5: self.a = endvalue-startvalue gyorgyf@5: if self.a == 0: gyorgyf@5: self.a = 1. gyorgyf@5: # x-scaling gyorgyf@5: if trange!=0: gyorgyf@5: self.b = 1./abs(trange) gyorgyf@5: else: gyorgyf@5: self.b = 1. gyorgyf@5: # x-displacement gyorgyf@5: self.c = 0 gyorgyf@5: # y-displacement gyorgyf@5: self.d = min(max(startvalue,0),255) gyorgyf@5: gyorgyf@5: def eval(self, x): gyorgyf@5: ''' gyorgyf@5: eval(x)->float gyorgyf@5: gyorgyf@5: return value at position x gyorgyf@5: ''' gyorgyf@5: # make sure that the returned value is in [0,255] gyorgyf@5: ## return int(round(min(max(self.a*self.func(self.b*(x+self.c))+self.d, 0), 255))) gyorgyf@5: return int(min(max(self.a*self.func(self.b*(x+self.c))+self.d, 0), 255)) gyorgyf@5: gyorgyf@5: gyorgyf@5: gyorgyf@5: ##def gradient(surface, gyorgyf@5: ## startpoint, gyorgyf@5: ## endpoint, gyorgyf@5: ## startcolor, gyorgyf@5: ## endcolor, gyorgyf@5: ## Rfunc = (lambda x:x), gyorgyf@5: ## Gfunc = (lambda x:x), gyorgyf@5: ## Bfunc = (lambda x:x), gyorgyf@5: ## Afunc = (lambda x:1), gyorgyf@5: ## type = "line", gyorgyf@5: ## mode = None ): gyorgyf@5: ## ''' gyorgyf@5: ## surface : surface to draw on gyorgyf@5: ## startpoint: (x,y) point on surface gyorgyf@5: ## endpoint : (x,y) point on surface gyorgyf@5: ## startcolor: (r,g,b,a) color at startpoint gyorgyf@5: ## endcolor : (r,g,b,a) color at endpoint gyorgyf@5: ## Rfunc : function y = f(x) with startcolor =f(0) and endcolor = f(1) where 0 is at startpoint and 1 at endpoint gyorgyf@5: ## Gfunc : --- " --- gyorgyf@5: ## Bfunc : --- " --- gyorgyf@5: ## Afunc : --- " --- gyorgyf@5: ## these functions are evaluated in the range 0 <= x <= 1 and 0<= y=f(x) <= 1 gyorgyf@5: ## type : "line", "circle" or "rect" gyorgyf@5: ## mode : "+", "-", "*", None (how the pixels are drawen) gyorgyf@5: ## gyorgyf@5: ## returns : surface with the color characteristics w,h = (d, 256) and d = length of endpoint-startpoint gyorgyf@5: ## gyorgyf@5: ## ''' gyorgyf@5: ## dx = endpoint[0]-startpoint[0] gyorgyf@5: ## dy = endpoint[1]-startpoint[1] gyorgyf@5: ## d = int(round(math.hypot(dx, dy))) gyorgyf@5: ## angle = math.degrees( math.atan2(dy, dx) ) gyorgyf@5: ## gyorgyf@5: ## color = ColorInterpolator(d, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) gyorgyf@5: ## gyorgyf@5: ## if type=="line": gyorgyf@5: ## h = int(2.*math.hypot(*surface.get_size())) gyorgyf@5: ### bigSurf = pygame.Surface((d, h)).convert_alpha() gyorgyf@5: ## bigSurf = pygame.Surface((d, h), pygame.SRCALPHA)#.convert_alpha() gyorgyf@5: ### bigSurf = pygame.Surface((d, 1), pygame.SRCALPHA)#.convert_alpha() gyorgyf@5: ## bigSurf.lock() gyorgyf@5: ## bigSurf.fill((0,0,0,0)) gyorgyf@5: ## bigSurf.set_colorkey((0,0,0,0)) gyorgyf@5: ## for x in range(d): gyorgyf@5: ## pygame.draw.line(bigSurf, color.eval(x), (x,0), (x,h), 1) gyorgyf@5: ### for x in range(d): gyorgyf@5: ### bigSurf.set_at((x, 0), color.eval(x)) gyorgyf@5: ### bigSurf = pygame.transform.scale(bigSurf, (d, h)) gyorgyf@5: ## gyorgyf@5: ## bigSurf = pygame.transform.rotate(bigSurf, -angle) #rotozoom(bigSurf, -angle, 1) gyorgyf@5: ## bigSurf.set_colorkey((0,0,0, 0)) gyorgyf@5: ## rect = bigSurf.get_rect() gyorgyf@5: ## srect = pygame.Rect(rect) gyorgyf@5: ## dx = d/2. * math.cos(math.radians(angle)) gyorgyf@5: ## dy = d/2. * math.sin(math.radians(angle)) gyorgyf@5: ## rect.center = startpoint gyorgyf@5: ## rect.move_ip(dx, dy) gyorgyf@5: ## bigSurf.unlock() gyorgyf@5: ## gyorgyf@5: ## elif type=="circle": gyorgyf@5: ## bigSurf = pygame.Surface((2*d, 2*d)).convert_alpha() gyorgyf@5: ## bigSurf.fill((0,0,0,0)) gyorgyf@5: ## bigSurf.lock() gyorgyf@5: ## for x in range(d, 0, -1): gyorgyf@5: ## pygame.draw.circle(bigSurf, color.eval(x), (d,d), x) gyorgyf@5: ## bigSurf.unlock() gyorgyf@5: ## rect = bigSurf.get_rect() gyorgyf@5: ## srect = pygame.Rect(rect) gyorgyf@5: ## rect.center = (startpoint[0], startpoint[1]) gyorgyf@5: ## gyorgyf@5: ## elif type=="rect": gyorgyf@5: ## bigSurf = pygame.Surface((2*d, 2*d)).convert_alpha() gyorgyf@5: ## bigSurf.fill((0,0,0,0)) gyorgyf@5: ## c = bigSurf.get_rect().center gyorgyf@5: ## bigSurf.lock() gyorgyf@5: ## for x in range(d,-1,-1): gyorgyf@5: ## r = pygame.Rect(0,0,2*x,2*x) gyorgyf@5: ## r.center = c gyorgyf@5: ## pygame.draw.rect(bigSurf, color.eval(x), r) gyorgyf@5: ## bigSurf.unlock() gyorgyf@5: ## bigSurf = pygame.transform.rotozoom(bigSurf, -angle, 1) gyorgyf@5: ## bigSurf.set_colorkey((0,0,0, 0)) gyorgyf@5: ## gyorgyf@5: ## rect = bigSurf.get_rect() gyorgyf@5: ## srect = pygame.Rect(rect) gyorgyf@5: ## rect.center = startpoint gyorgyf@5: ## else: gyorgyf@5: ## raise NameError("type must be one of \"line\",\"circle\" or \"rect\"") gyorgyf@5: ## gyorgyf@5: ## if mode is None: gyorgyf@5: ## surface.blit(bigSurf, rect, srect) gyorgyf@5: ## else: gyorgyf@5: ## if mode=="+": gyorgyf@5: ## cf = pygame.color.add gyorgyf@5: ## elif mode=="*": gyorgyf@5: ## cf = pygame.color.multiply gyorgyf@5: ## elif mode=="-": gyorgyf@5: ## cf = pygame.color.subtract gyorgyf@5: ## else: gyorgyf@5: ## raise NameError("type must be one of \"+\", \"*\", \"-\" or None") gyorgyf@5: ## irect = surface.get_clip().clip(rect) gyorgyf@5: ## surface.lock() gyorgyf@5: ## for x in range(irect.left, irect.left+irect.width): gyorgyf@5: ## for y in range(irect.top, irect.top+irect.height): gyorgyf@5: ## surface.set_at((x,y), cf(surface.get_at((x,y)), bigSurf.get_at((x-rect.left, y-rect.top)) ) ) gyorgyf@5: ## surface.unlock() gyorgyf@5: ## gyorgyf@5: ## del bigSurf gyorgyf@5: ## char = pygame.Surface((d+1, 257)) gyorgyf@5: ### char.fill((0,0,0)) gyorgyf@5: ### ox = 0 gyorgyf@5: ### oldcol = color.eval(0) gyorgyf@5: ### for x in range(d): gyorgyf@5: ### col = color.eval(x) gyorgyf@5: ### pygame.draw.line(char, (255,0,0), (x, 256-col[0]), (ox, 256-oldcol[0])) gyorgyf@5: ### pygame.draw.line(char, (0,255,0), (x, 256-col[1]), (ox, 256-oldcol[1])) gyorgyf@5: ### pygame.draw.line(char, (0,0,255), (x, 256-col[2]), (ox, 256-oldcol[2])) gyorgyf@5: ### pygame.draw.line(char, (255,255,255), (x, 256-col[3]), (ox, 256-oldcol[3])) gyorgyf@5: ### ox = x gyorgyf@5: ### oldcol = col gyorgyf@5: ### gyorgyf@5: ## return char gyorgyf@5: gyorgyf@5: gyorgyf@5: gyorgyf@5: gyorgyf@5: def vertical(size, startcolor, endcolor): gyorgyf@5: """ gyorgyf@5: Draws a vertical linear gradient filling the entire surface. Returns a gyorgyf@5: surface filled with the gradient (numeric is only 2-3 times faster). gyorgyf@5: """ gyorgyf@5: height = size[1] gyorgyf@5: bigSurf = pygame.Surface((1,height)).convert_alpha() gyorgyf@5: dd = 1.0/height gyorgyf@5: sr, sg, sb, sa = startcolor gyorgyf@5: er, eg, eb, ea = endcolor gyorgyf@5: rm = (er-sr)*dd gyorgyf@5: gm = (eg-sg)*dd gyorgyf@5: bm = (eb-sb)*dd gyorgyf@5: am = (ea-sa)*dd gyorgyf@5: for y in range(height): gyorgyf@5: bigSurf.set_at((0,y), gyorgyf@5: (int(sr + rm*y), gyorgyf@5: int(sg + gm*y), gyorgyf@5: int(sb + bm*y), gyorgyf@5: int(sa + am*y)) gyorgyf@5: ) gyorgyf@5: return pygame.transform.scale(bigSurf, size) gyorgyf@5: gyorgyf@5: gyorgyf@5: def horizontal(size, startcolor, endcolor): gyorgyf@5: """ gyorgyf@5: Draws a horizontal linear gradient filling the entire surface. Returns a gyorgyf@5: surface filled with the gradient (numeric is only 2-3 times faster). gyorgyf@5: """ gyorgyf@5: width = size[0] gyorgyf@5: bigSurf = pygame.Surface((width, 1)).convert_alpha() gyorgyf@5: dd = 1.0/width gyorgyf@5: sr, sg, sb, sa = startcolor gyorgyf@5: er, eg, eb, ea = endcolor gyorgyf@5: rm = (er-sr)*dd gyorgyf@5: gm = (eg-sg)*dd gyorgyf@5: bm = (eb-sb)*dd gyorgyf@5: am = (ea-sa)*dd gyorgyf@5: for y in range(width): gyorgyf@5: bigSurf.set_at((y,0), gyorgyf@5: (int(sr + rm*y), gyorgyf@5: int(sg + gm*y), gyorgyf@5: int(sb + bm*y), gyorgyf@5: int(sa + am*y)) gyorgyf@5: ) gyorgyf@5: return pygame.transform.scale(bigSurf, size) gyorgyf@5: gyorgyf@5: gyorgyf@5: def radial(radius, startcolor, endcolor): gyorgyf@5: """ gyorgyf@5: Draws a linear raidal gradient on a square sized surface and returns gyorgyf@5: that surface. gyorgyf@5: """ gyorgyf@5: bigSurf = pygame.Surface((2*radius, 2*radius)).convert_alpha() gyorgyf@5: bigSurf.fill((0,0,0,0)) gyorgyf@5: dd = -1.0/radius gyorgyf@5: sr, sg, sb, sa = endcolor gyorgyf@5: er, eg, eb, ea = startcolor gyorgyf@5: rm = (er-sr)*dd gyorgyf@5: gm = (eg-sg)*dd gyorgyf@5: bm = (eb-sb)*dd gyorgyf@5: am = (ea-sa)*dd gyorgyf@5: gyorgyf@5: draw_circle = pygame.draw.circle gyorgyf@5: for rad in range(radius, 0, -1): gyorgyf@5: draw_circle(bigSurf, (er + int(rm*rad), gyorgyf@5: eg + int(gm*rad), gyorgyf@5: eb + int(bm*rad), gyorgyf@5: ea + int(am*rad)), (radius, radius), rad) gyorgyf@5: return bigSurf gyorgyf@5: gyorgyf@5: def squared(width, startcolor, endcolor): gyorgyf@5: """ gyorgyf@5: Draws a linear sqared gradient on a square sized surface and returns gyorgyf@5: that surface. gyorgyf@5: """ gyorgyf@5: bigSurf = pygame.Surface((width, width)).convert_alpha() gyorgyf@5: bigSurf.fill((0,0,0,0)) gyorgyf@5: dd = -1.0/(width/2) gyorgyf@5: sr, sg, sb, sa = endcolor gyorgyf@5: er, eg, eb, ea = startcolor gyorgyf@5: rm = (er-sr)*dd gyorgyf@5: gm = (eg-sg)*dd gyorgyf@5: bm = (eb-sb)*dd gyorgyf@5: am = (ea-sa)*dd gyorgyf@5: gyorgyf@5: draw_rect = pygame.draw.rect gyorgyf@5: for currentw in range((width/2), 0, -1): gyorgyf@5: pos = (width/2)-currentw gyorgyf@5: draw_rect(bigSurf, (er + int(rm*currentw), gyorgyf@5: eg + int(gm*currentw), gyorgyf@5: eb + int(bm*currentw), gyorgyf@5: ea + int(am*currentw)), pygame.Rect(pos, pos, 2*currentw, 2*currentw )) gyorgyf@5: return bigSurf gyorgyf@5: gyorgyf@5: gyorgyf@5: def vertical_func(size, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1)): gyorgyf@5: """ gyorgyf@5: Draws a vertical linear gradient filling the entire surface. Returns a gyorgyf@5: surface filled with the gradient (numeric is only 2x faster). gyorgyf@5: Rfunc, Gfunc, Bfunc and Afunc are function like y = f(x). They define gyorgyf@5: how the color changes. gyorgyf@5: """ gyorgyf@5: height = size[1] gyorgyf@5: bigSurf = pygame.Surface((1,height)).convert_alpha() gyorgyf@5: color = ColorInterpolator(height, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) gyorgyf@5: for y in range(0, height): gyorgyf@5: bigSurf.set_at((0,y), color.eval(y+0.1)) gyorgyf@5: return pygame.transform.scale(bigSurf, size) gyorgyf@5: gyorgyf@5: gyorgyf@5: def horizontal_func(size, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1)): gyorgyf@5: """ gyorgyf@5: Draws a horizontal linear gradient filling the entire surface. Returns a gyorgyf@5: surface filled with the gradient (numeric is only 2x faster). gyorgyf@5: Rfunc, Gfunc, Bfunc and Afunc are function like y = f(x). They define gyorgyf@5: how the color changes. gyorgyf@5: """ gyorgyf@5: width = size[0] gyorgyf@5: bigSurf = pygame.Surface((width, 1)).convert_alpha() gyorgyf@5: color = ColorInterpolator(width, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) gyorgyf@5: for y in range(0, width): gyorgyf@5: bigSurf.set_at((y, 0), color.eval(y+0.1)) gyorgyf@5: return pygame.transform.scale(bigSurf, size) gyorgyf@5: gyorgyf@5: def radial_func(radius, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), colorkey=(0,0,0,0)): gyorgyf@5: """ gyorgyf@5: Draws a linear raidal gradient on a square sized surface and returns gyorgyf@5: that surface. gyorgyf@5: """ gyorgyf@5: bigSurf = pygame.Surface((2*radius, 2*radius)).convert_alpha() gyorgyf@5: if len(colorkey)==3: gyorgyf@5: colorkey += (0,) gyorgyf@5: bigSurf.fill(colorkey) gyorgyf@5: color = ColorInterpolator(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) gyorgyf@5: draw_circle = pygame.draw.circle gyorgyf@5: for rad in range(radius, 0, -1): gyorgyf@5: draw_circle(bigSurf, color.eval(rad), (radius, radius), rad) gyorgyf@5: return bigSurf gyorgyf@5: gyorgyf@5: def radial_func_offset(radius, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), colorkey=(0,0,0,0), offset=(0,0)): gyorgyf@5: """ gyorgyf@5: Draws a linear raidal gradient on a square sized surface and returns gyorgyf@5: that surface. gyorgyf@5: offset is the amount the center of the gradient is displaced of the center of the image. gyorgyf@5: Unfotunately this function ignores alpha. gyorgyf@5: """ gyorgyf@5: bigSurf = pygame.Surface((2*radius, 2*radius))#.convert_alpha() gyorgyf@5: gyorgyf@5: mask = pygame.Surface((2*radius, 2*radius), pygame.SRCALPHA)#.convert_alpha() gyorgyf@5: mask.fill(colorkey) gyorgyf@5: mask.set_colorkey((255,0,255)) gyorgyf@5: pygame.draw.circle(mask, (255,0,255), (radius, radius), radius) gyorgyf@5: gyorgyf@5: if len(colorkey)==3: gyorgyf@5: colorkey += (0,) gyorgyf@5: bigSurf.fill(colorkey) gyorgyf@5: gyorgyf@5: color = ColorInterpolator(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) gyorgyf@5: draw_circle = pygame.draw.circle gyorgyf@5: radi = radius + int(math.hypot(offset[0], offset[1])+1) gyorgyf@5: for rad in range(radi, 0, -1): gyorgyf@5: draw_circle(bigSurf, color.eval(rad), (radius+offset[0], radius+offset[1]), rad) gyorgyf@5: gyorgyf@5: bigSurf.blit(mask, (0,0)) gyorgyf@5: bigSurf.set_colorkey(colorkey) gyorgyf@5: return bigSurf gyorgyf@5: gyorgyf@5: gyorgyf@5: def squared_func(width, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), offset=(0,0)): gyorgyf@5: """ gyorgyf@5: Draws a linear sqared gradient on a square sized surface and returns gyorgyf@5: that surface. gyorgyf@5: """ gyorgyf@5: bigSurf = pygame.Surface((width, width)).convert_alpha() gyorgyf@5: bigSurf.fill((0,0,0,0)) gyorgyf@5: color = ColorInterpolator(width/2, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) gyorgyf@5: draw_rect = pygame.draw.rect gyorgyf@5: widthh = width+2*int(max(abs(offset[0]),abs(offset[1]))) gyorgyf@5: for currentw in range((widthh/2), 0, -1): gyorgyf@5: ## pos = (width/2)-currentw gyorgyf@5: rect = pygame.Rect(0, 0, 2*currentw, 2*currentw ) gyorgyf@5: rect.center = (width/2+offset[0], width/2+offset[1]) gyorgyf@5: draw_rect(bigSurf, color.eval(currentw), rect) gyorgyf@5: return bigSurf gyorgyf@5: gyorgyf@5: def draw_gradient(surface, startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), mode=0): gyorgyf@5: """ gyorgyf@5: Instead of returning an Surface, this function draw it directy onto the gyorgyf@5: given Surface and returns the rect. gyorgyf@5: """ gyorgyf@5: dx = endpoint[0]-startpoint[0] gyorgyf@5: dy = endpoint[1]-startpoint[1] gyorgyf@5: d = int(round(math.hypot(dx, dy))) gyorgyf@5: angle = math.degrees( math.atan2(dy, dx) ) gyorgyf@5: gyorgyf@5: h = int(2.*math.hypot(*surface.get_size())) gyorgyf@5: gyorgyf@5: bigSurf = horizontal_func((d,h), startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) gyorgyf@5: gyorgyf@5: ## bigSurf = pygame.transform.rotate(bigSurf, -angle) #rotozoom(bigSurf, -angle, 1) gyorgyf@5: bigSurf = pygame.transform.rotozoom(bigSurf, -angle, 1) gyorgyf@5: ## bigSurf.set_colorkey((0,0,0, 0)) gyorgyf@5: rect = bigSurf.get_rect() gyorgyf@5: srect = pygame.Rect(rect) gyorgyf@5: dx = d/2. * math.cos(math.radians(angle)) gyorgyf@5: dy = d/2. * math.sin(math.radians(angle)) gyorgyf@5: rect.center = startpoint gyorgyf@5: rect.move_ip(dx, dy) gyorgyf@5: if BLEND_MODES_AVAILABLE: gyorgyf@5: return surface.blit(bigSurf, rect, None, mode) gyorgyf@5: else: gyorgyf@5: return surface.blit(bigSurf, rect) gyorgyf@5: gyorgyf@5: gyorgyf@5: def draw_circle(surface, startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), mode=0): gyorgyf@5: """ gyorgyf@5: Instead of returning an Surface, this function draw it directy onto the gyorgyf@5: given Surface and returns the rect. gyorgyf@5: """ gyorgyf@5: dx = endpoint[0]-startpoint[0] gyorgyf@5: dy = endpoint[1]-startpoint[1] gyorgyf@5: radius = int(round(math.hypot(dx, dy))) gyorgyf@5: pos = (startpoint[0]-radius, startpoint[1]-radius) gyorgyf@5: if BLEND_MODES_AVAILABLE: gyorgyf@5: return surface.blit(radial_func(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc), pos, None, mode) gyorgyf@5: else: gyorgyf@5: return surface.blit(radial_func(radius, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc), pos) gyorgyf@5: gyorgyf@5: def draw_squared(surface, startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), mode=0): gyorgyf@5: """ gyorgyf@5: Instead of returning an Surface, this function draw it directy onto the gyorgyf@5: given Surface and returns the rect. gyorgyf@5: """ gyorgyf@5: dx = endpoint[0]-startpoint[0] gyorgyf@5: dy = endpoint[1]-startpoint[1] gyorgyf@5: angle = math.degrees( math.atan2(dy, dx) ) gyorgyf@5: width = 2*int(round(math.hypot(dx, dy))) gyorgyf@5: gyorgyf@5: bigSurf = squared_func(width, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) gyorgyf@5: gyorgyf@5: bigSurf = pygame.transform.rotozoom(bigSurf, -angle, 1) gyorgyf@5: ## bigSurf.set_colorkey((0,0,0, 0)) gyorgyf@5: rect = bigSurf.get_rect() gyorgyf@5: rect.center = startpoint gyorgyf@5: if BLEND_MODES_AVAILABLE: gyorgyf@5: return surface.blit(bigSurf, rect, None, mode) gyorgyf@5: else: gyorgyf@5: return surface.blit(bigSurf, rect) gyorgyf@5: gyorgyf@5: gyorgyf@5: def chart(startpoint, endpoint, startcolor, endcolor, Rfunc = (lambda x:x), Gfunc = (lambda x:x), Bfunc = (lambda x:x), Afunc = (lambda x:1), scale=None): gyorgyf@5: """ gyorgyf@5: This returns a Surface where the change of the colors over the distance gyorgyf@5: (the width of the image) is showen as a line. gyorgyf@5: scale: a float, 1 is not scaling gyorgyf@5: """ gyorgyf@5: dx = endpoint[0]-startpoint[0] gyorgyf@5: dy = endpoint[1]-startpoint[1] gyorgyf@5: distance = int(round(math.hypot(dx, dy))) gyorgyf@5: color = ColorInterpolator(distance, startcolor, endcolor, Rfunc, Gfunc, Bfunc, Afunc) gyorgyf@5: bigSurf = pygame.Surface((distance, 256)) gyorgyf@5: bigSurf.fill((0,)*3) gyorgyf@5: oldcol = color.eval(0) gyorgyf@5: for x in range(distance): gyorgyf@5: r, g, b, a = color.eval(x) gyorgyf@5: pygame.draw.line(bigSurf, (255, 0, 0, 128), (x-1, oldcol[0]), (x, r)) gyorgyf@5: pygame.draw.line(bigSurf, (0, 255, 0, 128), (x-1, oldcol[1]), (x, g)) gyorgyf@5: pygame.draw.line(bigSurf, (0, 0, 255, 128), (x-1, oldcol[2]), (x, b)) gyorgyf@5: pygame.draw.line(bigSurf, (255, 255, 255, 128), (x-1, oldcol[3]), (x, a)) gyorgyf@5: oldcol = (r,g,b,a) gyorgyf@5: if scale: gyorgyf@5: ## return pygame.transform.scale(bigSurf, size) gyorgyf@5: return pygame.transform.rotozoom(bigSurf, 0, scale) gyorgyf@5: return pygame.transform.flip(bigSurf, 0, 1) gyorgyf@5: #------------------------------------------------------------------------------ gyorgyf@5: gyorgyf@5: gyorgyf@5: gyorgyf@5: gyorgyf@5: def genericFxyGradient(surf, clip, color1, color2, func, intx, yint, zint=None): gyorgyf@5: """ gyorgyf@5: genericFxyGradient(size, color1, color2,func, intx, yint, zint=None) gyorgyf@5: gyorgyf@5: some sort of highfield drawer :-) gyorgyf@5: gyorgyf@5: surf : surface to draw gyorgyf@5: clip : rect on surf to draw in gyorgyf@5: color1 : start color gyorgyf@5: color2 : end color gyorgyf@5: func : function z = func(x,y) gyorgyf@5: xint : interval in x direction where the function is evaluated gyorgyf@5: yint : interval in y direction where the function is evaluated gyorgyf@5: zint : if not none same as yint or xint, if None then the max and min value gyorgyf@5: of func is taken as z-interval gyorgyf@5: gyorgyf@5: color = a*func(b*(x+c), d*(y+e))+f gyorgyf@5: """ gyorgyf@5: # make shure that x1