Code:
Option Explicit
'Hypocycloid cam generator
'Based on script by Zoidberg on the CNCZone Forum
'In turn based on a Python script by Alex Lait
'Modified to work with Rhino4 (which doesn't have ATan2 function) and
'Addition of pin and cam circles by Simon Rafferty www.x-eng.co.uk
'I also added a clearance value - as reduction will not run if rotor is touching pins all the way round.
'0.1mm seems to be a good compromise between backlash and smooth running
'Credit To:
' Zoidberg
' http://www.cnczone.com/forums/linear_rotary_motion/72261-backlash_free_rotary_table-9.html#post602329
' Alex Lait
' http://www.zincland.com/hypocycloid
' Formulas To describe a hypocycloid cam
' http://gears.ru/transmis/zaprogramata/2.139.pdf
' Insperational thread On CNCzone
' http://www.cnczone.com/forums/showthread.php?t=72261
' Documenting And updating the sdxf library
' http://www.kellbot.com/sdxf-python-library-For-dxf/
' Formulas For calculating the pressure angle And finding the limit circles
' http://imtuoradea.ro/auo.fmte/files-2007/MECATRONICA_files/Anamaria_Dascalescu_1.pdf
'Suggestions:
' - Eccentricity should Not be more than the roller radius. Generally about 0.25 x Pin radius For a smooth result
' Try with values:
' 160, 15, 3, 14, 0.2
Sub Hypocycloid()
Dim p, b, d, e, n,c
b = Rhino.GetReal ("Pin circle diameter")
d = Rhino.GetReal ("Pin diameter")
e = Rhino.GetReal ("Eccentricity")
n = Rhino.GetInteger ("Number of teeth")
c = Rhino.GetReal ("Clearance between rotor & pins")
p = (b/2)/n
Dim i, arrPoint, arrPoints(360)
For i = 0 To 360
arrPoint = Array(CalcX(p,d+c,e,n,Rhino.ToRadians(i)), CalcY(p,d+c,e,n,Rhino.ToRadians(i)), 0)
arrPoints(i) = arrPoint
Next
Rhino.AddInterpCurve(arrPoints)
Dim xtemp, ytemp, arrPlane(3), Plane
For i = 0 To n+1
xtemp = (p*n)*Cos(2*Rhino.pi/(n+1)*i)
ytemp = (p*n)*Sin(2*Rhino.pi/(n+1)*i)
arrPoint = Array(xtemp+e-d/2, ytemp, 0)
arrPlane(0) = arrPoint
arrPoint = Array(xtemp+e + d/2, ytemp, 0)
arrPlane(1) = arrPoint
arrPoint = Array(xtemp+e, ytemp + d/2, 0)
arrPlane(2) = arrPoint
Rhino.AddCircle3Pt arrPlane(0),arrPlane(1),arrPlane(2)
Next
'Lastly, add cam
arrPoint = Array(e-d/2, 0, 0)
arrPlane(0) = arrPoint
arrPoint = Array(e+d/2, 0, 0)
arrPlane(1) = arrPoint
arrPoint = Array(e,d/2, 0)
arrPlane(2) = arrPoint
'Origin
Rhino.AddCircle3Pt arrPlane(0),arrPlane(1),arrPlane(2)
arrPoint = Array(-d, 0, 0)
arrPlane(0) = arrPoint
arrPoint = Array(d, 0, 0)
arrPlane(1) = arrPoint
arrPoint = Array(e,d, 0)
arrPlane(2) = arrPoint
'Offset Cam
Rhino.AddCircle3Pt arrPlane(0),arrPlane(1),arrPlane(2)
End Sub
Private Function CalcYP(a, e, n, p)
CalcYP = ATan2(Sin(n*a)/(Cos(n*a)+(n*p)/(e*(n+1))), 1.0)
End Function
Private Function CalcX(p,d,e,n,a)
CalcX = (n*p)*Cos(a)+e*Cos((n+1)*a)-d/2*Cos(CalcYP(a,e,n,p)+a)
End Function
Private Function CalcY(p,d,e,n,a)
CalcY = (n*p)*Sin(a)+e*Sin((n+1)*a)-d/2*Sin(CalcYP(a,e,n,p)+a)
End Function
Private Function atan2(y,x)
Dim theta, pi: pi = 4*Atn(1)
If x <> 0 Then
theta = Atn(y/x)
If x < 0 Then theta = theta + pi
Else
If y < 0 Then theta = (3 * pi/2) Else theta = pi/2
End If
atan2 = theta
End Function
For those who have not used Rhinoscript before,