Connecting spheres and surrounding wall at smaller minimum distances with cylinder bridges

Hi,

I am trying to connect a cluster of spheres with a wall surrounding it. However, only the closest spheres are to be connected at the following criterion:

gap = cylinder wall radius - sphere radius - rs.Distance(point1, point2);
tolerance = 0.080
val = gap/radius

Since there is no easy way to connect them solely on sphere particle and wall coordinates and dimensions, I decide to make an orientation from center points of cross-sectional area of the cylinder wall, as the bridge is perpendicular to the wall (z-axis).

Therefore, gap could be determined as

gap = radiuswall – radiusparticle – rs.Distance([0,0,zi] – point1)

To make the geometry, I wrote coding as follows:

import rhinoscriptsyntax as rs
import math as math

def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
    return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)

# determination of particle-particle bridge is given as follows
def isConnected(point1, point2):
    gap = 31.5 - radius - rs.Distance(point1, point2);
    tolerance = 0.080
    val = gap/radius
    return (isclose(val, tolerance) or (val < tolerance))

#sphere center coordinates, namely 'point i'

radius = 9.5
points = []
points.append([3.8004, -10.7703, -14.7366])
points.append([6.89814, 9.90892, -14.7361])
points.append([-14.1991, -1.3038, -14.7362])
points.append([-2.50297, -1.28871, 1.70578])
points.append([12.3037, -17.4367, 2.09313])
points.append([21.1603, -2.79959, -8.81348])
points.append([-11.5506, -18.1149, -4.23054])
points.append([-11.1571, 18.5256, -14.736])
points.append([4.63671, 21.0576, 1.71328])
points.append([-19.803, 8.74576, 1.62201])
points.append([19.4772, 8.88409, 7.33124])
points.append([19.7547, -8.05903, 18.1097])
points.append([8.40554, -19.6233, 29.834])
points.append([19.879, 7.92851, 30.1251])
points.append([4.80376, 21.0154, 28.916])
points.append([-14.0158, -14.7737, 29.5774])
points.append([-19.7362, -8.70016, 11.4009])
points.append([-3.47392, -21.1316, 13.8154])
points.append([-20.8642, 5.75207, 25.1795])
points.append([3.10321, 2.98932, 20.421])
points.append([-9.83524, 19.2703, 15.4012])
points.append([-21.4772, -2.41992, 43.4234])
points.append([19.6639, -8.27222, 41.8506])
points.append([-12.3412, 17.7824, 38.6932])
points.append([-2.90253, 21.4069, 55.9492])
points.append([-0.923667, 0.666779, 39.873])
points.append([-3.82574, -21.0765, 45.5909])
points.append([14.4364, 15.8948, 47.644])
points.append([-7.73744, -5.57666, 57.6097])


for i in range(len(points)):
    rs.AddPoint(points[i], radius)
    rs.AddSphere(points[i], radius)
    
#cylinder wall plane center points (point j) at same plane as center points

points = []
points.append([0, 0, -14.7366])
points.append([0, 0, -14.7361])
points.append([0, 0, -14.7362])
points.append([0, 0, 1.70578])
points.append([0, 0, 2.09313])
points.append([0, 0, -8.81348])
points.append([0, 0, -4.23054])
points.append([0, 0, -14.736])
points.append([0, 0, 1.71328])
points.append([0, 0, 1.62201])
points.append([0, 0, 7.33124])
points.append([0, 0, 18.1097])
points.append([0, 0, 29.834])
points.append([0, 0, 30.1251])
points.append([0, 0, 28.916])
points.append([0, 0, 29.5774])
points.append([0, 0, 11.4009])
points.append([0, 0, 13.8154])
points.append([0, 0, 25.1795])
points.append([0, 0, 20.421])
points.append([0, 0, 15.4012])
points.append([0, 0, 43.4234])
points.append([0, 0, 41.8506])
points.append([0, 0, 38.6932])
points.append([0, 0, 55.9492])
points.append([0, 0, 39.873])
points.append([0, 0, 45.5909])
points.append([0, 0, 47.644])
points.append([0, 0, 57.6097])

for j in range(len(points)):
    rs.AddPoint(points[j], 31.5)


#forming wall-particle connections 

for i in range(len(points)):
    for j in range(len(points)):
        if (isConnected(points[i], points[j])):            
            direction_vector = rs.VectorCreate(points[i], points[j])
            cylinder_plane = rs.PlaneFromNormal(points[i],direction_vector)
            
            rs.AddCylinder(cylinder_plane, 8, 1, cap=True)
            
#cylinder wall
cylinder = rs.AddCylinder([0,0,-30], 110, 31.5, False)

As seen, I try to split the cross sectional wall center and sphere center points as ‘point i’ and ‘point j’, respectively. However, the geometry isn’t the one I expect.

Despite orienting the direction vector radially (from center outward, see Line 95) and making ‘points i’ as cylinder bridge bases, the bridges are based on ‘points j’ and pointing upward/axially. I suppose I did something wrong with labelling of points i and j but I am still new in Rhino-Python.

I set the bridge length longer than total distance of gap and sphere radius (see line 99), but it is not a problem since I can do Boolean difference later on to tidy it up.

Could somebody point out what’s wrong with my code and suggest what I should do with it? Thanks in advance.

Regards,

Anthony

Try this:
http://developer.rhino3d.com/api/RhinoScriptSyntax/win/#surface-BrepClosestPoint

1 Like