[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Using Numeric & Surfarray with alpha values



Rene, thank you for your advice and tips on improving the
performance of our list comprehension, I've made the changes
you suggested. However, I am still trying to get this to
work with Numeric. What I'm trying to do is something along
the lines of:

pygame.surfarray.pixels_alpha(newimg)[:] /= (particle.decay
/ particle.life)

However, this crashes, with the error message: "return array
has incorrect type"

Any insights?

-Mike Rotondo


> >>> 200 * (50/100)
> 0
> >>> 200 * 50/100
> 100
> >>> 200 * (50/100.)
> 100.0
> 
> 
> Make an array of lifetime, and an array of decay with the
> same sized types compared to the alpha array.
> 
> 
> Note that:
> >>> 200 * 50
> 10000
> 
> You see that 10000 would overflow the 8bit of the alpha. 
> The alphas maximum value is 255.
> 
> There is also a precion problem with the other part.
> >>> 50 / 100
> 0
> >>> 50 / 100.
> 0.5
> 
> If you use floats then, you need to cast to int.  Which
> can be slow unless you use a fast-yet-inacurate float->int
> cast.
> 
> So...
> 
> You could instead use divides.
> 
> Because 200 * 0.5 is the same as 200 / 2
> 
> Divides are slow, however if you use divides you may be
> able to use less memory, which may therefore be faster. 
> As you don't need to have a big enough type to store eg.
> 200 * 50 -> 10000 like above.  You can also avoid
> float->int casts.
> 
> 
> Use *= or /= instead of * or /, so that no temporary
> arrays are allocated.  a = a * b will allocate a new
> array.  Whereas a *= b reuses the old memory.
> 
> 
> If the life, and decay don't change much, make an
> intermediate array.  Which I am assuming because mostly
> this is what happens.  Your particles may be different
> though.
> 
> 
> decay_life_array = decay_array / life_array
> 
> loop:
>     alpha_array /= decay_life_array
> 
> 
> 
> 
> 
> Here is the lifetime of a particle using your way.
> 
> >>> 200 * 50/100
> 100
> >>> 100 * 50/100
> 50
> >>> 50 * 50/100
> 25
> >>> 25 * 50/100
> 12
> >>> 12 * 50/100
> 6
> >>> 6 * 50/100
> 3
> >>> 3 * 50/100
> 1
> >>> 1 * 50/100
> 0
> >>> 0 * 50/100
> 0
> 
> 
> 
> 
> >>> 200 / (100 / 50)
> 100
> >>> 100 / (100 / 50)
> 50
> >>> 50 / (100 / 50)
> 25
> >>> 25 / (100 / 50)
> 12
> >>> 12 / (100 / 50)
> 6
> >>> 6 / (100 / 50)
> 3
> >>> 3 / (100 / 50)
> 1
> >>> 1 / (100 / 50)
> 0
> >>> 0 / (100 / 50)
> 0
> 
> 
> 
> An here is what would happen if you use floats.
> >>> 200 / (100 / 50.)
> 100.0
> >>> 100 / (100 / 50.)
> 50.0
> >>> 50 / (100 / 50.)
> 25.0
> >>> 25 / (100 / 50.)
> 12.5
> >>> 12.5 / (100 / 50.)
> 6.25
> >>> 6.25 / (100 / 50.)
> 3.125
> >>> 3.125 / (100 / 50.)
> 1.5625
> >>> 1.5625 / (100 / 50.)
> 0.78125
> >>> 0.78125 / (100 / 50.)
> 0.390625
> >>> 0.390625 / (100 / 50.)
> 0.1953125
> 
> 
> 
> Hopefully I haven't made any mistakes and wasted your time
> ;)
> 
> Cheers,
> 
> 
> On 11/27/05, Mike Rotondo <mr001m@xxxxxxxxxxxxxxxxxx>
> > wrote: We are writing a 2D particle engine and we would
> > like to render each particle with gradually decreasing
> > alpha values. However, our original image for the
> > particles has per-pixel alpha, so we can't use
> set-alpha. So, we are going to have to modify each pixel's
> > alpha value ith Numeric, it seems.
> >
> > We have a value for the time left for the particle to
> > live, named lifetime, and a value for how long it will
> > live, named decay. The value (lifetime/decay) is the
> > percent of the original alpha value we want to render
> each pixel with. So, if a pixel in the original image has
> > alpha 200, and a particular particle has lifetime 50 and
> > decay 100, we would want to render that pixel in that
> > particle with an alpha of 200 * (50/100) = 100.
> >
> > We are trying to do this with numeric & surfarray, but
> > are having trouble with array types. The best we've been
> > able to do is to create a list comprehension which does
> the job: >
> > [[pixel and (pixel * particle.life / particle.decay) for
> > pixl in row] for row in array]
> >
> > This uses short circuit evaluation and the fact that
> > booleans return the last object they looked at to return
> > either the pixel's alpha value if it is 0, or the
> pixel's alpha value times our percentage if it is not 0. >
> > array is pygame.surfarray.array_alpha(original_image)
> >
> > SO, my question is: What is the best way to translate
> > the above list comprehension into Numeric, so as to
> speed it up? >
> > Thanks,
> > Mike Rotondo
> >
>