How to filter points based on distance from sphere center?

Hey guys, so I have a sphere and three types of curves intersecting the sphere. I have populated the curves with points and would like to filter out those points based on their distance from the spheres center. Once I filter those points (between a radius of 40 and 50 from sphereCenter) I want to randomly connect 3 points with a crv. Right now I’m not sure how to filter the list of points…

script below

#Random Numbers
#Random Lines

import rhinoscriptsyntax as rs
import random as rnd

sphereCenter = [50,50,50]

sphere = rs.AddSphere(sphereCenter,45)

rs.EnableRedraw(False)

pts = []

for i in range(0,100):
    #coordinates
    x = rnd.uniform(0,100)
    y = rnd.uniform(0,100)
    z = rnd.uniform(0,100)
    pt = [x,y,z]
    
    pts.append(pt)
    
pl = rs.AddPolyline(pts)
crv = rs.AddCurve(pts)
intpcrv = rs.AddInterpCurve(pts)
 
color01 = [0,255,255]
color02 = [255,0,255]
color03 = [255,255,0]
 
rs.ObjectColor(pl, color01)
rs.ObjectColor(crv, color02)
rs.ObjectColor(intpcrv, color03)

pt = []

pt1 = pt.append(rs.DivideCurve(pl,5000,True,True))
pt2 = pt.append(rs.DivideCurve(crv,5000,True,True))
pt3 = pt.append(rs.DivideCurve(intpcrv,5000,True,True))













#rs.GetPoint(sphereCenter, [pt], 45)

#if pt.x or pt.y or pt.z <= 45:
#    rs.AddSphere([pt],5)
#else:
#    rs.DeleteObjects([pt])

#rs.GetPointOnSurface(sphere, None)

Hi,

You might try editing your post to better format your script and make it more readable:

3 backticks and “python”

  • script -
    3 backticks

i.e.

```python
<paste script in here>
```

Someone will have a look. You want just the points between 40 and 50 units from the center then take 3 random from there?

–Mitch

Here’s something that works I think:

import rhinoscriptsyntax as rs
import random as rnd

#make a real 3dPoint object for later use
sphereCenter = rs.coerce3dpoint([50,50,50])
sphere = rs.AddSphere(sphereCenter,45)
#rs.EnableRedraw(False)

pts = []
for i in range(0,100):
#coordinates
    x = rnd.uniform(0,100)
    y = rnd.uniform(0,100)
    z = rnd.uniform(0,100)
    pt = [x,y,z]
    pts.append(pt)

pl = rs.AddPolyline(pts)
crv = rs.AddCurve(pts)
intpcrv = rs.AddInterpCurve(pts)

color01 = [0,255,255]
color02 = [255,0,255]
color03 = [255,255,0]

rs.ObjectColor(pl, color01)
rs.ObjectColor(crv, color02)
rs.ObjectColor(intpcrv, color03)

div_pts = []

#use extend not append to keep all points in one array
div_pts.extend(rs.DivideCurve(pl,5000,False,True))
div_pts.extend(rs.DivideCurve(crv,5000,False,True))
div_pts.extend(rs.DivideCurve(intpcrv,5000,False,True))

#collect all points between 40 and 50 units from center
good_pts=[]
for pt in div_pts:
    d=pt.DistanceTo(sphereCenter)
    if d<50 and d>40:
        good_pts.append(pt)
        
#get random sample of 3 points from above list
three_rnd_pts=rnd.sample(good_pts,3)
#add first point again for closed curve
three_rnd_pts.append(three_rnd_pts[0])
#make curve periodic with knotstyle=3
crv_thru_pts=rs.AddInterpCurve(three_rnd_pts,3,knotstyle=3)
rs.DeleteObjects([pl,crv,intpcrv])

thanks for your feedback! it’s not quite working but lets just say we forget about connecting those points with a line. Can we visualize those points that are being sorted between a range of 40 and 50?

Sure. Just take out the AddInterpCurve part - everything after good_pts.append(pt) - and put in:

rs.AddPoints(good_pts)

–Mitch