Code

Added tutorial-basic.it
[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.perpDistanceToPoint(s[0])>=threshold or bridge.perpDistanceToPoint(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