Newbie question about updating multiple objects ...

Diez B. Roggisch deets at nospam.web.de
Thu Jun 8 04:29:49 EDT 2006


fivenastydisco at hotmail.com wrote:
> I've copied in the code I'm using below, as it's not very long -- can
> anyone help me?

I'll have some remarks:

 
> <--START-->
> 
> from visual import *
> from random import randrange # to create random numbers
> 
> numballs = 5 # number of balls
> balls = [] # a list to contain the balls
> 
> # set up a box to collide with
> side_length = 100
> minx = side_length * -10
> maxx = side_length * 10
> miny = side_length * -4
> maxy = side_length * 4
> 
> # create a wireframe of space
> left = curve(pos=[(minx, miny),(minx, maxy)], color = color.white)
> top = curve(pos = [(minx, maxy),(maxx, maxy)], color = color.white)
> right = curve(pos = [(maxx, maxy),(maxx, miny)], color = color.white)
> bottom = curve(pos = [(maxx, miny),(minx,miny)], color = color.white)
> 
> #create some balls
> for b in range(numballs): #  for each ball
>     x = randrange(minx, maxx)
>     y = randrange(miny, maxy)


Don't use range - use xrange. range actually creates a list of numbers,
where xrange creates a iterator that will just return the subsequent
numbers. The difference: the first solution consumes memory linear to the
number of numbers! 
 
>     balls.append(sphere(pos = (x,y), radius = 50, color = color.red)) #
> add balls
> 
> dt = 0.05 # time interval
> velocity = vector(2,0.2,1) # velocity of the balls
> 
> while (1==1): # forever ...
>     rate(50)
>     for b in range(numballs): # for each ball ...

This is a C-ism (or JAVA-ism if you like). The for-loop in python allows you
to iterate over objects in iterables. And list is one of those. So

for ball in balls:
    ball.x = ...

does the trick. And if you need an index, the commonly used idiom is

for i, ball in enumerate(balls):
    ...

>         if balls[b].x < minx: # check it hasn't overrun a boundary
>             balls[b].x = maxx
>         if balls[b].x > maxx:
>             balls[b].minx
>         if balls[b].y < miny:
>             balls[b].y = maxy
>         if balls[b].y > maxy:
>             balls[b].y = miny

You should do that checks above _after_ you changed the coordinates, not
before!
 
>         # NB betting this is where it's going wrong ...
>         balls[b].pos = balls[b].pos + (velocity * dt) # update the
> position of the ball

This could be the problem: you are using a python tuple and a vector object
and add them. Are you sure that works? The python tuples themselves
concatenate under the +-operator. So you'd create a large tuple of
coordinate differences here.

I suppose that using a vector for the coordinates or doing the calculation
component-wise will solve the problem.

HTH,

Diez
 



More information about the Python-list mailing list