diff options
author | Cyrille Henry <nusmuk@users.sourceforge.net> | 2013-04-09 10:43:54 +0000 |
---|---|---|
committer | Cyrille Henry <nusmuk@users.sourceforge.net> | 2013-04-09 10:43:54 +0000 |
commit | 7d4780c91c33c3aa7e1663762783350935dc8d04 (patch) | |
tree | 1e0f0aaaa269d2a0f12cd0b3d9fcdb5698157346 | |
parent | 70583ff7ea3d34acc0d119f401046dd1e0257283 (diff) |
add interactors to pmpd2d
svn path=/trunk/externals/pmpd/; revision=17078
-rw-r--r-- | TODO.txt | 1 | ||||
-rw-r--r-- | pmpd2d.c | 4 | ||||
-rw-r--r-- | pmpd2d_interactor.c | 178 |
3 files changed, 181 insertions, 2 deletions
@@ -24,6 +24,7 @@ TODO : closestNeighbor linkEndL add creation parametter to fix maximum number of link and mass +iBox3d / iBox2d ? messages a tester : # class_addmethod(pmpd3d_class, (t_method)pmpd3d_setLCurrent, gensym("setLCurrent"), A_GIMME, 0); @@ -270,8 +270,8 @@ void pmpd2d_setup(void) Functions to add a global interaction with a specific shape
*/
- // class_addmethod(pmpd2d_class, (t_method)pmpd2d_iCircle, gensym("iCircle"), A_GIMME, 0);
- // class_addmethod(pmpd2d_class, (t_method)pmpd2d_iLine, gensym("iLine"), A_GIMME, 0);
+ class_addmethod(pmpd2d_class, (t_method)pmpd2d_iCircle, gensym("iCircle"), A_GIMME, 0);
+ class_addmethod(pmpd2d_class, (t_method)pmpd2d_iLine, gensym("iLine"), A_GIMME, 0);
/*
pmpd2d_various
diff --git a/pmpd2d_interactor.c b/pmpd2d_interactor.c index e69de29..08bbbbc 100644 --- a/pmpd2d_interactor.c +++ b/pmpd2d_interactor.c @@ -0,0 +1,178 @@ +void pmpd2d_iCircle_i(t_pmpd2d *x, int i, t_float a, t_float b, t_float r, t_float K, t_float power, t_float Rmin, t_float Rmax) +{ + t_float distance, X, Y, rayon, tmp; + + X = x->mass[i].posX - a; + Y = x->mass[i].posY - b; + + rayon = sqrt ( sqr(X) + sqr(Y) ); + distance = r - rayon; + + if (rayon != 0) + { + X /= rayon; // normalisation + Y /= rayon; + } + else + { + X = 0; // normalisation + Y = 0; + } + +// X, Y : vecteur unitaire normal au cercle +// rayon : distance au centre. + + if ( (rayon>Rmin) && (rayon<=Rmax) ) + { + tmp = pow_ch(K * distance, power); + x->mass[i].forceX += X * tmp; + x->mass[i].forceY += Y * tmp; + } +} + +void pmpd2d_iCircle(t_pmpd2d *x, t_symbol *s, int argc, t_atom *argv) +{ + // Argument : + // 0 : mass to apply this interactor + // 1,2 : XY : center of the Circle + // 3 : Circle radius + // 4 : K + // [5] : power of the force + // [6] : min radium of the interactor + // [7] : max radium of the interactor + + + t_float a, b, R, K, power, tmp, Rmin, Rmax; + t_int i; + + if (!((argc>=5) && (argv[1].a_type == A_FLOAT)&& (argv[2].a_type == A_FLOAT)&& (argv[3].a_type == A_FLOAT) )) + { + post("bad argument for iCircle"); + return; + } + + a = atom_getfloatarg(1, argc, argv); + b = atom_getfloatarg(2, argc, argv); + + R = atom_getfloatarg(3, argc, argv); + + K = atom_getfloatarg(4, argc, argv); + power = atom_getfloatarg(5, argc, argv); + if (power == 0) power = 1; + + Rmin = 0; + if ((argc>=7) && (argv[6].a_type == A_FLOAT)) { Rmin = (atom_getfloatarg(6,argc,argv));} + Rmax = 1000000; + if ((argc>=8) && (argv[7].a_type == A_FLOAT)) { Rmax = (atom_getfloatarg(7,argc,argv));} + + if ((argc>0) && (argv[0].a_type == A_FLOAT) && (atom_getfloatarg(0,argc,argv) == -1)) // all + { + for (i=0; i < x->nb_mass; i++) + { + pmpd2d_iCircle_i(x, i, a, b, R, K, power, Rmin, Rmax); + } + } + else if (((argc>0) && argv[0].a_type == A_FLOAT)) + { + pmpd2d_iCircle_i(x, atom_getfloatarg(0,argc,argv), a, b, R, K, power, Rmin, Rmax); + } + else if ((argc>0) && (argv[0].a_type == A_SYMBOL)) + { + for (i=0; i < x->nb_mass; i++) + { + if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id) + { + pmpd2d_iCircle_i(x, i, a, b, R, K, power, Rmin, Rmax); + } + } + } +} + +// -------------------------------------------------------- + +void pmpd2d_iLine_i(t_pmpd2d *x, int i, t_float a, t_float b, t_float c, t_float K, t_float power, t_float Rmin, t_float Rmax) +{ + t_float distance, force; + + distance = ( (a * x->mass[i].posX) + (b * x->mass[i].posY) ) - c; + + if ( (distance>Rmin) && (distance<=Rmax) ) + { + force = pow_ch(K * distance, power); + x->mass[i].forceX += a * force; + x->mass[i].forceY += b * force; + } +} + +void pmpd2d_iLine(t_pmpd2d *x, t_symbol *s, int argc, t_atom *argv) +{ + // Argument : + // 0 : mass to apply this interactor + // 1, 2 : X1 Y1 : 1st point of the line + // 3, 4 : X2 Y2 : 2nd point of the line + // 5 : K + // [6] : power of the force + // [7] : min radium of the interactor + // [8] : max radium of the interactor + + + t_float a, b, c, X1, X2, Y1, Y2, K, power, tmp, Rmin, Rmax; + t_int i; + + if (!((argc>=6) && (argv[1].a_type == A_FLOAT) && (argv[2].a_type == A_FLOAT) && (argv[3].a_type == A_FLOAT) && (argv[4].a_type == A_FLOAT) && (argv[5].a_type == A_FLOAT) )) + { + post("bad argument for iLine"); + return; + } + + X1 = atom_getfloatarg(1, argc, argv); + Y1 = atom_getfloatarg(2, argc, argv); + + X2 = atom_getfloatarg(3, argc, argv); + Y2 = atom_getfloatarg(4, argc, argv); + + a = Y2 - Y1; + b = X1 - X2; + tmp = sqrt(a*a + b*b); + if (tmp == 0) + { + a = 1; + b = 0; + tmp = 1; + } + a /= tmp; + b /= tmp; + c = - (a * X1 + b * Y1); + // line equation : aX + bY + c = 0 + + K = atom_getfloatarg(5, argc, argv); + power = atom_getfloatarg(6, argc, argv); + if (power == 0) power = 1; + + Rmin = 0; + if ((argc>=8) && (argv[7].a_type == A_FLOAT)) { Rmin = (atom_getfloatarg(7,argc,argv));} + Rmax = 1000000; + if ((argc>=9) && (argv[8].a_type == A_FLOAT)) { Rmax = (atom_getfloatarg(8,argc,argv));} + + if ((argc>0) && (argv[0].a_type == A_FLOAT) && (atom_getfloatarg(0,argc,argv) == -1)) // all + { + for (i=0; i < x->nb_mass; i++) + { + pmpd2d_iLine_i(x, i, a, b, c, K, power, Rmin, Rmax); + } + } + else if (((argc>0) && argv[0].a_type == A_FLOAT)) + { + pmpd2d_iLine_i(x, atom_getfloatarg(0,argc,argv), a, b, c, K, power, Rmin, Rmax); + } + else if ((argc>0) && (argv[0].a_type == A_SYMBOL)) + { + for (i=0; i < x->nb_mass; i++) + { + if (atom_getsymbolarg(0,argc,argv) == x->mass[i].Id) + { + pmpd2d_iLine_i(x, i, a, b, c, K, power, Rmin, Rmax); + } + } + } +} |