#!/usr/bin/env python # -*- coding: iso-8859-15 -*- # GIMP plugin to generate a path for dial marks # (c) Ofnuts 2014 # # History: # # v0.0: 2013-11-15: First published version # v0.1: 2013-11-15: Add offset/start angle # v0.2: 2014-10-22: Add straight/round sides # # 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. from gimpfu import * import math def point(origin,radius,angle): originX,originY=origin x=radius*math.cos(angle)+originX y=radius*math.sin(angle)+originY return (x,y) def tangentDistanceForArc(radius,halfAngle): return radius * (4./3.) * (1-math.cos(halfAngle))/math.sin(halfAngle) def markPointsSquare(center,innerRadius,outerRadius,angle,width): p1=point(center,innerRadius,angle-width) p2=point(center,outerRadius,angle-width) p3=point(center,outerRadius,angle+width) p4=point(center,innerRadius,angle+width) return [p1]*3+[p2]*3+[p3]*3+[p4]*3 def markPointsRound(center,innerRadius,outerRadius,angle,width): innerTg=tangentDistanceForArc(innerRadius,width) outerTg=tangentDistanceForArc(outerRadius,width) p1=point(center,innerRadius,angle-width) p2=point(center,outerRadius,angle-width) p3=point(center,outerRadius,angle+width) p4=point(center,innerRadius,angle+width) t1=point(p1,innerTg,angle-width+math.pi/2) t2=point(p2,outerTg,angle-width+math.pi/2) t3=point(p3,outerTg,angle+width-math.pi/2) t4=point(p4,innerTg,angle+width-math.pi/2) return [t1,p1,p1,p2,p2,t2,t3,p3,p3,p4,p4,t4] def flattenToStroke(points): ''' Takes a list of points as tuples and flattens it to a list of coordinates ''' return [coord for point in points for coord in point] def dialMarks(image,centerX,centerY,innerRadius,outerRadius,marksCount,marksWidth,startAngle,rounded): if marksWidth>90.: pdb.gimp_message('Maximum mark width is 90°') return angleStep=2*math.pi/marksCount width=marksWidth*math.pi/360 # Actually half-width offset=startAngle*math.pi/180 markPoints=[markPointsSquare,markPointsRound][rounded] marksPath=pdb.gimp_vectors_new(image,'Marks: %d, %2.1f, %3.1f, %3.1f' % (marksCount,marksWidth,innerRadius,outerRadius)) for i in range(marksCount): angle=offset+angleStep*i points=flattenToStroke(markPoints((centerX,centerY),innerRadius,outerRadius,angle,width)) sid = pdb.gimp_vectors_stroke_new_from_points(marksPath,0, len(points),points, True) pdb.gimp_image_add_vectors(image,marksPath,0) marksPath.visible=True ### Registration register( 'dial-marks', 'Dial marks', 'Dial marks', 'Ofnuts','Ofnuts','2014', 'Dial marks', '*', [ (PF_IMAGE, 'image', 'Input image', None), (PF_INT, 'centerX', 'Center X',0), (PF_INT, 'centerY', 'Center Y',0), (PF_FLOAT, 'innerRadius', 'Inner radius',0.), (PF_FLOAT, 'outerRadius', 'Outer radius',0.), (PF_INT, 'marksCount', 'Total marks:',0), (PF_FLOAT, 'markWidth', 'Mark width (degrees)',0.), (PF_FLOAT, 'startAngle', 'Start angle (degrees)',0.), (PF_OPTION, 'rounded', 'Sides',0,['Straight','Round']) ], [], dialMarks, menu='/Filters/Render/Paths/', domain=('gimp20-python', gimp.locale_directory) ) main()