Points on and in spheres


#1

A small snippet that puts points on spheres and in spheres. For example to create a cloud of stars or solar systems.

prandom:
add randomly placed points on a sphere

pspiral:
add evenly distributed points on sphere

pcloud:
add points that fill a sphere(does a layered fill based on dist).
‘dist’ is the space between the points. To spread them more increase the dist, to cluster them up deacrease the dist.

import direct.directbase.DirectStart
from pandac.PandaModules import*

import random,math

smi=loader.loadModel('smiley')
base.cam.setY(-500)
base.win.setClearColor(VBase4(0,0,0,1))

def prandom(pnr,scale):
    x=y=z=w=t=0
    for nr in range(pnr):
        z=2.0*random.random()-1.0
        t=2.0*math.pi*random.random()
        w=math.sqrt(1-z*z)
        x=w*math.cos(t)
        y=w*math.sin(t)
        pt=render.attachNewNode('pt')
        smi.instanceTo(pt)
        pos=VBase3(x,y,z)*scale
        pt.setPos(pos)        
        
def pspiral(pnr,scale):    
    dl=math.pi*(3-math.sqrt(5))
    dz=2.0/pnr
    l=0.0
    z=1-dz/2.0
    for nr in range(pnr):
        r=math.sqrt(1-z*z)
        pos=VBase3(math.cos(l)*r,math.sin(l)*r,z)
        pt=render.attachNewNode('pt')
        smi.instanceTo(pt)
        pt.setPos(pos*scale)        
        z=z-dz
        l=l+dl

def pcloud(pnr,dist):
    parea=math.pi*dist*dist
    count=0
    pleft=pnr
    srad=2*dist
    doit=1
    while doit:
        sarea=4*math.pi*srad*srad
        pused=int(sarea/parea)
        if pused>pleft:
            pused=pleft
            doit=0
        else:
            pleft-=pused        
            if pleft==0:
                doit=0
        print 'layer:',count,'pused:',pused
        pspiral(pused,srad)
        #prandom(pused,srad)
        srad+=2*dist
        count+=1
    
    print 'count:',count
    
    biggest=parea*pnr
    srad=math.sqrt(biggest/4*math.pi)
    

#prandom(64,20)
#pspiral(64,20)
pcloud(512,40)

run()

Performance with a lot of particles.
flattenReallyStrong
#2

Useful. I don’t get why you don’t just do this instead

z = random.uniform(-1.0, 1.0)

#3

Coz i din’t know the .uniform :wink:

PS. random.uniform(-1,1) performes 1.5 times slower than 2*random.random()-1.0

Python is weird sometimes :wink:

import random,time

start=time.time()
nr=0
while 1:
    random.uniform(-1,1)
    nr+=1
    if time.time()-start>1:
        print nr
        break
    
start=time.time()
nr=0
while 1:
    2*random.random()-1.0
    nr+=1
    if time.time()-start>1:
        print nr
        break