Trouble with orbits

9 views
Skip to first unread message

Richard Jones

unread,
Aug 30, 2009, 10:20:58 PM8/30/09
to General discussion of the Lepton particle engine for Python
Hi there, I'm trying to create an effect for PyWeek which has
particles oribiting around each other. To this end I've written the
pasted code below. My problem is that the magnet appears to do
nothing. The particles just expand from their initial position
unhindered. I've tried various values of charge.

Any ideas?


Richard



import pyglet
from pyglet.gl import *

from lepton import ParticleGroup, Particle
from lepton import controller, domain, renderer, texturizer
from lepton.emitter import StaticEmitter
from lepton.domain import Point, Disc

window = pyglet.window.Window()

x, y = 200, 200
emitter = StaticEmitter(
template = Particle(
position=(x, y, 0),
color=(1, 1, 1, .5),
velocity=(0, 0, 0),
),
velocity=Disc((0,0,0), (0,0,1), 50, 50),
)
center = Point((x, y, 0))
group = ParticleGroup(
controllers=[
emitter,
controller.Movement(),
controller.Magnet(center, charge=1000),
]
)
emitter.emit(10, group)

t = texturizer.create_point_texture(16, 1)
t = texturizer.SpriteTexturizer(t)
group.renderer = renderer.PointRenderer(10, t)

@window.event
def on_draw():
window.clear()
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE)
group.draw()

pyglet.clock.schedule_interval(group.update, 1/60.)
pyglet.app.run()

Casey Duncan

unread,
Aug 31, 2009, 3:22:50 AM8/31/09
to py-lept...@googlegroups.com
I tried it with a much higher charge (around 30-50k) and a fairly high
epsilon (around 5) and he particles stayed clumped pretty well around
the magnet. Without the epsilon, the forces get too large and tend to
launch the particles off faster than the escape velocity. You could
also introduce a drag controller or set a max velocity with the
movement controller to keep velocities in check.

I also added a deviation to the velocity to make them "orbit"
otherwise they just travel radially from the center. Something like
this:

emitter = StaticEmitter(
template = Particle(
position=(x, y, 0),
color=(1, 1, 1, .5),
velocity=(0, 0, 0),
),
velocity=Disc((0,0,0), (0,0,1), 50, 50),
deviation = Particle(
velocity=(10, 10, 0),
),
)

Glad to see you using lepton for pyweek. If you need any other help
getting a particular look or effect right, let me know.

hth,

-Casey

Andrew Charles

unread,
Aug 31, 2009, 3:51:14 AM8/31/09
to py-lept...@googlegroups.com
To get a clean orbit the velocity of the particles should be
perpendicular to the force, which points towards the controller's
position. I think you can accomplish this by setting the disc's normal
vector so that it's parallel to the particle positions:

velocity=Disc((0,0,0), (1,1,0), 50, 50),

Casey has done this by adding deviations in the x and y directions.
This will create a kind of disordered spirally orbit, like in the
magnet example. If you want a circular orbit you'll need to make it
exactly perpendicular.

The integrator is just Euler from memory, so expect even a perfectly
initialised orbit to spiral in or out if the particles are allowed to
live long enough.

-Andrew C

Richard Jones

unread,
Aug 31, 2009, 3:52:43 AM8/31/09
to General discussion of the Lepton particle engine for Python
On Aug 31, 5:22 pm, Casey Duncan <casey.dun...@gmail.com> wrote:
> I tried it with a much higher charge (around 30-50k) and a fairly high
> epsilon (around 5) and he particles stayed clumped pretty well around
> the magnet. Without the epsilon, the forces get too large and tend to
> launch the particles off faster than the escape velocity. You could
> also introduce a drag controller or set a max velocity with the
> movement controller to keep velocities in check.

Thanks for the help - I ended up stumbling on the Clumper and am using
that instead (with an emitter and collector) which generates a
pleasing effect. It also has the benefit of fading away automatically
when turned off.

I'm now stuck on something else. pydoc doesn't seem to work on some of
the C modules and I'm hesitant to read the C module source to figure
this out... so I'm a little confused about how to get an image in as
the texture for my particles. I've tried substituting my
create_point_texture()'ed images I've been using, but the resulting
particle is about 1px in size. If I bump the (I presume it's a size
argument) first argument to PointRenderer way up to 64 (the image is
only 16x16) then I start to see more than 1 pixel. At 128 I still only
see a couple pixels. Still not the whole image. My code looks
something like this:

zap_tex = pyglet.resource.image('zap-star.png').get_texture()
zap_texturizer = texturizer.SpriteTexturizer(zap_tex.id)
...
group.renderer = renderer.PointRenderer(64, zap_texturizer)


Richard

Richard Jones

