Re: [pygame] QuadMap
by Dr0id other posts by this author
Aug 10 2007 6:39AM messages near this date
Re: [pygame] QuadMap
|
[pygame] dock icon causes bus error
Hi
Since you posted your quad stuff, I got an idea and now finally I had
the time to try it out. But I encountered some problems! It does not
work as I expect it to work.
The idea is to take an image, slice it into rectangles, then randomize
the egdgepoints of the rects and apply your quad code to the quads
(rects with randomized edgepoints). But sometimes it works, sometimes
not. Because I do not fully understand what you are exactly doing in the
quad code I ask you to take a look.
I see no reason why it should not work since I do exactly the same as
you have done in the last example (at least I think I do what you do).
If you set 'CHAOS' to 0 then it works perfectly, but is a bit boring
because it is without randomness.
As soon you set 'CHAOS'!=0 it does not work anymore! (hmm, sometimes
single quads work, but the rest does not....)
I have modified mesh to my needs.
Thanks.
~DR0ID
Kamilche schrieb:
> DR0ID wrote:
> > nice!
> >
> > Some comments would be appreciated. Is it an affine transformation?
> > The hit test look like raytracing code; how does it work?
> >
>
> Well, no can do - I'm looking stuff up in books and online, and barely
> understanding this myself. For instance - you must specify the
> quadrilateral corners in topleft, bottomleft, bottomright, topright
> order for the picture to be upright - why's that? Specifying them in a
> different order gives various flipping and mirroring effects... but
> sometimes it crashes. Anyways, if you can figure it out, let me know. :-D
>
> But what I can give you, is a more interesting version that textures
> the quadrilaterals.
>
> import pygame, math, Numeric
>
> WIDTH = 800
> HEIGHT = 600
>
> BLACK = ( 0, 0, 0, 255)
> WHITE = (255, 255, 255, 255)
> RED = (255, 0, 0, 255)
> YELLOW = (255, 255, 0, 255)
> BLUE = ( 0, 0, 255, 255)
> GREEN = ( 0, 255, 0, 255)
> GRAY = (212, 208, 200, 255)
> MAGENTA = (255, 0, 255, 255)
>
> class Mesh(object):
> quads = None
> texture = None
> posx = 0
> posy = 0
>
> def __init__(self):
> self.pic = pygame.Surface([WIDTH, HEIGHT], pygame.SRCALPHA,
> 32).convert_alpha()
> self.quads = []
>
> def Add(self, quads):
> self.quads.append(quads)
>
> def Texture(self, texture):
> quad = None
> w, h = self.pic.get_size()
> tw, th = texture.get_size()
> array = pygame.surfarray.pixels3d(texture)
> alpha = pygame.surfarray.pixels_alpha(texture)
> myarray = pygame.surfarray.pixels3d(self.pic)
> myalpha = pygame.surfarray.pixels_alpha(self.pic)
> for quad in self.quads:
> for y in range(quad.miny, quad.maxy):
> for x in range(quad.minx, quad.maxx):
> offset = quad.PointToOffset([x, y])
> if offset:
> x1 = int((tw-1) * offset[0])
> y1 = int((th-1) * offset[1])
> myarray[x, y] = array[x1, y1]
> myalpha[x, y] = alpha[x1, y1]
>
> def Draw(self, bg):
> bg.blit(self.pic, [self.posx, self.posy])
> for quad in self.quads:
> quad.Draw(bg)
>
> def PointToOffset(self, pos):
> for quad in self.quads:
> offset = quad.PointToOffset(pos)
> if offset:
> return offset
> return None
>
> def OffsetToPoint(self, offset):
> for quad in self.quads:
> quad.point = quad.OffsetToPoint(offset)
>
> class Quad(object):
> data = None
> point = None
>
> def __init__(self, p1, p2, p3, p4):
> self.p1 = list(p1)
> self.p2 = list(p2)
> self.p3 = list(p3)
> self.p4 = list(p4)
> self.polys = [self.p1, self.p2, self.p3, self.p4]
> self.minx = 99999
> self.maxx = -1
> self.miny = 99999
> self.maxy = -1
> for x, y in self.polys:
> self.minx = min(self.minx, x)
> self.maxx = max(self.maxx, x)
> self.miny = min(self.miny, y)
> self.maxy = max(self.maxy, y)
>
> def Draw(self, bg):
> pygame.draw.line(bg, RED, self.p1, self.p2, 1)
> pygame.draw.line(bg, YELLOW, self.p2, self.p3, 1)
> pygame.draw.line(bg, BLUE, self.p3, self.p4, 1)
> pygame.draw.line(bg, GREEN, self.p4, self.p1, 1)
> if self.point:
> pygame.draw.rect(bg, MAGENTA, [self.point[0]-2,
> self.point[1]-2, 4, 4], 0)
>
> def OffsetToPoint(self, offset):
> if offset == None:
> return None
> s, t = offset
> x1, y1 = self.p1
> x2, y2 = self.p2
> x3, y3 = self.p4
> x4, y4 = self.p3
> xa = x1 + t * (x2 - x1)
> ya = y1 + t * (y2 - y1)
> xb = x3 + t * (x4 - x3)
> yb = y3 + t * (y4 - y3)
> X = xa + s * (xb - xa)
> Y = ya + s * (yb - ya)
> return int(X), int(Y)
>
> def PointToOffset(self, pos):
> x, y = pos[0], pos[1]
> if not (x >= self.minx and x <= self.maxx and y >= self.miny
> and y <= self.maxy):
> return None
> x1, y1 = self.p1
> x2, y2 = self.p2
> x3, y3 = self.p4
> x4, y4 = self.p3
>
> Ax = x2 - x1
> Ay = y2 - y1
> Bx = x4 - x3
> By = y4 - y3
> Cx = x3 - x1
> Cy = y3 - y1
> Dx = x - x1
> Dy = y - y1
> Ex = Bx - Ax
> Ey = By - Ay
>
> a = -Ax * Ey + Ay * Ex
> b = Ey * Dx - Dy * Ex + Ay * Cx - Ax * Cy
> c = Dx * Cy - Dy * Cx
>
> det = b * b - 4 * a * c
> if det >= 0:
> if abs(a) < 0.001:
> t = -c / float(b)
> else:
> t = (-b - math.sqrt(det)) / float(2 * a)
> denom = (Cx + Ex * t)
> if denom > 0.01:
> s = (Dx - Ax * t) / float(denom)
> else:
> s = (Dy - Ay * t) / float(Cy + Ey * t)
>
> if (t >= 0) and (t <= 1) and (s >= 0) and (s <= 1):
> return s, t
>
> def LoadPic(filename = 'test2.jpg'):
> try:
> pic = pygame.image.load(filename).convert_alpha()
> except:
> pic = pygame.Surface([100, 100], pygame.SRCALPHA,
> 32).convert_alpha()
> pic.fill(RED, [0, 0, 50, 50])
> pic.fill(YELLOW, [50, 0, 50, 50])
> pic.fill(BLUE, [0, 50, 50, 50])
> pic.fill(GREEN, [50, 50, 50, 50])
> pic = AdjustAlpha(pic, .3)
> return pic
>
> def AdjustAlpha(pic, adj = .5):
> alphaarray = pygame.surfarray.array_alpha(pic).astype(Numeric.Float)
> alphaarray[:, :] = Numeric.clip(alphaarray * adj, 0, 255)
> pygame.surfarray.pixels_alpha(pic)[:, :] =
> alphaarray.astype(Numeric.UInt8)
> return pic
>
>
> def main():
> pygame.init()
> bg = pygame.display.set_mode([WIDTH, HEIGHT], 0, 32)
> quit = 0
> pic = LoadPic()
> mesh = Mesh()
> w, h = pic.get_size()
> x, y = 280, 20
> mesh.Add(Quad([x, y], [x, y+h], [x+w, y+h], [x+w, y]) )
> x, y = 280, 300
> mesh.Add(Quad([x, y+h], [x, y], [x+w, y], [x+w, y+h]) )
> x, y = 0, 400
> w, h = 200, 150
> mesh.Add(Quad([x+w, y], [x, y], [x, y+h], [x+w, y+h]) )
> mesh.Add(Quad([ 20, 50], [120, 30], [150, 110], [ 10, 130]) )
> mesh.Add(Quad([210, 170], [250, 260], [100, 240], [120, 150]) )
> if mesh.Texture(pic):
> pass
> else:
> while not quit:
> bg.fill(GRAY)
> mesh.Draw(bg)
> pygame.display.flip()
> pygame.event.pump()
> moved = 0
> for e in pygame.event.get():
> if e.type == pygame.QUIT:
> quit = 1
> break
> elif e.type == pygame.MOUSEMOTION:
> if not moved:
> moved = 1
> offset = mesh.PointToOffset(e.pos)
> mesh.OffsetToPoint(offset)
> pygame.quit()
>
>
> if __name__ == '__main__':
> main()
>
Thread:
Kamilche
Dr0id
Kamilche
Dr0id
|