[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] Using Numeric & Surfarray with alpha values
- To: pygame-users@xxxxxxxx
- Subject: Re: [pygame] Using Numeric & Surfarray with alpha values
- From: Rene Dudfield <renesd@xxxxxxxxx>
- Date: Sun, 27 Nov 2005 12:45:22 +1100
- Delivered-to: archiver@seul.org
- Delivered-to: pygame-users-outgoing@seul.org
- Delivered-to: pygame-users@seul.org
- Delivery-date: Sat, 26 Nov 2005 20:45:25 -0500
- Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=ToT9PZNykQc0kJL8L+ETLQpNj6YrdIB7qKgg9Sf82fYA9ET6cqO3OKuyAKpXaKQypDuxc9yN+Bq7XiUlGQL577VPKokay0C0ikR5ywBKwVioByc1E/Q0zNYVrr0IdxYl8nBZsIcpcXhhtlTDp9+DobI15YqNB44CJeXlRAmFAb0=
- In-reply-to: <4388EF90.6060603@mail.rochester.edu>
- References: <4388EF90.6060603@mail.rochester.edu>
- Reply-to: pygame-users@xxxxxxxx
- Sender: owner-pygame-users@xxxxxxxx
>>> 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
>