algorithmic modeling for Rhino
Good day,
I have a couple of hundred N.u.r.b.s. spheres that I evaluate for intersections.
The script mathematically checks each sphere for intersections with the other spheres and appends intersecting spheres, as well as the test sphere, to a sub group list (that is later added to a groups list).
Currently:
Each sphere is now associated with its intersecting neighbours, which is great, but what I want to have is a list of lists of neighbourhoods, where each sphere and its intersecting neighbours and their intersecting neighbours and so fourth are grouped in unique sublists, meaning that each sphere can only exist once in the list of lists.
Hopefully later:
Script Start
"""Evaluates the intersections between spheres.
Inputs:
S: List of Nurbs spheres
Output:
G: Tree with intersection groups"""
from Grasshopper.Kernel.Data import GH_Path
from Grasshopper import DataTree
import rhinoscriptsyntax as rs
import math
def center_point(sph):
""" Returns the center point of a nurbs sphere. """
pt_id = rs.AddPoint(rs.SurfaceAreaCentroid(sph)[0])
return rs.coerce3dpoint(pt_id)
def list_to_tree(nested_list):
""" Returns a GH Data Tree from a two
dimensional nested Python list. """
data_tree = DataTree[object]()
for i, item_list in enumerate(nested_list):
path = GH_Path(i)
data_tree.AddRange(item_list, path)
return data_tree
def pt_on_srf(srf):
""" Returns a point in the middle
of a nurbs surface. """
dom_u = rs.SurfaceDomain(srf, 0)
dom_v = rs.SurfaceDomain(srf, 1)
u = dom_u[1]/2.0
v = dom_v[1]/2.0
pt = rs.EvaluateSurface(srf, u, v)
return pt
groups = [] # All intersection groups
for i in range(len(S)):
grp = [] # Intersection group per sphere
center_pt = center_point(S[i])
srf_pt = pt_on_srf(S[i])
radius = rs.Distance(center_pt, srf_pt)
grp.append(S[i])
for j in range(len(S)):
if i != j: # Avoid self-evaluation
center_pt_x = center_point(S[j])
srf_pt_x = pt_on_srf(S[j])
radius_x = rs.Distance(center_pt_x, srf_pt_x)
dist_pts = rs.Distance(center_pt, center_pt_x)
# Evaluate the sphere relationship
if dist_pts > (radius + radius_x): # No intersection or inclusion
pass
elif dist_pts <= math.fabs(radius - radius_x): # Inclusion
pass
else: # Intersection
grp.append(S[j])
groups.append(grp)
G = list_to_tree(groups)
Script End
I would be very glad, if somebody could take a look at the script and point me into the right direction.
Thank you.
Tags:
Thanks for your fast reply. Your solution seems very elegant.
Could it be that your solution doesn't work, if there are lots of sphere intersections for a cluster?
When I input my spheres from the example above, the lowest bottom sphere of group X is always put in a separate single branch.
Thanks, for all your help! I've managed to come up with a similar solution, by looking at Peter's C# script and translating it to Python. I've attached the working file to a comment below, if your interested.
For big N of spheres Intersection takes ages. If on the other hand he had to cluster intersecting breps ... mama mia (even using some // approach). That said is way faster to convert Breps to Meshes.
Intersection is used because that way you can cluster closed curves (other wise [radii] you'll be limited to circles). Anyway for curves there's no big difference in speed,
Welcome to
Grasshopper
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
© 2024 Created by Scott Davidson. Powered by