1 /* 2 Copyright 2010 3 Matthias Ehmann, 4 Michael Gerhaeuser, 5 Carsten Miller, 6 Bianca Valentin, 7 Alfred Wassermann, 8 Peter Wilfahrt 9 10 This file is part of JSXGraph. 11 12 JSXGraph is free software: you can redistribute it and/or modify 13 it under the terms of the GNU Lesser General Public License as published by 14 the Free Software Foundation, either version 3 of the License, or 15 (at your option) any later version. 16 17 JSXGraph is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU Lesser General Public License for more details. 21 22 You should have received a copy of the GNU Lesser General Public License 23 along with JSXGraph. If not, see <http://www.gnu.org/licenses/>. 24 */ 25 26 JXG.Math.Numerics.createRoulette = function(c1, c2, start_c1, stepsize, direction, time, pointlist) { 27 var Roulette = function() { 28 var alpha = 0, 29 t1 = start_c1, 30 t2 = JXG.Math.Numerics.root( 31 function(t) { 32 var c1x = c1.X(t1), 33 c1y = c1.Y(t1), 34 c2x = c2.X(t), 35 c2y = c2.Y(t); 36 return (c1x-c2x)*(c1x-c2x) + (c1y-c2y)*(c1y-c2y); 37 }, 38 0), 39 t1_new = 0.0, t2_new = 0.0, 40 mx, my, c1x, c1y, c2x, c2y, c1dist, 41 rotation = brd.create('transform',[function(){ return alpha;}, 42 function(){ return c1.X(t1);}, 43 function(){ return c1.Y(t1);}], 44 {type:'rotate'}), 45 linDist = function(t) { 46 c2x = mx - c2.X(t); 47 c2y = my - c2.Y(t); 48 return c1dist - (c2x*c2x+c2y*c2y); 49 }, 50 beta = Math.PI/18.0, 51 beta9 = beta*9, 52 interval = null; 53 54 this.rolling = function(){ 55 t1_new = t1+direction*stepsize; 56 mx = c1.X(t1); 57 my = c1.Y(t1); 58 c1x = mx - c1.X(t1_new); 59 c1y = my - c1.Y(t1_new); 60 c1dist = c1x*c1x+c1y*c1y; // used in linDist 61 t2_new = JXG.Math.Numerics.root(linDist, t2+direction*stepsize); 62 alpha = -JXG.Math.Geometry.rad( 63 [c1.X(t1_new),c1.Y(t1_new)], 64 [c1.X(t1),c1.Y(t1)], 65 [c2.X(t2_new),c2.Y(t2_new)]); 66 if (alpha <-beta && alpha>-beta9) { // -(10-90) degrees 67 alpha = -beta; 68 rotation.applyOnce(pointlist); 69 } else if (alpha>-2*Math.PI+beta && alpha<-2*Math.PI+beta9) { 70 alpha = -2*Math.PI+beta; 71 rotation.applyOnce(pointlist); 72 } else { 73 rotation.applyOnce(pointlist); 74 t1 = t1_new; 75 t2 = t2_new; 76 } 77 brd.update(); 78 }; 79 80 this.start = function() { 81 if (time>0) { 82 interval = setInterval(this.rolling, time); 83 } 84 return this; 85 }; 86 87 this.stop = function() { 88 clearInterval(interval); 89 return this; 90 }; 91 return this; 92 }; 93 return new Roulette(); 94 }; 95 96 JXG.Math.Numerics.reuleauxPolygon = function(points, nr) { 97 var pi2 = Math.PI*2, 98 pi2_n = pi2/nr, 99 diag = (nr-1)/2, 100 beta, d = 0, 101 makeFct = function(which, trig) { 102 return function(t, suspendUpdate) { 103 if (!suspendUpdate) { 104 d = points[0].Dist(points[diag]); 105 beta = JXG.Math.Geometry.rad([points[0].X()+1,points[0].Y()],points[0],points[(diag)%nr]); 106 } 107 var t1 = (t%pi2 + pi2) % pi2; 108 var j = Math.floor(t1 / pi2_n)%nr; 109 if (isNaN(j)) return j; 110 t1 = (t1-j*pi2_n)*0.5 + beta+j*pi2_n; 111 return points[j][which]()+d*Math[trig](t1); 112 }; 113 }; 114 return [ 115 makeFct('X','cos'), 116 makeFct('Y','sin'), 117 0, 118 Math.PI*2 119 ]; 120 }; 121