unread,
Aug 31, 2009, 3:56:26 AM8/31/09
to General discussion of the Lepton particle engine for Python
On Aug 31, 5:52 pm, Richard Jones <r1chardj0...@gmail.com> wrote:
> zap_tex = pyglet.resource.image('zap-star.png').get_texture()
> zap_texturizer = texturizer.SpriteTexturizer(zap_tex.id)
> ...
> group.renderer = renderer.PointRenderer(64, zap_texturizer)

Oh, I noticed BillboardRenderer in some of the examples but I don't
know how to use it - when I try it:

group.renderer = renderer.BillboardRenderer(zap_texturizer)

nothing is drawn at all.


Richard

Casey Duncan

unread,
Aug 31, 2009, 12:02:25 PM8/31/09
to py-lept...@googlegroups.com
Fwiw, I'm going to work on some better docs for the texturizers, I've
been a bit slack on that for 1.0. In the mean time you can use the
python help() built-in to get at the docstrings, which should be
helpful.

I suspect the reason that the billboard renderer is not drawing
anything is because the particles have no size. The point renderer is
a fixed size for the entire group, but the billboard renderer uses the
individual particle sizes. Try adding a size=(5,5,0) or something to
you emitter template particle.

I'm not sure why the point renderer is not working as expected. It
just uses point sprites when textured, so it should use the entire
texture. If you like, send me the image off-list and I will test it
out.

The Clumper controller is kinda half-baked, but I'm glad you find it
helpful. It just attracts particles to the average center point for
the group.

-Casey

Casey Duncan

unread,
Aug 31, 2009, 12:03:59 PM8/31/09
to py-lept...@googlegroups.com

A better integrator is on my short-list for new features. Euler is
pretty bad when magnets are involved.

-Casey

Richard Jones

unread,
Aug 31, 2009, 6:37:01 PM8/31/09
to General discussion of the Lepton particle engine for Python
On Sep 1, 2:02 am, Casey Duncan <casey.dun...@gmail.com> wrote:
> I suspect the reason that the billboard renderer is not drawing
> anything is because the particles have no size. The point renderer is
> a fixed size for the entire group, but the billboard renderer uses the
> individual particle sizes. Try adding a size=(5,5,0) or something to
> you emitter template particle.

Thanks for your hint here and encouragement; I tried a few things out
and one reason I wasn't seeing anything correctly was because there's
a bug in pyglet's resource.image loader. Avoiding that I see my effect
just right! Now to figure out how rotation / up work :)


Richard

Richard Jones

unread,
Aug 31, 2009, 8:44:09 PM8/31/09
to py-lept...@googlegroups.com
On 01/09/2009, at 8:37 AM, Richard Jones wrote:
> On Sep 1, 2:02 am, Casey Duncan <casey.dun...@gmail.com> wrote:
>> I suspect the reason that the billboard renderer is not drawing
>> anything is because the particles have no size. The point renderer is
>> a fixed size for the entire group, but the billboard renderer uses
>> the
>> individual particle sizes. Try adding a size=(5,5,0) or something to
>> you emitter template particle.
>
> Thanks for your hint here and encouragement; I tried a few things out
> and one reason I wasn't seeing anything correctly was because there's
> a bug in pyglet's resource.image loader.

Or at least there's a bug in the interaction between textures loaded
by pyglet. resource.image and lepton's texturizer. Probably something
to do with the subtexture stuff due to resource using texture atlases.
No time to look into it right now :(


Richard

Casey Duncan

unread,
Aug 31, 2009, 9:34:36 PM8/31/09
to py-lept...@googlegroups.com

Yeah, the pyglet resource images are a bit high-level for use directly
in texturizers without more hinting. To make them work you would need
to pass in the texture id and the texture coordinates. When passing
just the id, the texturizer assumes it should apply the whole texture
to the particles. However custom texture coordinates will only work
with the billboard renderer because the point renderer just uses point
sprites, and afaik you cannot specify texture coordinates for those.

-Casey

Richard Jones

unread,
Sep 1, 2009, 2:29:26 AM9/1/09
to py-lept...@googlegroups.com
On 01/09/2009, at 11:34 AM, Casey Duncan wrote:
> Yeah, the pyglet resource images are a bit high-level for use directly
> in texturizers without more hinting. To make them work you would need
> to pass in the texture id and the texture coordinates. When passing
> just the id, the texturizer assumes it should apply the whole texture
> to the particles. However custom texture coordinates will only work
> with the billboard renderer because the point renderer just uses point
> sprites, and afaik you cannot specify texture coordinates for those.

It'd be awesome to be able to supply a pyglet texture object (or
anything that has a texture id and tex_coords) - pyglet's resource
module automatic texture atlas packing is really nice and saves on
texture context swapping.


Richard

Casey Duncan

unread,
Sep 1, 2009, 11:40:51 AM9/1/09
to py-lept...@googlegroups.com

Yeah, it should be easy to add an alternate SpriteTexturizer
constructor that takes an arbitrary pyglet texture object and does the
right thing. I'll look into that.

-Casey

Reply all
Reply to author
Forward
0 new messages