 # How do you build a capsule solid in python script

what is the fastest way to build a generic capsule with give any orientation by a vector, given the following parameters

A length of cylindrical height
r radius of cylinder and hemispheres
x y z location of the center of the solid

alpha, beta, gamma as the vector determining the orientation of the capsule( ahpha^2+beta^2+gamma^2=1), say 1,0,0 meaning it is along x axis, but would like to extend it to any generic direction not just on x or y or z axis by giving the proper orientation vector.

``````import Rhino
import scriptcontext
import System.Guid

r=4
h=8
x = 5
y = 10
z = 4
alpha = 1 # Along x axis
beta  = 0
gamma = 0

center = Rhino.Geometry.Point3d(x, y, z)
c = Rhino.Geometry.Circle(center, r)
# how to rotate the circle then move it to the ends of the cylinder so you could sweep to generate the cylinder surface
# then copy the center to the end of the cylinder top/bottom to generate the hemi-spheres and join 3 surfaces together? # I got stuck at the rotation part and am not quite familiar with the syntax...
``````

If you are going to orient multiples, I prefer to create the object flat relative to the World axis and then rotate/translate it into position. Below is a quick sample which creates a series of randomly oriented and spaced capsules in a cube. There are obviously different ways to construct the capsule, I prefer as a polysurface composed of the cylinder and two hemispheres rather than joining the revolve curves and getting one single surface.

The capsules are all the samesize in the example, it’s certainly also possible to create random-sized capsules with a couple more lines of code.

Edit- more fun version that adds random color to each capsule…

``````import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino, random, System

#makes capsule oriented along X-axis, centered at 0
#I prefer to create this as 3 separate surfaces and join
#points

#curve geometry
x_vec=Rhino.Geometry.Vector3d(1,0,0)
line_crv=Rhino.Geometry.LineCurve(ptA,ptC)
arc_R=Rhino.Geometry.Arc(ptA,-x_vec,ptB).ToNurbsCurve()
arc_L=Rhino.Geometry.Arc(ptC,x_vec,ptD).ToNurbsCurve()

#revolve surfaces
axis=Rhino.Geometry.Line(ptB,ptD)
srf_R=Rhino.Geometry.RevSurface.Create(arc_R,axis).ToBrep()
srf_C=Rhino.Geometry.RevSurface.Create(line_crv,axis).ToBrep()
srf_L=Rhino.Geometry.RevSurface.Create(arc_L,axis).ToBrep()

#join
brep=Rhino.Geometry.Brep.JoinBreps([srf_R,srf_C,srf_L],tol)
return brep

def Get3RandomValues(min,max):
x=random.randrange(min,max)
y=random.randrange(min,max)
z=random.randrange(min,max)
return x,y,z

def CreateOrientCapsules():
#test will create n number of capsules at different locations
tol=sc.doc.ModelAbsoluteTolerance
height=rs.GetReal("Cylinder section height?",2,minimum=tol)
if not height: return
extents=rs.GetReal("Extents cube?",100,minimum=tol)
if not extents: return
count=rs.GetInteger("Number of capsules?",10,minimum=1)
if not count: return

vecs=[] ; pts=[] ; colors=[]
x_vec=Rhino.Geometry.Vector3d(1,0,0)
origin=Rhino.Geometry.Point3d(0,0,0)

for i in range(count):
x,y,z=Get3RandomValues(-extents/2,extents/2)
pts.append(Rhino.Geometry.Point3d(x,y,z))
x,y,z=Get3RandomValues(-extents/2,extents/2)
vecs.append(Rhino.Geometry.Vector3d(x,y,z))
r,g,b=Get3RandomValues(0,255)
colors.append(System.Drawing.Color.FromArgb(r,g,b))

sc.doc.Views.RedrawEnabled=False
for i in range(count):
xform=Rhino.Geometry.Transform.Rotation(x_vec,vecs[i],origin)
cap.Transform(xform)
xform=Rhino.Geometry.Transform.Translation(pts[i]-origin)
cap.Transform(xform)
rs.ObjectColor(objID,colors[i])
CreateOrientCapsules()
``````

–Mitch

1 Like

@ludicris, below is my shortest version:

``````import Rhino
import scriptcontext
import rhinoscriptsyntax as rs

brep = Rhino.Geometry.Brep()
mode = Rhino.Geometry.PipeCapMode.Round
t1 = scriptcontext.doc.ModelAbsoluteTolerance
rc = brep.CreatePipe(curve, radius, False, mode, False, t1, t2)
if rc: return rc

def GetCapsulePoints():
pts = rs.GetPoints(True, False, "first point", "second point", 2)
if not pts: return
if len(pts) == 1: return
if pts == pts: return
curve = Rhino.Geometry.Line(pts, pts).ToNurbsCurve()