aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Henry <nusmuk@users.sourceforge.net>2013-04-09 10:43:54 +0000
committerCyrille Henry <nusmuk@users.sourceforge.net>2013-04-09 10:43:54 +0000
commit7d4780c91c33c3aa7e1663762783350935dc8d04 (patch)
tree1e0f0aaaa269d2a0f12cd0b3d9fcdb5698157346
parent70583ff7ea3d34acc0d119f401046dd1e0257283 (diff)
add interactors to pmpd2d
svn path=/trunk/externals/pmpd/; revision=17078
-rw-r--r--TODO.txt1
-rw-r--r--pmpd2d.c4
-rw-r--r--pmpd2d_interactor.c178
3 files changed, 181 insertions, 2 deletions
diff --git a/TODO.txt b/TODO.txt
index 4920a5d..67ef588 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -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);
diff --git a/pmpd2d.c b/pmpd2d.c
index a1c8400..9fc0f4d 100644
--- a/pmpd2d.c
+++ b/pmpd2d.c
@@ -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);
+ }
+ }
+ }
+}