00001 #include "MusimatChapter9.h" 00002 MusimatChapter9Section(C091201f) { 00003 Print("*** Linear Interpolation ***"); 00004 /***************************************************************************** 00005 00006 Linear Interpolation 00007 00008 Linear interpolation allows us to map a range of values so that it covers 00009 a proportionately wider or narrower range. Figure 9.14 shows linear interpolation from the range 00010 1-4 on the left being mapped to the range 3-9 on the right. The value 3 on the left corresponds by 00011 linear interpolation to 7 on the right. Linear interpolation maintains the linear proportions of the 00012 two number lines: 3 is two-thirds of the way from 1 to 4, and 7 is two-thirds of the way from 3 to 9. 00013 00014 Linear interpolation is a slight generalization of unit interpolation, as follows. If xMax is 00015 the upper bound and xMin is the lower bound, and x is a parameter in the range xmin <= x <= xmax, then 00016 00017 x - xMin 00018 y = ----------- (yMax - yMin) + yMin 00019 xMax - xMin 00020 00021 sets y to a position within the range yMin <= y <= yMax that is proportional to the position of x within 00022 its range. Below is the definition of linear interpolation in Musimat: 00023 *****************************************************************************/ 00024 para1(); // Step into this function to continue. 00025 para2(); // Step into this function to continue. 00026 } 00027 00028 Real linearInterpolate( 00029 Real x, // value ranging from xMin to xMax 00030 Real xMin, // minimum range of x 00031 Real xMax, // maximum range of x 00032 Real yMin, // target minimum range 00033 Real yMax // target maximum range 00034 ) { 00035 Real a = (x - xMin) / (xMax - xMin); 00036 Real b = yMax - yMin; 00037 Return(a * b + yMin); 00038 } 00039 00040 Static Void para1() { 00041 /***************************************************************************** 00042 Here is an example of linear interpolation: 00043 *****************************************************************************/ 00044 00045 Print("*** Linear Interpolation ***"); 00046 Print("linearInterpolate(3.0, 1.0, 4.0, 3.0, 9.0) = ", linearInterpolate(3.0, 1.0, 4.0, 3.0, 9.0)); 00047 00048 /***************************************************************************** 00049 We also can use linear interpolation to map an entire function to a different range. We do so by 00050 applying linear interpolation to every point on the function. For example, we can scale a chromatic 00051 melody to occupy a wider or narrower tessatura as follows: 00052 *****************************************************************************/ 00053 } 00054 00055 IntegerList stretch(IntegerList L, Integer yMin, Integer yMax) { 00056 Integer xMin = Integer(Min(L)); // find the list's minimum 00057 Integer xMax = Integer(Max(L)); // find the list's maximum 00058 For (Integer i = 0; i < Length(L); i = i + 1) { 00059 L[i] = Integer(linearInterpolate(L[i], xMin, xMax, yMin, yMax)); 00060 } 00061 Return(L); 00062 } 00063 00064 Static Void para2() { 00065 /***************************************************************************** 00066 For example, if the input is 00067 *****************************************************************************/ 00068 00069 Print("*** Stretch ***"); 00070 IntegerList L(0, 8, 10, 6, 7, 5, 9, 1, 3, 2, 11, 4); 00071 Print("Source list: ", L); 00072 00073 /***************************************************************************** 00074 invoking stretch() with these arguments 00075 *****************************************************************************/ 00076 00077 Print("stretch(L, 24, 47)=", stretch(L, 24, 47)); 00078 00079 /***************************************************************************** 00080 will scale the row to cover a two-octave range and offset it upward by one octave. 00081 Then x will be {24, 40, 44, 36, 38, 34, 42, 26, 30, 28, 47, 32}. It can also be used to com- 00082 press rows. With the same input, 00083 *****************************************************************************/ 00084 00085 Print("stretch(L, 0, 5)=", stretch(L, 0, 5)); 00086 00087 /***************************************************************************** 00088 will produce {0, 3, 4, 2, 3, 2, 4, 0, 1, 0, 5, 1}. 00089 *****************************************************************************/ 00090 } 00091 00093 /* $Revision: 1.3 $ $Date: 2006/09/05 08:02:46 $ $Author: dgl $ $Name: $ $Id: C091201f.cpp,v 1.3 2006/09/05 08:02:46 dgl Exp $ */ 00094 // The Musimat Tutorial © 2006 Gareth Loy 00095 // Derived from Chapter 9 and Appendix B of "Musimathics Vol. 1" © 2006 Gareth Loy 00096 // and published exclusively by The MIT Press. 00097 // This program is released WITHOUT ANY WARRANTY; without even the implied 00098 // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00099 // For information on usage and redistribution, and for a DISCLAIMER OF ALL 00100 // WARRANTIES, see the file, "LICENSE.txt," in this distribution. 00101 // "Musimathics" is available here: http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&tid=10916 00102 // Gareth Loy's Musimathics website: http://www.musimathics.com/ 00103 // The Musimat website: http://www.musimat.com/ 00104 // This program is released under the terms of the GNU General Public License 00105 // available here: http://www.gnu.org/licenses/gpl.txt 00106