Hi!

I had spheres with the same diameter randomly drop in a cylindrical vessel. Then, I imported the sphere centers from CSV to Rhinoceros using Python and created the spheres in Rhinoceros from these coordinates.

Some of these spheres will touch the cylinder wall and I need to know the coordinates of these tangent points.

Is there a way for me to determine the tangent points between the cylinder wall and the touching spheres automatically by Python? If so, can you kindly direct me? Newbie here.

P.S. I will be dealing with around 800 spheres.

Thank you so much in advance! <3

I happen to have solved a similar problem with spheres and tangents very recently.

You know the dimensions of the cylinder with radius `R`

. The spheres have the same radius `r`

.

Each sphere has coordinates `(x, y, z)`

in the 3D space. If the cylinder is centered at the origin, any sphere with a center located on the circle `x^2 + y^2 = (R - r)^2`

should be touching the cylinder wall. No sphere should have a center with `x^2 + y^2 > (R - r)^2`

because it would be passing through the cylinder wall. Any sphere with `x^2 + y^2 < (R - r)^2`

is an interior sphere.

Because of floating point errors it might be the case that no sphere exactly satisfies `x^2 + y^2 = (R - r)^2`

, so you can probably consider any sphere with `x^2 + y^2 > (R - r)^2 - 0.0001`

as touching the wall.

Does that answer your question?

1 Like

Hi James!

This code is valuable for testing the tangency of a sphere. Thank you!

However, I’m stuck at looking for a way to determine the coordinates of the point of tangency. Do you have any idea how? Would really appreciate it.

Thank you! <3

Maria,

If you know a given sphere centered at `(x, y, z)`

is touching the cylinder wall, you can get the point of contact using some more math. You know the 3rd coordinate must be `z`

, so you just need to calculate the other two.

There’s probably more than one way to do this, but an easy way to get that point is by first considering the sphere’s center in polar coordinates.

The `theta`

value is something like `tan2(y / x)`

and `d`

is `(R - r)`

. The point you are interested in has the same `theta`

value but with`d`

equal to `R`

. So translate that point from polar coordinates back to cartesian coordinates and you are done.

Trying drawing a picture if this isn’t clear. All the spheres that touch the cylinder will have centers that are on an invisible cylinder with radius `(R - r)`

. If you can translate the location of that center to an angle then you can project a line from the center of the real cylinder, through the center of the sphere, to the surface of the cylinder.

1 Like

Thanks James! <3

I made it work using these lines of code, thanks to your help.

pt1 = sphere center point

R = 5

r = 2

if ((pt1.X ** 2 + pt1.Y ** 2) > (5 - 2)**2 - 0.1):

pt = Rhino.Geometry.Brep.ClosestPoint(obj_WallCylinder,pt1)

pt_int = rs.AddPoint(pt)

That works also. Happy to help!