Code

moving trunk for module inkscape
[inkscape.git] / share / extensions / ffproc.py
1 #!/usr/bin/env python
2 '''
3     Copyright (C) 2004 Aaron Cyril Spike
5     This file is part of FretFind 2-D.
7     FretFind 2-D is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
12     FretFind 2-D is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
17     You should have received a copy of the GNU General Public License
18     along with FretFind 2-D; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 '''
21 import sys
22 from ffgeom import *
23 threshold=0.0000000001
25 def FindFrets(strings, meta, scale, tuning, numfrets):
26         scale = scale['steps']
28         #if the string ends don't fall on the nut and bridge
29         #don't look for partial frets.
30         numStrings = len(strings)
31         doPartials = True
32         parallelFrets = True
33         
34         nut = Segment(strings[0][0],strings[-1][0])
35         bridge = Segment(strings[0][1],strings[-1][1])
36         midline = Segment(
37                 Point((nut[1]['x']+nut[0]['x'])/2.0,(nut[1]['y']+nut[0]['y'])/2.0),
38                 Point((bridge[1]['x']+bridge[0]['x'])/2.0,(bridge[1]['y']+bridge[0]['y'])/2.0))
39         for s in strings:
40                 if nut.distanceToPoint(s[0])>=threshold or bridge.distanceToPoint(s[1])>=threshold:
41                         doPartials = False
42                         break
44         denom = ((bridge[1]['y']-bridge[0]['y'])*(nut[1]['x']-nut[0]['x']))-((bridge[1]['x']-bridge[0]['x'])*(nut[1]['y']-nut[0]['y']))
45         if denom != 0:
46                 parallelFrets = False
48         fretboard = []
49         tones = len(scale)-1
50         for i in range(len(strings)):
51                 base = tuning[i]
52                 frets = []
53                 if doPartials:
54                         frets.append(Segment(meta[i][0],meta[i+1][0]))
55                 else:
56                         frets.append(Segment(strings[i][0],strings[i][0]))
57                 last = strings[i][0]
59                 for j in range(numfrets):
60                         step=((base+j-1)%(tones))+1
61                         ratio=1.0-((scale[step][1]*scale[step-1][0])/(scale[step][0]*scale[step-1][1]))
62                         x = last['x']+(ratio*(strings[i][1]['x']-last['x']))
63                         y = last['y']+(ratio*(strings[i][1]['y']-last['y']))
64                         current = Point(x,y)    
65                         temp = Segment(strings[i][0],current)
66                         totalRatio = temp.length()/strings[i].length()
67                         
68                         if doPartials:
69                                 #partials depending on outer strings (questionable)
70                                 if parallelFrets:
71                                         temp = nut.createParallel(current)
72                                 else:
73                                         temp = Segment(strings[0].pointAtLength(strings[0].length()*totalRatio),
74                                                 strings[-1].pointAtLength(strings[-1].length()*totalRatio))
75                                 frets.append(Segment(intersectSegments(temp,meta[i]),intersectSegments(temp,meta[i+1])))
76                         else:
77                                 frets.append(Segment(current,current))
78                         last = current
79                 fretboard.append(frets)
80         return fretboard
81         
82 def FindStringsSingleScale(numStrings,scaleLength,nutWidth,bridgeWidth,oNF,oBF,oNL,oBL):
83         strings = []
84         meta = []
85         nutHalf = nutWidth/2
86         bridgeHalf = bridgeWidth/2
87         nutCandidateCenter = (nutHalf) + oNL
88         bridgeCandidateCenter = (bridgeHalf) + oBL
89         if bridgeCandidateCenter >= nutCandidateCenter:
90                 center = bridgeCandidateCenter
91         else:
92                 center = nutCandidateCenter
93         nutStringSpacing = nutWidth/(numStrings-1)
94         bridgeStringSpacing = bridgeWidth/(numStrings-1)
95         
96         for i in range(numStrings):
97                 strings.append(Segment(Point(center+nutHalf-(i*nutStringSpacing),0),
98                         Point(center+bridgeHalf-(i*bridgeStringSpacing),scaleLength)))
100         meta.append(Segment(Point(center+nutHalf+oNF,0),Point(center+bridgeHalf+oBF,scaleLength)))
101         for i in range(1,numStrings):
102                 meta.append(Segment(
103                         Point((strings[i-1][0]['x']+strings[i][0]['x'])/2.0,
104                                 (strings[i-1][0]['y']+strings[i][0]['y'])/2.0),
105                         Point((strings[i-1][1]['x']+strings[i][1]['x'])/2.0,
106                                 (strings[i-1][1]['y']+strings[i][1]['y'])/2.0)))
107         meta.append(Segment(Point(center-(nutHalf+oNL),0),Point(center-(bridgeHalf+oBL),scaleLength)))
109         return strings, meta
111 def FindStringsMultiScale(numStrings,scaleLengthF,scaleLengthL,nutWidth,bridgeWidth,perp,oNF,oBF,oNL,oBL):
112         strings = []
113         meta = []
114         nutHalf = nutWidth/2
115         bridgeHalf = bridgeWidth/2
116         nutCandidateCenter = (nutHalf)+oNL
117         bridgeCandidateCenter = (bridgeHalf)+oBL
118         if bridgeCandidateCenter >= nutCandidateCenter:
119                 xcenter = bridgeCandidateCenter
120         else:
121                 nutCandidateCenter
123         fbnxf = xcenter+nutHalf+oNF
124         fbbxf = xcenter+bridgeHalf+oBF
125         fbnxl = xcenter-(nutHalf+oNL)
126         fbbxl = xcenter-(bridgeHalf+oBL)
128         snxf = xcenter+nutHalf
129         sbxf = xcenter+bridgeHalf
130         snxl = xcenter-nutHalf
131         sbxl = xcenter-bridgeHalf
133         fdeltax = sbxf-snxf
134         ldeltax = sbxl-snxl
135         fdeltay = math.sqrt((scaleLengthF*scaleLengthF)-(fdeltax*fdeltax))
136         ldeltay = math.sqrt((scaleLengthL*scaleLengthL)-(ldeltax*ldeltax))
138         fperp = perp*fdeltay
139         lperp = perp*ldeltay
141         #temporarily place first and last strings
142         first = Segment(Point(snxf,0),Point(sbxf,fdeltay))
143         last = Segment(Point(snxl,0),Point(sbxl,ldeltay))
144         
145         if fdeltay<=ldeltay:
146                 first.translate(0,(lperp-fperp))
147         else:
148                 last.translate(0,(fperp-lperp))
150         nut = Segment(first[0].copy(),last[0].copy())
151         bridge = Segment(first[1].copy(),last[1].copy())
152         #overhang measurements are now converted from delta x to along line lengths
153         oNF = (oNF*nut.length())/nutWidth
154         oNL = (oNL*nut.length())/nutWidth
155         oBF = (oBF*bridge.length())/bridgeWidth
156         oBL = (oBL*bridge.length())/bridgeWidth
157         #place fretboard edges
158         fbf = Segment(nut.pointAtLength(-oNF),bridge.pointAtLength(-oBF))
159         fbl = Segment(nut.pointAtLength(nut.length()+oNL),bridge.pointAtLength(bridge.length()+oBL))
160         #normalize values into the first quadrant via translate
161         if fbf[0]['y']<0 or fbl[0]['y']<0:
162                 if fbf[0]['y']<=fbl[0]['y']:
163                         move = -fbf[0]['y']
164                 else:
165                         move = -fbl[0]['y']
166                 
167                 first.translate(0,move)
168                 last.translate(0,move)
169                 nut.translate(0,move)
170                 bridge.translate(0,move)
171                 fbf.translate(0,move)
172                 fbl.translate(0,move)
174         #output values
175         nutStringSpacing = nut.length()/(numStrings-1)
176         bridgeStringSpacing = bridge.length()/(numStrings-1)
177         strings.append(first)
178         for i in range(1,numStrings-1):
179                 n = nut.pointAtLength(i*nutStringSpacing)
180                 b = bridge.pointAtLength(i*bridgeStringSpacing)
181                 strings.append(Segment(Point(n['x'],n['y']),Point(b['x'],b['y'])))
182         strings.append(last)
184         meta.append(fbf)
185         for i in range(1,numStrings):
186                 meta.append(Segment(
187                         Point((strings[i-1][0]['x']+strings[i][0]['x'])/2.0,
188                                 (strings[i-1][0]['y']+strings[i][0]['y'])/2.0),
189                         Point((strings[i-1][1]['x']+strings[i][1]['x'])/2.0,
190                                 (strings[i-1][1]['y']+strings[i][1]['y'])/2.0)))
191         
192         meta.append(fbl)
193         
194         return strings, meta