# ADAPTED BY FRANCISCO FOR FAB 9000 ARM GEAR
# ORIGINAL FILE FROM MATT KEETER KOKOPELLI GEAR EXAMPLE
# Released under MIT license http://opensource.org/licenses/MIT
"""
examples/gear.cad
This example creates an involute gear with user-defined
pressure angle, diametral pitch, and number of teeth.
It works directly with MathTree expressions to create the
involute curve profile, then uses higher-level operations
to create the teeth and base.
The involute gear construction is based on the tutorial at
http://www.cartertools.com/involute.html
"""
from math import sqrt, atan2, sin, cos, pi, radians
import operator
from koko.lib.shapes import *
P = 14. # diametral pitch
PA = 20 # pressure angle
N = 45 # number of teeth
R = N/P/2 # pitch radius
RB = R*cos(radians(PA)) # base circle radius
a = 1/P # addendum
d = 1.157/P # dedendum
RO = R+a # outer radius
RR = R-d # root radius
# MathTree expressions for r and r**2
r_2 = MathTree.square(X) + MathTree.square(Y)
r = MathTree.sqrt(r_2)
# See note (1) for derivation of tooth rotation
t = sqrt(R**2/RB**2 -1)
rot = atan2(sin(t)-t*cos(t), cos(t)+t*sin(t)) + pi/2/N
# See note (2) for derivation of involute curve
tooth = (
MathTree.sqrt(r_2-RB**2) - RB*(MathTree.atan(Y/X) +
MathTree.acos(RB/r)) - RB*rot
)
tooth.shape = True
tooth &= reflect_y(tooth)
# If we have an odd number of teeth, then we can't take
# advantage of bilateral tooth symmetry.
if N % 2:
tooth &= -X
teeth = reduce(operator.add, [rotate(tooth, i*360/N)
for i in range(N)])
else:
teeth = reduce(operator.add, [rotate(tooth, i*360/N)
for i in range(N/2)])
teeth += circle(0, 0, RR)
teeth &= circle(0, 0, RO) - circle(0, 0, RR*0.9)
teeth.bounds = circle(0, 0, RO).bounds
teeth = extrusion(teeth, -0.1, 0.1)
teeth.color = 'red'
# Create a set of six ribs inside the gear
ribs = rectangle(-0.002*N, 0.002*N, -RR*0.95, RR*0.95)
ribs = reduce(operator.add, [rotate(ribs, i*120) for i in range(3)])
ribs += circle(0, 0, 0.4)
ribs -= circle(0,0,0.25)
ribs -= rectangle(-0.06, 0.06, 0, 0.3)
ribs = extrusion(ribs, -0.08, 0.08)
ribs.color = 'green'
# Create a base for the gear
base = circle(0, 0, RR*0.95) - circle(0, 0, 0.35)
base -= rectangle(-0.06, 0.06, 0, 0.3)
base = extrusion(base, -0.04, 0.04)
base.color = 'blue'
r40=40/25.4
r30=30/25.4
r20=20/25.4
r12=12/25.4
r10=10/25.4
c=circle(0,0,RR)-circle(0,0,r30)
hole=circle(0,r40-0.5*r10,0.04921)
for i in range (11):
hole+=rotate(hole,30)
c=teeth+c
c-=hole
cad.shape = c
"""
Notes:
(1)
We want to find the angle such that the involute curve
intersects a circle of radius R, where the involute is being
unwound from a circle of radius RB (and RB < R)
The involute has coordinates
x, y = RB*(cos(t)+t*sin(t)), RB*(sin(t)-t*cos(t))
where t is a parameter.
Solving x**2 + y**2 = R**2 gives
t = sqrt(R**2/RB**2 -1)
which we can plug back in to find x(t) and y(t).
We take atan2(y(t), x(t)) to find the angle, then add another
(2*pi)/(4*N) so that we can mirror the tooth about the x axis.
(2)
[Clever math & explanation by Peter Fedak, HMC 2013]
Assuming that restricting to x and y greater than
R is not interesting/challenging, an expression
separating one side of a portion of a circle involute
from another is
R(atan(y/x) + acos( R/sqrt(x^2+y^2) )) - sqrt(x^2+y^2-R^2)
which is 0 on the curve and negative for points to the northeast.
This assumes the involute starts at (1,0), if you want to rotate it,
or deal with a different turn of the involute, subtract R*rotation
angle.
For points P=(x,y) in the first quadrant, atan(y/x) accurately gives
the angle between the x-axis and the ray from O=(0,0) to P. Assuming
we are "unwinding" the involute counterclockwise, the place where the
"string" meets the circle, Q, will be the more-counterclockwise
tangent from P to the circle. Then O,P,Q is a right triangle, and the
length of the string, PQ, is sqrt(x^2+y^2-R^2) (right angle between
the tangent and the radius OQ).
The angle of OQ from the x-axis is, again restricted to P in the first
quadrant, the sum of the angle of OP from the x-axis and one of the
angles in teh triangle. the cosine of the relevant angle is
R/sqrt(x^2+y^2), and as this angle will always be smaller than a right
angle, can by given by the inverse cosine of this ratio directly. The
condition for a point to lie on the involute is for the length of the
"string" to be equal to the amount unwound. The amount unwound is the
angle from OQ to the x-axis times R, which is the first term in the
expression. The length of the string is the expression after the minus
sign. Thus the involute is where this F=0, whereas if the point is too
close to the origin, the expression will be positive.
"""