summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 46bf50f)
raw | patch | inline | side by side (parent: 46bf50f)
author | buliabyak <buliabyak@users.sourceforge.net> | |
Wed, 18 Apr 2007 00:04:31 +0000 (00:04 +0000) | ||
committer | buliabyak <buliabyak@users.sourceforge.net> | |
Wed, 18 Apr 2007 00:04:31 +0000 (00:04 +0000) |
share/extensions/Makefile.am | patch | blob | history | |
share/extensions/gears.inx | [new file with mode: 0644] | patch | blob |
share/extensions/gears.py | [new file with mode: 0644] | patch | blob |
index f0c75fa9c54c0b12c5b0f2146f220ebd909a7c51..0ce2bba4af6056625bf973141b8d3833295574bb 100644 (file)
fractalize.py \
funcplot.py \
g2pngs.py\
+ gears.py\
gimp_xcf.py \
handles.py \
ill2svg.pl \
fractalize.inx \
funcplot.inx \
g2pngs.inx\
+ gears.inx\
gimp_xcf.inx \
handles.inx \
inkscape_help_commandline.inx \
diff --git a/share/extensions/gears.inx b/share/extensions/gears.inx
--- /dev/null
@@ -0,0 +1,18 @@
+<inkscape-extension>
+ <_name>Gear</_name>
+ <id>org.ekips.filter.gears</id>
+ <dependency type="executable" location="extensions">gears.py</dependency>
+ <dependency type="executable" location="extensions">inkex.py</dependency>
+ <param name="teeth" type="int" min="6" max="360" _gui-text="Number of teeth">24</param>
+ <param name="pitch" type="float" min="0.0" max="1000.0" _gui-text="Circular pitch, px">20.0</param>
+ <param name="angle" type="float" min="10.0" max="30.0" _gui-text="Pressure angle">20.0</param>
+ <effect>
+ <object-type>all</object-type>
+ <effects-menu>
+ <submenu _name="Render"/>
+ </effects-menu>
+ </effect>
+ <script>
+ <command reldir="extensions" interpreter="python">gears.py</command>
+ </script>
+</inkscape-extension>
diff --git a/share/extensions/gears.py b/share/extensions/gears.py
--- /dev/null
@@ -0,0 +1,166 @@
+#!/usr/bin/env python
+'''
+Copyright (C) 2007 Aaron Spike (aaron @ ekips.org)
+Copyright (C) 2007 Tavmjong Bah (tavmjong @ free.fr)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+'''
+
+import inkex, simplestyle, sys
+from math import *
+
+def involute_intersect_angle(Rb, R):
+ Rb, R = float(Rb), float(R)
+ return (sqrt(R**2 - Rb**2) / (Rb)) - (acos(Rb / R))
+
+def point_on_circle(radius, angle):
+ x = radius * cos(angle)
+ y = radius * sin(angle)
+ return (x, y)
+
+def points_to_svgd(p):
+ f = p[0]
+ p = p[1:]
+ svgd = 'M%.3f,%.3f' % f
+ for x in p:
+ svgd += 'L%.3f,%.3f' % x
+ svgd += 'z'
+ return svgd
+
+class Gears(inkex.Effect):
+ def __init__(self):
+ inkex.Effect.__init__(self)
+ self.OptionParser.add_option("-t", "--teeth",
+ action="store", type="int",
+ dest="teeth", default=24,
+ help="Number of teeth")
+ self.OptionParser.add_option("-p", "--pitch",
+ action="store", type="float",
+ dest="pitch", default=20.0,
+ help="Circular Pitch (length of arc from one tooth to next)")
+ self.OptionParser.add_option("-a", "--angle",
+ action="store", type="float",
+ dest="angle", default=20.0,
+ help="Pressure Angle (common values: 14.5, 20, 25 degrees)")
+ def effect(self):
+
+ teeth = self.options.teeth
+ pitch = self.options.pitch
+ angle = self.options.angle # Angle of tangent to tooth at circular pitch wrt radial line.
+
+ # print >>sys.stderr, "Teeth: %s\n" % teeth
+
+ two_pi = 2.0 * pi
+
+ # Pitch (circular pitch): Length of the arc from one tooth to the next)
+ # Pitch diameter: Diameter of pitch circle.
+ pitch_diameter = float( teeth ) * pitch / pi
+ pitch_radius = pitch_diameter / 2.0
+
+ # Base Circle
+ base_diameter = pitch_diameter * cos( radians( angle ) )
+ base_radius = base_diameter / 2.0
+
+ # Diametrial pitch: Number of teeth per unit length.
+ pitch_diametrial = float( teeth )/ pitch_diameter
+
+ # Addendum: Radial distance from pitch circle to outside circle.
+ addendum = 1.0 / pitch_diametrial
+
+ # Outer Circle
+ outer_radius = pitch_radius + addendum
+ outer_diameter = outer_radius * 2.0
+
+ # Tooth thickness: Tooth width along pitch circle.
+ tooth = ( pi * pitch_diameter ) / ( 2.0 * float( teeth ) )
+
+ # Undercut?
+ undercut = (2.0 / ( sin( radians( angle ) ) ** 2))
+ needs_undercut = teeth < undercut
+
+
+ # Clearance: Radial distance between top of tooth on one gear to bottom of gap on another.
+ clearance = 0.0
+
+ # Dedendum: Radial distance from pitch circle to root diameter.
+ dedendum = addendum + clearance
+
+ # Root diameter: Diameter of bottom of tooth spaces.
+ root_radius = pitch_radius - dedendum
+ root_diameter = root_radius * 2.0
+
+ half_thick_angle = two_pi / (4.0 * float( teeth ) )
+ pitch_to_base_angle = involute_intersect_angle( base_radius, pitch_radius )
+ pitch_to_outer_angle = involute_intersect_angle( base_radius, outer_radius ) - pitch_to_base_angle
+
+ centers = [(x * two_pi / float( teeth) ) for x in range( teeth ) ]
+
+ points = []
+
+ for c in centers:
+
+ # Angles
+ pitch1 = c - half_thick_angle
+ base1 = pitch1 - pitch_to_base_angle
+ outer1 = pitch1 + pitch_to_outer_angle
+
+ pitch2 = c + half_thick_angle
+ base2 = pitch2 + pitch_to_base_angle
+ outer2 = pitch2 - pitch_to_outer_angle
+
+ # Points
+ b1 = point_on_circle( base_radius, base1 )
+ p1 = point_on_circle( pitch_radius, pitch1 )
+ o1 = point_on_circle( outer_radius, outer1 )
+
+ b2 = point_on_circle( base_radius, base2 )
+ p2 = point_on_circle( pitch_radius, pitch2 )
+ o2 = point_on_circle( outer_radius, outer2 )
+
+ if root_radius > base_radius:
+ pitch_to_root_angle = pitch_to_base_angle - involute_intersect_angle(base_radius, root_radius )
+ root1 = pitch1 - pitch_to_root_angle
+ root2 = pitch2 + pitch_to_root_angle
+ r1 = point_on_circle(root_radius, root1)
+ r2 = point_on_circle(root_radius, root2)
+ p_tmp = [r1,p1,o1,o2,p2,r2]
+ else:
+ r1 = point_on_circle(root_radius, base1)
+ r2 = point_on_circle(root_radius, base2)
+ p_tmp = [r1,b1,p1,o1,o2,p2,b2,r2]
+
+ points.extend( p_tmp )
+
+ path = points_to_svgd( points )
+
+ # Create SVG Path for gear
+ gear = self.document.createElement( 'svg:path' )
+ style = { 'stroke': '#000000', 'fill': 'none' }
+ gear.setAttribute( 'style', simplestyle.formatStyle(style) )
+ gear.setAttribute( 'd', path )
+
+ # Embed gear in group to make animation easier:
+ # Translate group, Rotate path.
+ g=self.document.createElement('g')
+
+ g.setAttribute( 'inkscape:label', 'Gear' + str( teeth ) )
+ t = 'translate(' + str( self.view_center[0] ) + ',' + str( self.view_center[1] ) + ')'
+ g.setAttribute( 'transform', t )
+ self.current_layer.appendChild( g )
+ g.appendChild( gear )
+
+e = Gears()
+e.affect()
+