just a test

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Wed Mar 26 09:52:31 2014 +0000
Revision:
40:ee217eff826c
Parent:
32:52273c3291fe
Child:
41:32c80fc09b59
not bad...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedalvaro 31:5f039cbddee8 1 /*
mbedalvaro 31:5f039cbddee8 2 * elasticLoop.cpp
mbedalvaro 31:5f039cbddee8 3 * laserBlobPure
mbedalvaro 31:5f039cbddee8 4 *
mbedalvaro 31:5f039cbddee8 5 * Created by CASSINELLI ALVARO on 5/20/11.
mbedalvaro 31:5f039cbddee8 6 * Copyright 2011 TOKYO UNIVERSITY. All rights reserved.
mbedalvaro 31:5f039cbddee8 7 *
mbedalvaro 31:5f039cbddee8 8 */
mbedalvaro 31:5f039cbddee8 9
mbedalvaro 31:5f039cbddee8 10 #include "elasticLoop.h"
mbedalvaro 31:5f039cbddee8 11
mbedalvaro 31:5f039cbddee8 12 // SHOULD NOT BE HERE: (only because I am using AD_MIRRIOR... max and min in the set region function that should not be here)
mbedalvaro 31:5f039cbddee8 13 #include "hardwareIO.h"
mbedalvaro 31:5f039cbddee8 14
mbedalvaro 31:5f039cbddee8 15 elasticLoop::elasticLoop() {
mbedalvaro 31:5f039cbddee8 16 }
mbedalvaro 31:5f039cbddee8 17
mbedalvaro 31:5f039cbddee8 18 elasticLoop::~elasticLoop() {
mbedalvaro 31:5f039cbddee8 19 // no need to do clear, this is done by default when clearing the vector container?
mbedalvaro 31:5f039cbddee8 20 massesLoop.clear();
mbedalvaro 31:5f039cbddee8 21 loopSpringArray.clear();
mbedalvaro 31:5f039cbddee8 22 hairVector.clear();
mbedalvaro 31:5f039cbddee8 23 lightForce.clear();
mbedalvaro 31:5f039cbddee8 24 centralSpringArray.clear();
mbedalvaro 31:5f039cbddee8 25 displaySensingBuffer.lsdTrajectory.clear();
mbedalvaro 31:5f039cbddee8 26 }
mbedalvaro 31:5f039cbddee8 27
mbedalvaro 31:5f039cbddee8 28
mbedalvaro 31:5f039cbddee8 29 void elasticLoop::createBlob(int _id, ElasticLoopMode _elasticBlobMode, vector2Df _initPos, vector2Df _initSpeed) {
mbedalvaro 31:5f039cbddee8 30 // (1) set ID:
mbedalvaro 31:5f039cbddee8 31 identifier=_id;
mbedalvaro 31:5f039cbddee8 32
mbedalvaro 31:5f039cbddee8 33 startCenter=_initPos;
mbedalvaro 31:5f039cbddee8 34 startSpeed=_initSpeed;
mbedalvaro 31:5f039cbddee8 35
mbedalvaro 31:5f039cbddee8 36 // (2) Initialize common variables of all blobs (base class):
mbedalvaro 31:5f039cbddee8 37 initCommonVariables();
mbedalvaro 31:5f039cbddee8 38
mbedalvaro 31:5f039cbddee8 39 // (3) initialize common variables for the elastic blob types:
mbedalvaro 31:5f039cbddee8 40 slidingDirection=true; // (will change when touching wall)
mbedalvaro 31:5f039cbddee8 41 // Sending data:
mbedalvaro 31:5f039cbddee8 42 periodSendingData=15; // in ms
mbedalvaro 31:5f039cbddee8 43 sendingLoopPositions=false;
mbedalvaro 31:5f039cbddee8 44 sendingBlobArea=true;
mbedalvaro 31:5f039cbddee8 45 sendingKineticEnergy=true;
mbedalvaro 32:52273c3291fe 46 sendingBlobMaxMin=true;
mbedalvaro 32:52273c3291fe 47 // send ALWAYS, regardless of the fact the blob is being touched or not, in case of elastic loops:
mbedalvaro 32:52273c3291fe 48 sendingOnlyWhenTouch=false;
mbedalvaro 31:5f039cbddee8 49
mbedalvaro 31:5f039cbddee8 50 // (3) Initialize secondary variables depending on the blob type and mode:
mbedalvaro 31:5f039cbddee8 51
mbedalvaro 31:5f039cbddee8 52 // NOTE (!): the mode does not affect the update method; in fact, all these elastic loops have different behaviours because of different parameters (but the booleans modes could
mbedalvaro 31:5f039cbddee8 53 // actually be "condensed" in a mode...)
mbedalvaro 31:5f039cbddee8 54
mbedalvaro 31:5f039cbddee8 55 switch (_elasticBlobMode) {
mbedalvaro 31:5f039cbddee8 56 case RELAX:
mbedalvaro 31:5f039cbddee8 57
mbedalvaro 31:5f039cbddee8 58 // Name of this kind of spot:
mbedalvaro 31:5f039cbddee8 59 sprintf(spotName,"loop_relax"); //this is an relaxing elastic loop
mbedalvaro 31:5f039cbddee8 60
mbedalvaro 31:5f039cbddee8 61 // Color: (use parameter in the future):
mbedalvaro 31:5f039cbddee8 62 //setColor(0x07);//0x04+0x02>>i);
mbedalvaro 31:5f039cbddee8 63 setColor(0x04);
mbedalvaro 31:5f039cbddee8 64
mbedalvaro 31:5f039cbddee8 65 // default (initial) shape (the scafold belongs to the base class):
mbedalvaro 31:5f039cbddee8 66 startRadius=400;
mbedalvaro 31:5f039cbddee8 67 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 40); //(float _radius, vector2Dd _pos, int _numScafoldPoints);
mbedalvaro 31:5f039cbddee8 68
mbedalvaro 31:5f039cbddee8 69 // Numeric parameters for the simulated mechanical system:
mbedalvaro 31:5f039cbddee8 70 massLoopParticle=0.25;
mbedalvaro 31:5f039cbddee8 71 dampMotionMassesLoop=0.025;//0.17;
mbedalvaro 31:5f039cbddee8 72 massAnchor=2.0;
mbedalvaro 31:5f039cbddee8 73 dampMotionAnchorMass=0.001;
mbedalvaro 31:5f039cbddee8 74 // Springs:
mbedalvaro 31:5f039cbddee8 75 centralSpringK=0.3;
mbedalvaro 31:5f039cbddee8 76 centralSpringRelax=startRadius;// use the radius of the scafold
mbedalvaro 31:5f039cbddee8 77 interSpringK=0.46;
mbedalvaro 31:5f039cbddee8 78 interSpringRelax=20;
mbedalvaro 31:5f039cbddee8 79 // for "zack-like" blob:
mbedalvaro 31:5f039cbddee8 80 interParticleRange=100;
mbedalvaro 31:5f039cbddee8 81 factorInterParticleForce=18.0;
mbedalvaro 31:5f039cbddee8 82
mbedalvaro 31:5f039cbddee8 83 searchActive=false;
mbedalvaro 31:5f039cbddee8 84 pseudopodesMode=false; // this is for contour following.
mbedalvaro 31:5f039cbddee8 85
mbedalvaro 31:5f039cbddee8 86 // Active/inactive forces:
mbedalvaro 31:5f039cbddee8 87 springForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 88 lightForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 89 forceBorderOnLoop=false;
mbedalvaro 31:5f039cbddee8 90 nuclearForceOnLoop=false;//true;
mbedalvaro 31:5f039cbddee8 91 interParticleForceOnLoop=false;
mbedalvaro 31:5f039cbddee8 92 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 31:5f039cbddee8 93
mbedalvaro 31:5f039cbddee8 94 // Recentering vector:
mbedalvaro 31:5f039cbddee8 95 angleCorrectionForceLoop=0;// in deg
mbedalvaro 31:5f039cbddee8 96 recenteringForceOnLoop=false;
mbedalvaro 31:5f039cbddee8 97 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 31:5f039cbddee8 98 recenteringForceOnNucleus=false;//true;
mbedalvaro 31:5f039cbddee8 99
mbedalvaro 31:5f039cbddee8 100 factorLightForce=4.0;//3.0;//8.0;
mbedalvaro 31:5f039cbddee8 101 factorRecenteringAnchorMass=20.0/bluePrint.scafold.size(); // use number of points in the scafold
mbedalvaro 31:5f039cbddee8 102 factorRecenteringLoopMass=0.3;
mbedalvaro 31:5f039cbddee8 103 factorPressureLoopMass=1.0;
mbedalvaro 31:5f039cbddee8 104 factorForceBorder=4.5;
mbedalvaro 31:5f039cbddee8 105
mbedalvaro 31:5f039cbddee8 106 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 31:5f039cbddee8 107 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 31:5f039cbddee8 108 displaySensingBuffer.setDelayMirrors(2);
mbedalvaro 31:5f039cbddee8 109
mbedalvaro 31:5f039cbddee8 110 break;
mbedalvaro 31:5f039cbddee8 111
mbedalvaro 31:5f039cbddee8 112 case CONTRACT:
mbedalvaro 31:5f039cbddee8 113
mbedalvaro 31:5f039cbddee8 114 sprintf(spotName,"loop_contract"); //this is an relaxing elastic loop
mbedalvaro 31:5f039cbddee8 115
mbedalvaro 31:5f039cbddee8 116 setColor(0x07);//0x04+0x02>>i);
mbedalvaro 31:5f039cbddee8 117
mbedalvaro 31:5f039cbddee8 118 // default (initial) shape:
mbedalvaro 31:5f039cbddee8 119 startRadius =400;
mbedalvaro 31:5f039cbddee8 120 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 40); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 31:5f039cbddee8 121
mbedalvaro 31:5f039cbddee8 122 // Numeric parameters for the simulated mechanical system:
mbedalvaro 31:5f039cbddee8 123 massLoopParticle=0.25;
mbedalvaro 31:5f039cbddee8 124 dampMotionMassesLoop=0.024;//0.17;
mbedalvaro 31:5f039cbddee8 125 massAnchor=2.0;
mbedalvaro 31:5f039cbddee8 126 dampMotionAnchorMass=0.001;
mbedalvaro 31:5f039cbddee8 127 // Springs:
mbedalvaro 31:5f039cbddee8 128 centralSpringK=0.5;
mbedalvaro 31:5f039cbddee8 129 centralSpringRelax=startRadius;
mbedalvaro 31:5f039cbddee8 130 interSpringK=0.4;//46;
mbedalvaro 31:5f039cbddee8 131 interSpringRelax=30;
mbedalvaro 31:5f039cbddee8 132 // for "zack-like" blob:
mbedalvaro 31:5f039cbddee8 133 interParticleRange=100;
mbedalvaro 31:5f039cbddee8 134 factorInterParticleForce=18.0;
mbedalvaro 31:5f039cbddee8 135
mbedalvaro 31:5f039cbddee8 136 searchActive=false;
mbedalvaro 31:5f039cbddee8 137 pseudopodesMode=false; // this is for contour following.
mbedalvaro 31:5f039cbddee8 138
mbedalvaro 31:5f039cbddee8 139 // Active/Inactive Forces:
mbedalvaro 31:5f039cbddee8 140 springForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 141 lightForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 142 forceBorderOnLoop=false;
mbedalvaro 31:5f039cbddee8 143 nuclearForceOnLoop=true;//true;
mbedalvaro 31:5f039cbddee8 144 interParticleForceOnLoop=false;
mbedalvaro 31:5f039cbddee8 145 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 31:5f039cbddee8 146 // Recentering vector:
mbedalvaro 31:5f039cbddee8 147 angleCorrectionForceLoop=0;// in deg
mbedalvaro 31:5f039cbddee8 148 recenteringForceOnLoop=false;
mbedalvaro 31:5f039cbddee8 149 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 31:5f039cbddee8 150 recenteringForceOnNucleus=false;//true;
mbedalvaro 31:5f039cbddee8 151
mbedalvaro 31:5f039cbddee8 152 factorLightForce=6.0;//3.0;//8.0;
mbedalvaro 31:5f039cbddee8 153 factorRecenteringAnchorMass=20.0/bluePrint.scafold.size();
mbedalvaro 31:5f039cbddee8 154 factorRecenteringLoopMass=0.3;
mbedalvaro 31:5f039cbddee8 155 factorPressureLoopMass=1.0;
mbedalvaro 31:5f039cbddee8 156 factorForceBorder=4.5;
mbedalvaro 31:5f039cbddee8 157
mbedalvaro 31:5f039cbddee8 158 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 31:5f039cbddee8 159 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 31:5f039cbddee8 160 displaySensingBuffer.setDelayMirrors(2); // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 31:5f039cbddee8 161
mbedalvaro 31:5f039cbddee8 162 break;
mbedalvaro 31:5f039cbddee8 163 case CONTRACT_CENTRAL:
mbedalvaro 31:5f039cbddee8 164
mbedalvaro 31:5f039cbddee8 165 sprintf(spotName,"contract_central");
mbedalvaro 31:5f039cbddee8 166
mbedalvaro 31:5f039cbddee8 167 //setColor(0x07);//0x04+0x02>>i);
mbedalvaro 31:5f039cbddee8 168 setColor(0x04);
mbedalvaro 31:5f039cbddee8 169
mbedalvaro 31:5f039cbddee8 170 // default (initial) shape:
mbedalvaro 31:5f039cbddee8 171 startRadius=400;
mbedalvaro 31:5f039cbddee8 172 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 45); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 31:5f039cbddee8 173
mbedalvaro 31:5f039cbddee8 174 // Numeric parameters for the simulated mechanical system:
mbedalvaro 31:5f039cbddee8 175 massLoopParticle=0.3;
mbedalvaro 31:5f039cbddee8 176 dampMotionMassesLoop=0.023;//0.17;
mbedalvaro 31:5f039cbddee8 177 massAnchor=0.5;
mbedalvaro 31:5f039cbddee8 178 dampMotionAnchorMass=0.001;
mbedalvaro 31:5f039cbddee8 179 // Springs:
mbedalvaro 31:5f039cbddee8 180 centralSpringK=0.3;
mbedalvaro 31:5f039cbddee8 181 centralSpringRelax=startRadius;
mbedalvaro 31:5f039cbddee8 182 interSpringK=0.54;//46;
mbedalvaro 31:5f039cbddee8 183 interSpringRelax=30;
mbedalvaro 31:5f039cbddee8 184 // for "zack-like" blob:
mbedalvaro 31:5f039cbddee8 185 interParticleRange=100;
mbedalvaro 31:5f039cbddee8 186 factorInterParticleForce=18.0;
mbedalvaro 31:5f039cbddee8 187
mbedalvaro 31:5f039cbddee8 188 searchActive=false;
mbedalvaro 31:5f039cbddee8 189 pseudopodesMode=false; // this is for contour following.
mbedalvaro 31:5f039cbddee8 190
mbedalvaro 31:5f039cbddee8 191 // Active/Inactive Forces:
mbedalvaro 31:5f039cbddee8 192 springForcesOnLoop= true;
mbedalvaro 31:5f039cbddee8 193 lightForcesOnLoop= true;
mbedalvaro 31:5f039cbddee8 194 forceBorderOnLoop=false;
mbedalvaro 31:5f039cbddee8 195 nuclearForceOnLoop=false;//true;
mbedalvaro 31:5f039cbddee8 196 interParticleForceOnLoop=false;
mbedalvaro 31:5f039cbddee8 197 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 31:5f039cbddee8 198 // Recentering vector:
mbedalvaro 31:5f039cbddee8 199 angleCorrectionForceLoop=0;// in deg
mbedalvaro 31:5f039cbddee8 200 recenteringForceOnLoop=false ; //true; !!!!!!!!!!!!!!!
mbedalvaro 31:5f039cbddee8 201 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 31:5f039cbddee8 202 recenteringForceOnNucleus=false;//true;
mbedalvaro 31:5f039cbddee8 203
mbedalvaro 31:5f039cbddee8 204 factorLightForce=6.3;//4.3;
mbedalvaro 31:5f039cbddee8 205 factorRecenteringAnchorMass= 20.0/bluePrint.scafold.size();
mbedalvaro 31:5f039cbddee8 206 factorRecenteringLoopMass=0.045;
mbedalvaro 31:5f039cbddee8 207 factorPressureLoopMass=1.5;
mbedalvaro 31:5f039cbddee8 208 factorForceBorder=150;
mbedalvaro 31:5f039cbddee8 209
mbedalvaro 31:5f039cbddee8 210 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 31:5f039cbddee8 211 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 31:5f039cbddee8 212 displaySensingBuffer.setDelayMirrors(4);
mbedalvaro 31:5f039cbddee8 213
mbedalvaro 31:5f039cbddee8 214 break;
mbedalvaro 31:5f039cbddee8 215
mbedalvaro 31:5f039cbddee8 216 case CONTRACT_CENTRAL_FAST:
mbedalvaro 31:5f039cbddee8 217
mbedalvaro 31:5f039cbddee8 218 //setColor(0x07);//0x04+0x02>>i);
mbedalvaro 31:5f039cbddee8 219 setColor(0x04);
mbedalvaro 31:5f039cbddee8 220
mbedalvaro 31:5f039cbddee8 221 // default (initial) shape:
mbedalvaro 31:5f039cbddee8 222 startRadius=150;
mbedalvaro 31:5f039cbddee8 223 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 40); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 31:5f039cbddee8 224
mbedalvaro 31:5f039cbddee8 225 // Numeric parameters for the simulated mechanical system:
mbedalvaro 31:5f039cbddee8 226 massLoopParticle=0.06;
mbedalvaro 31:5f039cbddee8 227 dampMotionMassesLoop=0.021;//0.17;
mbedalvaro 31:5f039cbddee8 228 massAnchor=0.5;
mbedalvaro 31:5f039cbddee8 229 dampMotionAnchorMass=0.01;
mbedalvaro 31:5f039cbddee8 230 // Springs:
mbedalvaro 31:5f039cbddee8 231 centralSpringK=0.3;
mbedalvaro 31:5f039cbddee8 232 centralSpringRelax=startRadius;
mbedalvaro 31:5f039cbddee8 233 interSpringK=0.54;//46;
mbedalvaro 31:5f039cbddee8 234 interSpringRelax=40;
mbedalvaro 31:5f039cbddee8 235 // for "zack-like" blob:
mbedalvaro 31:5f039cbddee8 236 interParticleRange=150;
mbedalvaro 31:5f039cbddee8 237 factorInterParticleForce=160.0;
mbedalvaro 31:5f039cbddee8 238
mbedalvaro 31:5f039cbddee8 239 searchActive=false;
mbedalvaro 31:5f039cbddee8 240 pseudopodesMode=false; // this is for contour following.
mbedalvaro 31:5f039cbddee8 241
mbedalvaro 31:5f039cbddee8 242 // Active/Inactive Forces:
mbedalvaro 31:5f039cbddee8 243 springForcesOnLoop= true;
mbedalvaro 31:5f039cbddee8 244 lightForcesOnLoop= true;
mbedalvaro 31:5f039cbddee8 245 forceBorderOnLoop=false;
mbedalvaro 31:5f039cbddee8 246 nuclearForceOnLoop=false;
mbedalvaro 31:5f039cbddee8 247 interParticleForceOnLoop=true; //!!!
mbedalvaro 31:5f039cbddee8 248 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 31:5f039cbddee8 249 // Recentering vector:
mbedalvaro 31:5f039cbddee8 250 angleCorrectionForceLoop=90;// in deg
mbedalvaro 31:5f039cbddee8 251 recenteringForceOnLoop=true;
mbedalvaro 31:5f039cbddee8 252 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 31:5f039cbddee8 253 recenteringForceOnNucleus=false;//true;
mbedalvaro 31:5f039cbddee8 254
mbedalvaro 31:5f039cbddee8 255 factorLightForce=-4;//3.0;//8.0;
mbedalvaro 31:5f039cbddee8 256 factorRecenteringAnchorMass= 20.0/bluePrint.scafold.size();
mbedalvaro 31:5f039cbddee8 257 factorRecenteringLoopMass=0.06;
mbedalvaro 31:5f039cbddee8 258 factorPressureLoopMass=1.5;
mbedalvaro 31:5f039cbddee8 259 factorForceBorder=150;
mbedalvaro 31:5f039cbddee8 260
mbedalvaro 31:5f039cbddee8 261 displaySensingBuffer.setDelayMirrors(70);
mbedalvaro 31:5f039cbddee8 262 break;
mbedalvaro 31:5f039cbddee8 263
mbedalvaro 31:5f039cbddee8 264 case CONTOUR_FOLLOWING:
mbedalvaro 31:5f039cbddee8 265 sprintf(spotName,"following"); //this is a contour-following loop
mbedalvaro 31:5f039cbddee8 266
mbedalvaro 31:5f039cbddee8 267 //setColor(0x07);//0x04+0x02>>i);
mbedalvaro 31:5f039cbddee8 268 setColor(0x04);
mbedalvaro 31:5f039cbddee8 269
mbedalvaro 31:5f039cbddee8 270 // default (initial) shape:
mbedalvaro 31:5f039cbddee8 271 startRadius=100;
mbedalvaro 31:5f039cbddee8 272 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 20); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 31:5f039cbddee8 273
mbedalvaro 31:5f039cbddee8 274 // Numeric parameters for the simulated mechanical system:
mbedalvaro 31:5f039cbddee8 275 massLoopParticle=0.05;
mbedalvaro 31:5f039cbddee8 276 dampMotionMassesLoop=0.27;//0.17;
mbedalvaro 31:5f039cbddee8 277 massAnchor=3.0;
mbedalvaro 31:5f039cbddee8 278 dampMotionAnchorMass=0.03;
mbedalvaro 31:5f039cbddee8 279 // Springs:
mbedalvaro 31:5f039cbddee8 280 centralSpringK=0.4;
mbedalvaro 31:5f039cbddee8 281 centralSpringRelax=100;//bluePrint.radius;
mbedalvaro 40:ee217eff826c 282 interSpringK=0.43;//46;
mbedalvaro 31:5f039cbddee8 283 interSpringRelax=0.7*startRadius*2*sin(1.0* PI/ bluePrint.scafold.size()); // if factor=1, this makes for a perfect polygon at relax for all springs...
mbedalvaro 31:5f039cbddee8 284 // for "zack-like" blob:
mbedalvaro 31:5f039cbddee8 285 interParticleRange=70;
mbedalvaro 31:5f039cbddee8 286 factorInterParticleForce=4.0;
mbedalvaro 31:5f039cbddee8 287
mbedalvaro 31:5f039cbddee8 288 searchActive=true;
mbedalvaro 31:5f039cbddee8 289 pseudopodesMode=true; // this is for contour following.
mbedalvaro 31:5f039cbddee8 290
mbedalvaro 31:5f039cbddee8 291 // Active/Inactive Forces:
mbedalvaro 31:5f039cbddee8 292 springForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 293 lightForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 294 forceBorderOnLoop=false;
mbedalvaro 31:5f039cbddee8 295 nuclearForceOnLoop=false;//true;
mbedalvaro 31:5f039cbddee8 296 interParticleForceOnLoop=true;
mbedalvaro 31:5f039cbddee8 297 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 31:5f039cbddee8 298 // Recentering vector:
mbedalvaro 40:ee217eff826c 299 angleCorrectionForceLoop=236;//239;// in deg
mbedalvaro 31:5f039cbddee8 300 recenteringForceOnLoop=true;
mbedalvaro 31:5f039cbddee8 301 angleCorrectionForceNucleus=180;// in deg
mbedalvaro 31:5f039cbddee8 302 recenteringForceOnNucleus=false;//true;
mbedalvaro 31:5f039cbddee8 303
mbedalvaro 40:ee217eff826c 304 factorLightForce=2.4;//3.0;//8.0;
mbedalvaro 31:5f039cbddee8 305 factorRecenteringAnchorMass=1.0;//20.0/scafold.size();
mbedalvaro 31:5f039cbddee8 306 factorRecenteringLoopMass=0.09;
mbedalvaro 31:5f039cbddee8 307 factorPressureLoopMass=1.5;
mbedalvaro 31:5f039cbddee8 308 factorForceBorder=150;
mbedalvaro 31:5f039cbddee8 309 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 31:5f039cbddee8 310 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 40:ee217eff826c 311 displaySensingBuffer.setDelayMirrors(3);
mbedalvaro 31:5f039cbddee8 312
mbedalvaro 31:5f039cbddee8 313 break;
mbedalvaro 31:5f039cbddee8 314 case CONTOUR_FOLLOWING_FAST:
mbedalvaro 31:5f039cbddee8 315 sprintf(spotName,"following_fast");
mbedalvaro 31:5f039cbddee8 316
mbedalvaro 31:5f039cbddee8 317 setColor(0x07);//0x04+0x02>>i);
mbedalvaro 31:5f039cbddee8 318
mbedalvaro 31:5f039cbddee8 319 // default (initial) shape:
mbedalvaro 31:5f039cbddee8 320 startRadius=100;
mbedalvaro 31:5f039cbddee8 321 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 30); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 31:5f039cbddee8 322
mbedalvaro 31:5f039cbddee8 323 // Numeric parameters for the simulated mechanical system:
mbedalvaro 31:5f039cbddee8 324 massLoopParticle=0.05;
mbedalvaro 31:5f039cbddee8 325 dampMotionMassesLoop=0.27;//0.17;
mbedalvaro 31:5f039cbddee8 326 massAnchor=3.0;
mbedalvaro 31:5f039cbddee8 327 dampMotionAnchorMass=0.03;
mbedalvaro 31:5f039cbddee8 328 // Springs:
mbedalvaro 31:5f039cbddee8 329 centralSpringK=-200;
mbedalvaro 31:5f039cbddee8 330 centralSpringRelax=100;//bluePrint.radius;
mbedalvaro 31:5f039cbddee8 331 interSpringK=0.5;//46;
mbedalvaro 31:5f039cbddee8 332 interSpringRelax=0.7*startRadius*2*sin(1.0* PI/bluePrint.scafold.size()); // if factor=1, this makes for a perfect polygon at relax for all springs...
mbedalvaro 31:5f039cbddee8 333 // for "zack-like" blob:
mbedalvaro 31:5f039cbddee8 334 interParticleRange=80;
mbedalvaro 31:5f039cbddee8 335 factorInterParticleForce=4.0;
mbedalvaro 31:5f039cbddee8 336
mbedalvaro 31:5f039cbddee8 337 searchActive=false;
mbedalvaro 31:5f039cbddee8 338 pseudopodesMode=true; // this is for contour following.
mbedalvaro 31:5f039cbddee8 339
mbedalvaro 31:5f039cbddee8 340 // Active/Inactive Forces:
mbedalvaro 31:5f039cbddee8 341 springForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 342 lightForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 343 forceBorderOnLoop=false;
mbedalvaro 31:5f039cbddee8 344 nuclearForceOnLoop=false;//true;
mbedalvaro 31:5f039cbddee8 345 interParticleForceOnLoop=false;
mbedalvaro 31:5f039cbddee8 346 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 31:5f039cbddee8 347 // Recentering vector:
mbedalvaro 31:5f039cbddee8 348 angleCorrectionForceLoop=243;// in deg
mbedalvaro 31:5f039cbddee8 349 recenteringForceOnLoop=true;
mbedalvaro 31:5f039cbddee8 350 angleCorrectionForceNucleus=180;// in deg
mbedalvaro 31:5f039cbddee8 351 recenteringForceOnNucleus=false;//true;
mbedalvaro 31:5f039cbddee8 352
mbedalvaro 31:5f039cbddee8 353 factorLightForce=2.3;//3.0;//8.0;
mbedalvaro 31:5f039cbddee8 354 factorRecenteringAnchorMass=1.0;//20.0/bluePrint.scafold.size();
mbedalvaro 31:5f039cbddee8 355 factorRecenteringLoopMass=0.09;
mbedalvaro 31:5f039cbddee8 356 factorPressureLoopMass=1.5;
mbedalvaro 31:5f039cbddee8 357 factorForceBorder=150;
mbedalvaro 31:5f039cbddee8 358
mbedalvaro 31:5f039cbddee8 359 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 31:5f039cbddee8 360 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 31:5f039cbddee8 361 displaySensingBuffer.setDelayMirrors(2);
mbedalvaro 31:5f039cbddee8 362 break;
mbedalvaro 31:5f039cbddee8 363 case BOUNCING:
mbedalvaro 31:5f039cbddee8 364 sprintf(spotName,"bouncing");
mbedalvaro 31:5f039cbddee8 365
mbedalvaro 31:5f039cbddee8 366 setColor(0x07);//0x04+0x02>>i);
mbedalvaro 31:5f039cbddee8 367
mbedalvaro 31:5f039cbddee8 368 // default (initial) shape:
mbedalvaro 31:5f039cbddee8 369 startRadius=70;
mbedalvaro 31:5f039cbddee8 370 bluePrint.buildCircularScafold(startRadius, vector2Dd(0,0), 20); //(float _radius, vector2Dd _pos,vector2D _vel, int _numScafoldPoints);
mbedalvaro 31:5f039cbddee8 371
mbedalvaro 31:5f039cbddee8 372 // Numeric parameters for the simulated mechanical system:
mbedalvaro 31:5f039cbddee8 373 massLoopParticle=5.0;
mbedalvaro 31:5f039cbddee8 374 dampMotionMassesLoop=0.001;//0.17;
mbedalvaro 31:5f039cbddee8 375 massAnchor=1.0;
mbedalvaro 31:5f039cbddee8 376 dampMotionAnchorMass=0.002;
mbedalvaro 31:5f039cbddee8 377 // Springs:
mbedalvaro 31:5f039cbddee8 378 centralSpringK=1.0;
mbedalvaro 31:5f039cbddee8 379 centralSpringRelax=70;//bluePrint.radius;
mbedalvaro 31:5f039cbddee8 380 interSpringK=0.4;//46;
mbedalvaro 31:5f039cbddee8 381 interSpringRelax==1.0*startRadius*2*sin(1.0* PI/bluePrint.scafold.size()); // if factor=1, this makes for a perfect polygon at relax for all springs...
mbedalvaro 31:5f039cbddee8 382 // for "zack-like" blob:
mbedalvaro 31:5f039cbddee8 383 interParticleRange=100;
mbedalvaro 31:5f039cbddee8 384 factorInterParticleForce=3.0;
mbedalvaro 31:5f039cbddee8 385
mbedalvaro 31:5f039cbddee8 386 searchActive=false;
mbedalvaro 31:5f039cbddee8 387 pseudopodesMode=false; // this is for contour following.
mbedalvaro 31:5f039cbddee8 388
mbedalvaro 31:5f039cbddee8 389 // Active/Inactive Forces:
mbedalvaro 31:5f039cbddee8 390 springForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 391 lightForcesOnLoop=true;
mbedalvaro 31:5f039cbddee8 392 forceBorderOnLoop=true;
mbedalvaro 31:5f039cbddee8 393 nuclearForceOnLoop=true;//true;
mbedalvaro 31:5f039cbddee8 394 interParticleForceOnLoop=false;
mbedalvaro 31:5f039cbddee8 395 forceInternalPressureOnLoop=false; // (when true, either constant force or calculated area using Green function or approximation by bounding box)
mbedalvaro 31:5f039cbddee8 396 // Recentering vector:
mbedalvaro 31:5f039cbddee8 397 angleCorrectionForceLoop=0;// in deg
mbedalvaro 31:5f039cbddee8 398 recenteringForceOnLoop=false;
mbedalvaro 31:5f039cbddee8 399 angleCorrectionForceNucleus=0;// in deg
mbedalvaro 31:5f039cbddee8 400 recenteringForceOnNucleus=false;//true;
mbedalvaro 31:5f039cbddee8 401
mbedalvaro 31:5f039cbddee8 402 factorLightForce=0.6;//3.0;//8.0;
mbedalvaro 31:5f039cbddee8 403 factorRecenteringAnchorMass=100.0/bluePrint.scafold.size();
mbedalvaro 31:5f039cbddee8 404 factorRecenteringLoopMass=5.0;
mbedalvaro 31:5f039cbddee8 405 factorPressureLoopMass=2.0;
mbedalvaro 31:5f039cbddee8 406 factorForceBorder=4.5;
mbedalvaro 31:5f039cbddee8 407
mbedalvaro 31:5f039cbddee8 408 // per-blob mirror delay (if things were well adjusted - in particular mirror waiting times, then this could be 0.
mbedalvaro 31:5f039cbddee8 409 //But in case of unique blobs, it may be interesting to accelerate display AND correct the delay by software):
mbedalvaro 31:5f039cbddee8 410 displaySensingBuffer.setDelayMirrors(2);
mbedalvaro 31:5f039cbddee8 411 break;
mbedalvaro 31:5f039cbddee8 412 }
mbedalvaro 31:5f039cbddee8 413
mbedalvaro 31:5f039cbddee8 414 // Finally, we can create the loop using these parameters, and the positions given in the scafold:
mbedalvaro 31:5f039cbddee8 415 createLoopFromScafold(); // this sets the number of masses
mbedalvaro 31:5f039cbddee8 416
mbedalvaro 31:5f039cbddee8 417 // Excursion limits (ATTN!!! this will set the limits for all the masses, so we need FIRT to call to createLoopFromScafold - NO NEEDED ANYMORE: now calling to static member method of pointMass...)
mbedalvaro 31:5f039cbddee8 418 setRegionMotion(MIN_AD_MIRRORS, MIN_AD_MIRRORS, MAX_AD_MIRRORS, MAX_AD_MIRRORS);
mbedalvaro 31:5f039cbddee8 419
mbedalvaro 31:5f039cbddee8 420 // draw it once on the display buffer for good initialization:
mbedalvaro 31:5f039cbddee8 421 draw();
mbedalvaro 31:5f039cbddee8 422 }
mbedalvaro 31:5f039cbddee8 423
mbedalvaro 31:5f039cbddee8 424 void elasticLoop::speedFactor(float speedfactor) {
mbedalvaro 31:5f039cbddee8 425 // This method is more appropiate for rigid loop, but we can "simulate" speed up in case of elastic loop by changing some parameters, even if the loop is not
mbedalvaro 31:5f039cbddee8 426 // set in "contour following" mode.
mbedalvaro 31:5f039cbddee8 427 factorRecenteringLoopMass*=speedfactor;
mbedalvaro 31:5f039cbddee8 428 }
mbedalvaro 31:5f039cbddee8 429
mbedalvaro 31:5f039cbddee8 430 void elasticLoop::initSizeBlob(int _numMasses) {
mbedalvaro 31:5f039cbddee8 431 // Iinitialize blob size (number of points for the loop, as well as other structures such as lsdTrajectory)
mbedalvaro 31:5f039cbddee8 432 numMasses=_numMasses;
mbedalvaro 31:5f039cbddee8 433 // Since this is an elastic loop object, let's create an elastic loop of masses:
mbedalvaro 31:5f039cbddee8 434 massesLoop.resize(numMasses);
mbedalvaro 31:5f039cbddee8 435 loopSpringArray.resize(numMasses); // springs connecting consecutive masses
mbedalvaro 31:5f039cbddee8 436 // NOTE: to save memory, we can drop hairVector (use lightForce instead)
mbedalvaro 31:5f039cbddee8 437 hairVector.resize(numMasses); // the perpendiculars to the loop
mbedalvaro 31:5f039cbddee8 438 lightForce.resize(numMasses); // light force in each particle
mbedalvaro 31:5f039cbddee8 439 //vector2D totalLightForce; // this belongs to the base class now
mbedalvaro 31:5f039cbddee8 440 centralSpringArray.resize(numMasses); // springs connecting each mass to the anchorMass.
mbedalvaro 31:5f039cbddee8 441
mbedalvaro 31:5f039cbddee8 442 // Sensing and Display trajectory:
mbedalvaro 31:5f039cbddee8 443 displaySensingBuffer.lsdTrajectory.resize(numMasses); // the lsdTrajectory and the elastic loop will have the same number of points (this could be different - decimation?).
mbedalvaro 31:5f039cbddee8 444 }
mbedalvaro 31:5f039cbddee8 445
mbedalvaro 31:5f039cbddee8 446 // We will build the masses from the scafold shape (and maybe render it once on the lsdTrajectory to initialize this array?)
mbedalvaro 31:5f039cbddee8 447 void elasticLoop::createLoopFromScafold(void) {
mbedalvaro 31:5f039cbddee8 448 initSizeBlob(bluePrint.scafold.size()); // important: we will have here the same number of points in the scafold and the elastic loop (massLoop)
mbedalvaro 31:5f039cbddee8 449
mbedalvaro 31:5f039cbddee8 450 // Initial conditions for the loop masses:
mbedalvaro 31:5f039cbddee8 451 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 452 massesLoop[i].setIntegrationStep(0.23);//18); // VERY IMPORTANT! in the case of verlet integration, we need to set dt BEFORE setting the initial speed.
mbedalvaro 31:5f039cbddee8 453 massesLoop[i].setInitialCondition(startCenter.x+bluePrint.scafold[i].x,startCenter.y+bluePrint.scafold[i].y, startSpeed.x, startSpeed.y);
mbedalvaro 31:5f039cbddee8 454 massesLoop[i].mass=massLoopParticle;
mbedalvaro 31:5f039cbddee8 455 massesLoop[i].dampMotion=dampMotionMassesLoop;
mbedalvaro 31:5f039cbddee8 456 }
mbedalvaro 31:5f039cbddee8 457
mbedalvaro 31:5f039cbddee8 458 // Springs for the loop:
mbedalvaro 31:5f039cbddee8 459 for (int i = 0; i<numMasses; i++) {
mbedalvaro 31:5f039cbddee8 460 loopSpringArray[i].distance =interSpringRelax;
mbedalvaro 31:5f039cbddee8 461 // if we want an perfect polygon: =startRadius*2*sin(1.0* PI/ numMasses);
mbedalvaro 31:5f039cbddee8 462 // loopSpringArray[i].distance = startRadius*2*sin(1.0* PI/ numMasses);
mbedalvaro 31:5f039cbddee8 463 loopSpringArray[i].springiness = interSpringK;//*(i%5==0? .6 : 1);//0.4;//4f;
mbedalvaro 31:5f039cbddee8 464 loopSpringArray[i].massA = & (massesLoop[i ]);
mbedalvaro 31:5f039cbddee8 465 loopSpringArray[i].massB = & (massesLoop[(i+1) % numMasses]);
mbedalvaro 31:5f039cbddee8 466 }
mbedalvaro 31:5f039cbddee8 467
mbedalvaro 31:5f039cbddee8 468 // Central (anchor mass):
mbedalvaro 31:5f039cbddee8 469 anchorMass.setIntegrationStep(0.3); // VERY IMPORTANT! in the case of verlet integration, we need to set dt BEFORE setting the initial speed.
mbedalvaro 31:5f039cbddee8 470 anchorMass.setInitialCondition(startCenter, startSpeed);
mbedalvaro 31:5f039cbddee8 471 anchorMass.mass=massAnchor;
mbedalvaro 31:5f039cbddee8 472 anchorMass.dampMotion = dampMotionAnchorMass;
mbedalvaro 31:5f039cbddee8 473
mbedalvaro 31:5f039cbddee8 474
mbedalvaro 31:5f039cbddee8 475 // Initial conditions for central springs:
mbedalvaro 31:5f039cbddee8 476 for (int i = 0; i<numMasses; i++) {
mbedalvaro 31:5f039cbddee8 477 centralSpringArray[i].distance =centralSpringRelax;// + 60* cos ( (1.0*i / numMasses) * 7* 2 * PI);
mbedalvaro 31:5f039cbddee8 478 centralSpringArray[i].springiness =centralSpringK;// 0.4f;
mbedalvaro 31:5f039cbddee8 479 centralSpringArray[i].massA = & (anchorMass);
mbedalvaro 31:5f039cbddee8 480 centralSpringArray[i].massB = & (massesLoop[i]);
mbedalvaro 31:5f039cbddee8 481 }
mbedalvaro 31:5f039cbddee8 482 }
mbedalvaro 31:5f039cbddee8 483
mbedalvaro 31:5f039cbddee8 484
mbedalvaro 31:5f039cbddee8 485 void elasticLoop::setRegionMotion(float mmix, float mmiy, float mmax, float mmay) { // Attention: the initial position should be INSIDE this...
mbedalvaro 31:5f039cbddee8 486 /*
mbedalvaro 31:5f039cbddee8 487 for (int i = 0; i<numMasses; i++) {
mbedalvaro 31:5f039cbddee8 488 massesLoop[i].setWallLimits(mmix, mmiy, mmax, mmay);
mbedalvaro 31:5f039cbddee8 489 }
mbedalvaro 31:5f039cbddee8 490 anchorMass.setWallLimits(mmix+10, mmiy+10, mmax-10, mmay-10);
mbedalvaro 31:5f039cbddee8 491 */
mbedalvaro 31:5f039cbddee8 492
mbedalvaro 31:5f039cbddee8 493 // Use the static method of the class pointMass:
mbedalvaro 31:5f039cbddee8 494 // pointMass::setWallLimits(mmix+10, mmiy+10, mmax-10, mmay-10);
mbedalvaro 31:5f039cbddee8 495 pointMass::setWallLimits(mmix+10, mmiy+10, mmax-10, mmay-10);
mbedalvaro 31:5f039cbddee8 496 }
mbedalvaro 31:5f039cbddee8 497
mbedalvaro 31:5f039cbddee8 498 void elasticLoop::update(vector2Df referencePos) {
mbedalvaro 31:5f039cbddee8 499
mbedalvaro 31:5f039cbddee8 500 // (I) Process loop geometry (compute "hair vectors", area and first order moment):
mbedalvaro 31:5f039cbddee8 501 processLoopData();
mbedalvaro 31:5f039cbddee8 502
mbedalvaro 31:5f039cbddee8 503 // (II) Process sensing buffer and compute light forces
mbedalvaro 31:5f039cbddee8 504 displaySensingBuffer.processSensedData();
mbedalvaro 31:5f039cbddee8 505
mbedalvaro 31:5f039cbddee8 506 // (III) Reset all forces:
mbedalvaro 31:5f039cbddee8 507 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 508 massesLoop[i].resetForce();
mbedalvaro 31:5f039cbddee8 509 }
mbedalvaro 31:5f039cbddee8 510 anchorMass.resetForce();
mbedalvaro 31:5f039cbddee8 511
mbedalvaro 31:5f039cbddee8 512 // (IV) COMPUTE FORCES (motion is not update yet):
mbedalvaro 31:5f039cbddee8 513 //== (1) Compute each particle light force as well as total light force (this will be stored separatedly from the final total particle force to send to OSC):
mbedalvaro 31:5f039cbddee8 514 totalLightForce.set(0,0);
mbedalvaro 31:5f039cbddee8 515 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 516 // NOTE: to save memory, we can drop hairVector...
mbedalvaro 31:5f039cbddee8 517 lightForce[i]=hairVector[i]*factorLightForce*displaySensingBuffer.lsdTrajectory[i].lightZone;
mbedalvaro 31:5f039cbddee8 518 // lightForce[i]=lightForce[i]*factorLightForce*displaySensingBuffer.lsdTrajectory[i].lightZone;
mbedalvaro 31:5f039cbddee8 519 //compute total light force, not only on lighted zones, because it will mean AWAY from black zones:
mbedalvaro 31:5f039cbddee8 520 totalLightForce+=lightForce[i]; // note: bad value choice (negative means TOUCH, and equal to -1), TO CHANGE this in future implementations
mbedalvaro 31:5f039cbddee8 521 }
mbedalvaro 31:5f039cbddee8 522 //== (2) Compute the "recentering vector" from the total light force, by rotating by the angleCorrection (this will give different behaviours):
mbedalvaro 40:ee217eff826c 523 recenteringVectorLoop= totalLightForce.getRotatedDeg(slidingDirection? -110 : 110); // the hard coded value is a hack for the time being...
mbedalvaro 31:5f039cbddee8 524 // Compute redundant quantities:
mbedalvaro 31:5f039cbddee8 525 normRecenteringVector=recenteringVectorLoop.length();
mbedalvaro 31:5f039cbddee8 526 angleRecenteringVector=recenteringVectorLoop.angleDegHoriz();
mbedalvaro 31:5f039cbddee8 527 recenteringVectorNucleus=totalLightForce.getRotatedDeg(angleCorrectionForceNucleus);
mbedalvaro 31:5f039cbddee8 528 //== (3) Compute forces on the loop:
mbedalvaro 31:5f039cbddee8 529 //----(a) Nearest neighbour inter-particle springs on the loop (always? we can have still another mode, following the center mass only, etc...)
mbedalvaro 31:5f039cbddee8 530 if (springForcesOnLoop) {
mbedalvaro 31:5f039cbddee8 531 for (int i = 0; i < numMasses; i++) { // if putting -1, the loop is broken
mbedalvaro 31:5f039cbddee8 532 loopSpringArray[i].update();// this add forces to the particles
mbedalvaro 31:5f039cbddee8 533 }
mbedalvaro 31:5f039cbddee8 534 }
mbedalvaro 31:5f039cbddee8 535 //----(b) Direct forces from light pressure (COULD BE MERGED WITH FORCE RECENTERING!!)
mbedalvaro 31:5f039cbddee8 536 if (pseudopodesMode) {
mbedalvaro 31:5f039cbddee8 537 // special "patches" on blob membrane:
mbedalvaro 31:5f039cbddee8 538 if (lightForcesOnLoop) {
mbedalvaro 31:5f039cbddee8 539 int sign=1;
mbedalvaro 31:5f039cbddee8 540 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 541 if ((i%2)==0) sign*=-1;
mbedalvaro 31:5f039cbddee8 542 if (displaySensingBuffer.lsdTrajectory[i].lightZone>0) // this means touching something black: make SOME points attracted by it (pseudopodes!!) - but not all!
mbedalvaro 40:ee217eff826c 543 massesLoop[i].addForce(lightForce[i]*(sign<0? -1.8 : 1.8)); // sign<0 means this is a pseudopode attracted by dark zones
mbedalvaro 31:5f039cbddee8 544 else // this means something white: do nothing, all forces are towards the exterior
mbedalvaro 40:ee217eff826c 545 massesLoop[i].addForce(lightForce[i]*1.5); // this force tends to make the blob "inflate", but is not "directional"
mbedalvaro 31:5f039cbddee8 546 }
mbedalvaro 31:5f039cbddee8 547 }
mbedalvaro 31:5f039cbddee8 548 //----(c) Forces from the recentering vector on each particle (WITH PATCHES on the loop?):
mbedalvaro 31:5f039cbddee8 549 if (recenteringForceOnLoop) {
mbedalvaro 31:5f039cbddee8 550
mbedalvaro 40:ee217eff826c 551 vector2Df auxForce= recenteringVectorLoop*factorRecenteringLoopMass*1.6;
mbedalvaro 40:ee217eff826c 552 //vector2Df auxForce2= (slidingDirection? totalLightForce.getRotatedDeg(-90) : totalLightForce.getRotatedDeg(90))*factorRecenteringLoopMass*1.5;
mbedalvaro 40:ee217eff826c 553 //vector2Df auxForce3= (slidingDirection? totalLightForce.getRotatedDeg(-90) : totalLightForce.getRotatedDeg(90))*factorRecenteringLoopMass*1.5;
mbedalvaro 40:ee217eff826c 554 vector2Df auxForce2= (slidingDirection? totalLightForce.getRotatedDeg(90) : totalLightForce.getRotatedDeg(-90))*factorRecenteringLoopMass*1.1;
mbedalvaro 40:ee217eff826c 555 vector2Df auxForce3= (slidingDirection? totalLightForce.getRotatedDeg(90) : totalLightForce.getRotatedDeg(-90))*factorRecenteringLoopMass*1.1;
mbedalvaro 40:ee217eff826c 556
mbedalvaro 31:5f039cbddee8 557 int sign=1;
mbedalvaro 31:5f039cbddee8 558 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 559 if ((i%2)==0) sign*=-1;
mbedalvaro 31:5f039cbddee8 560 if (displaySensingBuffer.lsdTrajectory[i].lightZone>0) {// this means touching something black: behaviour may depend on the pseudopode presence:
mbedalvaro 40:ee217eff826c 561 massesLoop[i].addForce((sign<0? auxForce2 : auxForce3)); // nothing, or sign, or corrected angle
mbedalvaro 31:5f039cbddee8 562 } else
mbedalvaro 31:5f039cbddee8 563 massesLoop[i].addForce(auxForce); // this force is responsible for the behaviour (contour following or not)
mbedalvaro 31:5f039cbddee8 564 }
mbedalvaro 31:5f039cbddee8 565 }
mbedalvaro 31:5f039cbddee8 566 } else { // no special zones in the "cell membrane":
mbedalvaro 31:5f039cbddee8 567 if (lightForcesOnLoop) {
mbedalvaro 31:5f039cbddee8 568 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 569 massesLoop[i].addForce(lightForce[i]);
mbedalvaro 31:5f039cbddee8 570 }
mbedalvaro 31:5f039cbddee8 571 }
mbedalvaro 31:5f039cbddee8 572 //----(c') Forces from the recentering vector on each particle:
mbedalvaro 31:5f039cbddee8 573 if (recenteringForceOnLoop) {
mbedalvaro 31:5f039cbddee8 574 vector2Df auxForce= recenteringVectorLoop*factorRecenteringLoopMass;
mbedalvaro 31:5f039cbddee8 575 for (int i = 0; i < numMasses; i++) massesLoop[i].addForce(auxForce);
mbedalvaro 31:5f039cbddee8 576 }
mbedalvaro 31:5f039cbddee8 577 }
mbedalvaro 31:5f039cbddee8 578
mbedalvaro 31:5f039cbddee8 579 //----(d) Forces from the anchorMass (depending on how we set the equilibrium position for each central spring, we can have a nice blob shape at equilibrium... like a gear for instance)
mbedalvaro 31:5f039cbddee8 580 if (nuclearForceOnLoop) {
mbedalvaro 31:5f039cbddee8 581 // Springs:
mbedalvaro 31:5f039cbddee8 582 for (int i = 0; i < numMasses; i++) centralSpringArray[i].update();//assymetricUpdate();
mbedalvaro 31:5f039cbddee8 583 // note: if using centralSpringArray[i].update(), we will add forces to the particles AND to the anchor mass...
mbedalvaro 31:5f039cbddee8 584 // Inverse square (attractive):
mbedalvaro 31:5f039cbddee8 585 //for (int i = 0; i < numMasses; i++) massesLoop[i].addInterInvSquareForce(anchorMass, 10, 300, centralSpringK);
mbedalvaro 31:5f039cbddee8 586 }
mbedalvaro 31:5f039cbddee8 587 //----(d) Inter loop-particles forces (Zach-Liebermann-like blob):
mbedalvaro 31:5f039cbddee8 588 if (interParticleForceOnLoop) {
mbedalvaro 31:5f039cbddee8 589 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 590 for (int j = 0; j < i-1; j++) massesLoop[i].addInterSpringForce(massesLoop[j], interParticleRange, factorInterParticleForce);
mbedalvaro 31:5f039cbddee8 591 }
mbedalvaro 31:5f039cbddee8 592 }
mbedalvaro 31:5f039cbddee8 593 //----(e) Internal blob pressure force (my faster method to have a blob-like behaviour):
mbedalvaro 31:5f039cbddee8 594 if (forceInternalPressureOnLoop) {
mbedalvaro 31:5f039cbddee8 595 // NOTE on the Physics of the thing: the force on the membrane of a ballon is proportional to the DIFFERENCE of pressures (outside and inside):
mbedalvaro 31:5f039cbddee8 596 // so: f= factor/area - cte, with cte=factor/area0, with area0 being the area at equilibrium.
mbedalvaro 31:5f039cbddee8 597 // (And of course, to make it even more exact, we should do pressure*surface, but this will be considered constant)
mbedalvaro 31:5f039cbddee8 598 // float area0=30000; // area in pixels when at equilibrium
mbedalvaro 31:5f039cbddee8 599 //float factorPressureLoopMass=-0.1*(1.0/area-1.0/area0);
mbedalvaro 31:5f039cbddee8 600 //float factorPressureLoopMass=500000.0*(1.0/(area*area)-1.0/(area0*area0));
mbedalvaro 31:5f039cbddee8 601 //float factorPressureLoopMass=20000.0*(1.0/sqrt(area)-1.0/sqrt(area0));
mbedalvaro 31:5f039cbddee8 602 // Constant force seems to work well too... but produces an annoying blob reversal (probably solved by using negative light forces instead of internal blob pressure):
mbedalvaro 31:5f039cbddee8 603 //float factorPressureLoopMass=2.5;//4.8;
mbedalvaro 31:5f039cbddee8 604 // Now, add the pressure force proportional to the inverse of the area to all particles, or just a signed constant:
mbedalvaro 31:5f039cbddee8 605 int auxsign=(area>=0? -1: 1);
mbedalvaro 31:5f039cbddee8 606 auxsign=-1;
mbedalvaro 31:5f039cbddee8 607 for (int i = 0; i < numMasses; i++) massesLoop[i].addForce( hairVector[i] * factorPressureLoopMass* auxsign);
mbedalvaro 31:5f039cbddee8 608 }
mbedalvaro 31:5f039cbddee8 609 //----(f) force from border:
mbedalvaro 31:5f039cbddee8 610 if (forceBorderOnLoop) {
mbedalvaro 31:5f039cbddee8 611 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 612 if (massesLoop[i].bWallCollision) massesLoop[i].addForce(massesLoop[i].innerCollitionDirection*factorForceBorder);
mbedalvaro 31:5f039cbddee8 613 }
mbedalvaro 31:5f039cbddee8 614 }
mbedalvaro 31:5f039cbddee8 615
mbedalvaro 31:5f039cbddee8 616 //== (4) Compute forces on the anchor mass:
mbedalvaro 31:5f039cbddee8 617 //----(a) Force from data send by OSC? (ex: from mouse?)
mbedalvaro 31:5f039cbddee8 618 // anchorMass.addSpringForce(mx, my, 500, -10.2f);
mbedalvaro 31:5f039cbddee8 619 // or direct control:
mbedalvaro 31:5f039cbddee8 620 // anchorMass.pos.x=mx;anchorMass.pos.y=my;
mbedalvaro 31:5f039cbddee8 621 //----(b) Force from the total light force (aka, the "recentering vector"!):
mbedalvaro 31:5f039cbddee8 622 if (recenteringForceOnNucleus) {
mbedalvaro 31:5f039cbddee8 623 anchorMass.addForce(recenteringVectorNucleus*factorRecenteringAnchorMass);
mbedalvaro 31:5f039cbddee8 624 }
mbedalvaro 31:5f039cbddee8 625
mbedalvaro 31:5f039cbddee8 626 // when nothing is touching it for a while:
mbedalvaro 31:5f039cbddee8 627 if (searchActive) {
mbedalvaro 31:5f039cbddee8 628 if (!displaySensingBuffer.lightTouched) {
mbedalvaro 31:5f039cbddee8 629 if (firstTimeNoTouch) {
mbedalvaro 31:5f039cbddee8 630 firstTimeNoTouch=false;
mbedalvaro 31:5f039cbddee8 631 computeBoundingBox();
mbedalvaro 31:5f039cbddee8 632 randomForce.set(2000-cx,2000-cy);
mbedalvaro 31:5f039cbddee8 633 randomForce.normalize();
mbedalvaro 31:5f039cbddee8 634 randomForce= randomForce.getRotatedDeg(rand()%50-25);
mbedalvaro 31:5f039cbddee8 635 }
mbedalvaro 31:5f039cbddee8 636 if (noTouchedCounter>0) {
mbedalvaro 31:5f039cbddee8 637 // add random force, modulated:
mbedalvaro 31:5f039cbddee8 638 float aux=1.0*noTouchedCounter/1150;
mbedalvaro 31:5f039cbddee8 639 vector2Df randf=randomForce.getRotatedDeg(40.0*sin(aux*2*PI*2))*20.0;//*(1.0-aux)*0.3;
mbedalvaro 31:5f039cbddee8 640 for (int i = 0; i < 1; i=i+1) { // only on some of the particles, and better if these are in the "black attractive" patch!
mbedalvaro 31:5f039cbddee8 641 massesLoop[i].addForce(randf);
mbedalvaro 31:5f039cbddee8 642 }
mbedalvaro 31:5f039cbddee8 643 // and a special point?
mbedalvaro 31:5f039cbddee8 644 //massesLoop[numMasses/2].addForce(randf);
mbedalvaro 31:5f039cbddee8 645 // plus amoeba effect ?
mbedalvaro 31:5f039cbddee8 646 // for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 647 // massesLoop[i].addForce(hairVector[i]*18*cos( (0.0*noTouchedCounter/1000 + 1.0*i/(numMasses-1)*2*PI*3)));
mbedalvaro 31:5f039cbddee8 648 //}
mbedalvaro 31:5f039cbddee8 649
mbedalvaro 31:5f039cbddee8 650 if ((noTouchedCounter>1150)||(blobWallCollision)) {
mbedalvaro 31:5f039cbddee8 651 noTouchedCounter=0;
mbedalvaro 31:5f039cbddee8 652 // compute force towards the center, slightly rotated to make the blob wander about:
mbedalvaro 31:5f039cbddee8 653 computeBoundingBox();
mbedalvaro 31:5f039cbddee8 654 randomForce.set(2000-cx,2000-cy);
mbedalvaro 31:5f039cbddee8 655 randomForce.normalize();
mbedalvaro 31:5f039cbddee8 656 randomForce= randomForce.getRotatedDeg(rand()%50-25);
mbedalvaro 31:5f039cbddee8 657 }
mbedalvaro 31:5f039cbddee8 658 }
mbedalvaro 31:5f039cbddee8 659 } else {
mbedalvaro 31:5f039cbddee8 660 firstTimeNoTouch=true;
mbedalvaro 31:5f039cbddee8 661 noTouchedCounter=0;
mbedalvaro 31:5f039cbddee8 662 }
mbedalvaro 31:5f039cbddee8 663 noTouchedCounter++;
mbedalvaro 31:5f039cbddee8 664 }
mbedalvaro 31:5f039cbddee8 665
mbedalvaro 31:5f039cbddee8 666 // (V) UPDATE DYNAMICS
mbedalvaro 31:5f039cbddee8 667 //== (1) particules on the loop:
mbedalvaro 31:5f039cbddee8 668 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 669 #ifndef VERLET_METHOD
mbedalvaro 31:5f039cbddee8 670 massesLoop[i].addDampingForce(); // only in case of EULER method (damping in VERLET mode is done automatically when updating)
mbedalvaro 31:5f039cbddee8 671 #endif
mbedalvaro 31:5f039cbddee8 672 massesLoop[i].update(); // unconstrained
mbedalvaro 31:5f039cbddee8 673 massesLoop[i].bounceOffWalls(); // constrain position (and compute wall "hit")
mbedalvaro 31:5f039cbddee8 674 }
mbedalvaro 31:5f039cbddee8 675 //== (2) For the anchorMass:
mbedalvaro 31:5f039cbddee8 676 #ifndef VERLET_METHOD
mbedalvaro 31:5f039cbddee8 677 anchorMass.addDampingForce(); // // only in case of EULER method (damping in VERLET mode is done automatically when updating)
mbedalvaro 31:5f039cbddee8 678 #endif
mbedalvaro 31:5f039cbddee8 679 anchorMass.update(); // unconstrained
mbedalvaro 31:5f039cbddee8 680 anchorMass.bounceOffWalls(); // constrain position (and compute wall "hit")
mbedalvaro 31:5f039cbddee8 681
mbedalvaro 31:5f039cbddee8 682 // OTHER PARTICULAR THINGS:
mbedalvaro 31:5f039cbddee8 683 // (1) current color: change with touch? NO
mbedalvaro 31:5f039cbddee8 684 // if (displaySensingBuffer.lightTouched)
mbedalvaro 31:5f039cbddee8 685 // transientBlobColor=blobColor|0x02; // set green ON on the trajectory, regardless of the initial color
mbedalvaro 31:5f039cbddee8 686 // else
mbedalvaro 31:5f039cbddee8 687 transientBlobColor=blobColor; // just the original blob color
mbedalvaro 31:5f039cbddee8 688
mbedalvaro 31:5f039cbddee8 689 // change sliding direction (for countour following):
mbedalvaro 31:5f039cbddee8 690 if (blobWallCollision) {
mbedalvaro 31:5f039cbddee8 691 if (wallCounter>10) {
mbedalvaro 31:5f039cbddee8 692 slidingDirection=!slidingDirection;
mbedalvaro 31:5f039cbddee8 693 wallCounter=0;
mbedalvaro 31:5f039cbddee8 694 }
mbedalvaro 31:5f039cbddee8 695 }
mbedalvaro 31:5f039cbddee8 696 wallCounter++;
mbedalvaro 31:5f039cbddee8 697 }
mbedalvaro 31:5f039cbddee8 698
mbedalvaro 31:5f039cbddee8 699 // Drawing the graphics - this will in fact use the graphic renderer - if any - and produce the trajectory to be displayed by the laser
mbedalvaro 31:5f039cbddee8 700 void elasticLoop::draw() {
mbedalvaro 31:5f039cbddee8 701 // for the time being, there is no "opengl" like renderer, so we just copy the coordinates of the mass into the lsdTrajectory:
mbedalvaro 31:5f039cbddee8 702 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 703 displaySensingBuffer.lsdTrajectory[i].x= (unsigned short)( massesLoop[i].pos.x ); // note: it should be an unsigned short
mbedalvaro 31:5f039cbddee8 704 displaySensingBuffer.lsdTrajectory[i].y= (unsigned short)( massesLoop[i].pos.y );
mbedalvaro 31:5f039cbddee8 705
mbedalvaro 31:5f039cbddee8 706 //displaySensingBuffer.lsdTrajectory[i]= massesLoop[i].pos.y; // NOTE: doing this means converting from unsigned short to float (vector2Dd to vector2Df)
mbedalvaro 31:5f039cbddee8 707
mbedalvaro 31:5f039cbddee8 708 //displaySensingBuffer.lsdTrajectory[i].color=blobColor; // perhaps per point color is not a good idea for the time being...
mbedalvaro 31:5f039cbddee8 709 }
mbedalvaro 31:5f039cbddee8 710
mbedalvaro 31:5f039cbddee8 711 // Global color for the whole loop:
mbedalvaro 31:5f039cbddee8 712 displaySensingBuffer.displayColor=transientBlobColor;
mbedalvaro 31:5f039cbddee8 713 }
mbedalvaro 31:5f039cbddee8 714
mbedalvaro 31:5f039cbddee8 715 void elasticLoop::processLoopData() {
mbedalvaro 31:5f039cbddee8 716
mbedalvaro 31:5f039cbddee8 717 // (0) Check if the blob touched the borders:
mbedalvaro 31:5f039cbddee8 718 blobWallCollision=false;
mbedalvaro 31:5f039cbddee8 719 for (int i = 0; i < numMasses; i++) blobWallCollision= (blobWallCollision || massesLoop[i].bWallCollision);
mbedalvaro 31:5f039cbddee8 720
mbedalvaro 31:5f039cbddee8 721 // (1) Compute all the "hairvectors" for the loop (this is, the normals to the particles, pointing outwards).
mbedalvaro 31:5f039cbddee8 722 // This will be approximated by taking the 90 deg rotated difference between contiguous particles positions.
mbedalvaro 31:5f039cbddee8 723 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 724 vector2Df diff;
mbedalvaro 31:5f039cbddee8 725 diff.set(massesLoop[(i+1)%numMasses].pos-massesLoop[i].pos);
mbedalvaro 31:5f039cbddee8 726 // normalize and rotate 90 deg:
mbedalvaro 31:5f039cbddee8 727 // NOTE: to save memory, we can drop hairVector...
mbedalvaro 31:5f039cbddee8 728 hairVector[i]=diff.getPerpendicularNormed(CW);
mbedalvaro 31:5f039cbddee8 729 //lightForce[i]=diff.getPerpendicularNormed(CW);
mbedalvaro 31:5f039cbddee8 730 }
mbedalvaro 31:5f039cbddee8 731
mbedalvaro 31:5f039cbddee8 732 // (2) Compute area:
mbedalvaro 31:5f039cbddee8 733 // (a) using Green method:
mbedalvaro 31:5f039cbddee8 734 area=0;
mbedalvaro 31:5f039cbddee8 735 float dx;
mbedalvaro 31:5f039cbddee8 736 for (int i = 0; i < numMasses-1; i++){
mbedalvaro 31:5f039cbddee8 737 dx=massesLoop[i].pos.x-massesLoop[i+1].pos.x;
mbedalvaro 31:5f039cbddee8 738 area+=dx*massesLoop[i].pos.y;
mbedalvaro 31:5f039cbddee8 739 }
mbedalvaro 31:5f039cbddee8 740 // to avoid computation problems:
mbedalvaro 31:5f039cbddee8 741 // if (area<=0) area=1; // or just norm: area CAN be negative! (a loop that is larger than the original blob...)
mbedalvaro 31:5f039cbddee8 742
mbedalvaro 31:5f039cbddee8 743 // (b) Compute approximate area from enclosing rectangle:
mbedalvaro 31:5f039cbddee8 744 computeBoundingBox();
mbedalvaro 31:5f039cbddee8 745
mbedalvaro 31:5f039cbddee8 746 // (c) Compute kinetic energy:
mbedalvaro 31:5f039cbddee8 747 totalKineticEnergy=0;
mbedalvaro 31:5f039cbddee8 748 for (int i = 0; i < numMasses; i++){
mbedalvaro 31:5f039cbddee8 749 totalKineticEnergy+=massesLoop[i].getSpeed().squareLength();
mbedalvaro 31:5f039cbddee8 750 }
mbedalvaro 31:5f039cbddee8 751 }
mbedalvaro 31:5f039cbddee8 752
mbedalvaro 31:5f039cbddee8 753
mbedalvaro 31:5f039cbddee8 754 void elasticLoop::computeBoundingBox() {
mbedalvaro 31:5f039cbddee8 755 float minx=4096, maxx=-1, miny=4096, maxy=-1;
mbedalvaro 31:5f039cbddee8 756 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 757 if (i == 0) {
mbedalvaro 31:5f039cbddee8 758 minx = massesLoop[i].pos.x;
mbedalvaro 31:5f039cbddee8 759 maxx = massesLoop[i].pos.x;
mbedalvaro 31:5f039cbddee8 760 miny = massesLoop[i].pos.y;
mbedalvaro 31:5f039cbddee8 761 maxy = massesLoop[i].pos.y;
mbedalvaro 31:5f039cbddee8 762 } else {
mbedalvaro 31:5f039cbddee8 763
mbedalvaro 31:5f039cbddee8 764 minx = min(minx, massesLoop[i].pos.x);
mbedalvaro 31:5f039cbddee8 765 maxx = max(maxx, massesLoop[i].pos.x);
mbedalvaro 31:5f039cbddee8 766 miny = min(miny, massesLoop[i].pos.y);
mbedalvaro 31:5f039cbddee8 767 maxy = max(maxy, massesLoop[i].pos.y);
mbedalvaro 31:5f039cbddee8 768 }
mbedalvaro 31:5f039cbddee8 769 }
mbedalvaro 31:5f039cbddee8 770
mbedalvaro 31:5f039cbddee8 771 // final results:
mbedalvaro 31:5f039cbddee8 772 w = maxx - minx;
mbedalvaro 31:5f039cbddee8 773 h = maxy - miny;
mbedalvaro 31:5f039cbddee8 774 cx = minx+0.5*w; // note: center will be initialized with posX and posY when calling setInitialPos() of blobConfig
mbedalvaro 31:5f039cbddee8 775 cy = miny+0.5*h;
mbedalvaro 31:5f039cbddee8 776
mbedalvaro 31:5f039cbddee8 777 // approx area:
mbedalvaro 31:5f039cbddee8 778 approxArea=w*h;
mbedalvaro 31:5f039cbddee8 779 }
mbedalvaro 31:5f039cbddee8 780
mbedalvaro 31:5f039cbddee8 781 void elasticLoop::sendDataSpecific() {
mbedalvaro 31:5f039cbddee8 782 char auxstring[10];
mbedalvaro 31:5f039cbddee8 783 myled2=1; // for tests...
mbedalvaro 31:5f039cbddee8 784
mbedalvaro 31:5f039cbddee8 785 // First, set the top address of the message to the ID of the blob (not the name):
mbedalvaro 31:5f039cbddee8 786 // sprintf(auxstring, "%d", identifier);
mbedalvaro 31:5f039cbddee8 787 // sendMes.setTopAddress("0");//auxstring);
mbedalvaro 31:5f039cbddee8 788
mbedalvaro 31:5f039cbddee8 789 // ===================== OSC ======================
mbedalvaro 31:5f039cbddee8 790 if (sendOSC) {
mbedalvaro 31:5f039cbddee8 791
mbedalvaro 31:5f039cbddee8 792 // (new) Total kinetic energy:
mbedalvaro 31:5f039cbddee8 793 if (sendingKineticEnergy) {
mbedalvaro 31:5f039cbddee8 794 sprintf(auxstring, "/k %d",identifier);
mbedalvaro 31:5f039cbddee8 795 sendMes.setSubAddress(auxstring);
mbedalvaro 31:5f039cbddee8 796 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 797 x=(long)(totalKineticEnergy);
mbedalvaro 31:5f039cbddee8 798 sendMes.setArgs( "i", &x);
mbedalvaro 31:5f039cbddee8 799 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 800 }
mbedalvaro 31:5f039cbddee8 801 // (a) Anchor mass:
mbedalvaro 31:5f039cbddee8 802 if (sendingAnchorPosition) {
mbedalvaro 31:5f039cbddee8 803 sprintf(auxstring, "/p %d",identifier);
mbedalvaro 31:5f039cbddee8 804 sendMes.setSubAddress(auxstring);
mbedalvaro 31:5f039cbddee8 805 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 806 x=(long)(anchorMass.pos.x);
mbedalvaro 31:5f039cbddee8 807 y=(long)(anchorMass.pos.y);
mbedalvaro 31:5f039cbddee8 808 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 31:5f039cbddee8 809 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 810 }
mbedalvaro 31:5f039cbddee8 811 if (sendingAnchorForce) {
mbedalvaro 31:5f039cbddee8 812 sendMes.setSubAddress("/aforce");
mbedalvaro 31:5f039cbddee8 813 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 814 x=(long)(anchorMass.totalForce.x);
mbedalvaro 31:5f039cbddee8 815 y=(long)(anchorMass.totalForce.y);
mbedalvaro 31:5f039cbddee8 816 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 31:5f039cbddee8 817 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 818 }
mbedalvaro 31:5f039cbddee8 819 if (sendingAnchorTouchWall) {// note: not an else (we can send different data simultaneously)
mbedalvaro 31:5f039cbddee8 820 sendMes.setSubAddress("/awall");
mbedalvaro 31:5f039cbddee8 821 long wall=(long)(anchorMass.bWallCollision? 1 : 0);
mbedalvaro 31:5f039cbddee8 822 sendMes.setArgs( "i", &wall);
mbedalvaro 31:5f039cbddee8 823 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 824 }
mbedalvaro 31:5f039cbddee8 825 // (b) data from blob points:
mbedalvaro 31:5f039cbddee8 826 if (sendingLoopPositions) {
mbedalvaro 31:5f039cbddee8 827 #ifdef SEND_AS_POINTS
mbedalvaro 31:5f039cbddee8 828 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 829 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 830 sprintf(auxstring, "/p %d", i); // auxstring read as "/p1", "/p2", ...
mbedalvaro 31:5f039cbddee8 831 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 31:5f039cbddee8 832 x=(long)(massesLoop[i].pos.x);
mbedalvaro 31:5f039cbddee8 833 y=(long)(massesLoop[i].pos.y);
mbedalvaro 31:5f039cbddee8 834 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 31:5f039cbddee8 835 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 836 }
mbedalvaro 31:5f039cbddee8 837 #endif
mbedalvaro 31:5f039cbddee8 838 #ifdef SEND_AS_BLOB
mbedalvaro 31:5f039cbddee8 839 sendMes.clearArgs(); // no need, we won't use osc.sendOsc()...
mbedalvaro 31:5f039cbddee8 840 uint8_t blobdata[4*numMasses]; // 2 bytes per coordinate, and 2 coordinates
mbedalvaro 31:5f039cbddee8 841 for (int i = 0; i < numMasses; i++ ) {
mbedalvaro 31:5f039cbddee8 842 // note: massesLoop[i].pos.x is a "float"
mbedalvaro 31:5f039cbddee8 843 uint16_t x=(uint16_t)(massesLoop[i].pos.x);
mbedalvaro 31:5f039cbddee8 844 blobdata[4*i]=(uint8_t)x>>8; // BIG ENDIAN (send FIRST the MOST SIGNIFICANT BYTE)
mbedalvaro 31:5f039cbddee8 845 blobdata[4*i+1]=(uint8_t)x;
mbedalvaro 31:5f039cbddee8 846
mbedalvaro 31:5f039cbddee8 847 uint16_t y=(uint16_t)(massesLoop[i].pos.y);
mbedalvaro 31:5f039cbddee8 848 blobdata[4*i+2]=(uint8_t)y>>8; // BIG ENDIAN (send FIRST the MOST SIGNIFICANT BYTE)
mbedalvaro 31:5f039cbddee8 849 blobdata[4*i+3]=(uint8_t)y;
mbedalvaro 31:5f039cbddee8 850 }
mbedalvaro 31:5f039cbddee8 851 osc.sendOscBlob(&(blobdata[0]), 4*numMasses, &sendMes ); // second parameter is osc blob size in bytes
mbedalvaro 31:5f039cbddee8 852 #endif
mbedalvaro 31:5f039cbddee8 853 #ifdef SEND_AS_STRING
mbedalvaro 31:5f039cbddee8 854 sendMes.clearArgs(); // no need, we won't use osc.sendOsc()...
mbedalvaro 31:5f039cbddee8 855 uint8_t blobdata[4*numMasses]; // 2 bytes per coordinate, and 2 coordinates
mbedalvaro 31:5f039cbddee8 856 for (int i = 0; i < numMasses; i++ ) {
mbedalvaro 31:5f039cbddee8 857 // note: massesLoop[i].pos.x is a "float"
mbedalvaro 31:5f039cbddee8 858 uint16_t x=(uint16_t)(massesLoop[i].pos.x);
mbedalvaro 31:5f039cbddee8 859 blobdata[4*i]=(uint8_t)x>>8; // BIG ENDIAN (send FIRST the MOST SIGNIFICANT BYTE)
mbedalvaro 31:5f039cbddee8 860 blobdata[4*i+1]=(uint8_t)x;
mbedalvaro 31:5f039cbddee8 861
mbedalvaro 31:5f039cbddee8 862 uint16_t y=(uint16_t)(massesLoop[i].pos.y);
mbedalvaro 31:5f039cbddee8 863 blobdata[4*i+2]=(uint8_t)y>>8; // BIG ENDIAN (send FIRST the MOST SIGNIFICANT BYTE)
mbedalvaro 31:5f039cbddee8 864 blobdata[4*i+3]=(uint8_t)y;
mbedalvaro 31:5f039cbddee8 865 }
mbedalvaro 31:5f039cbddee8 866 osc.sendOscString(blobdata, 4*numMasses, &sendMes ); // second parameter is osc blob size in bytes
mbedalvaro 31:5f039cbddee8 867 #endif
mbedalvaro 31:5f039cbddee8 868 }
mbedalvaro 31:5f039cbddee8 869 if (sendingLoopForces) { // ATTN: the force is the TOTAL force on the point (interesting perhaps for making sound...)
mbedalvaro 31:5f039cbddee8 870 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 871 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 872 sprintf(auxstring, "/f%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 31:5f039cbddee8 873 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 31:5f039cbddee8 874 x=(long)(massesLoop[i].totalForce.x);
mbedalvaro 31:5f039cbddee8 875 y=(long)(massesLoop[i].totalForce.y);
mbedalvaro 31:5f039cbddee8 876 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 31:5f039cbddee8 877 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 878 }
mbedalvaro 31:5f039cbddee8 879 }
mbedalvaro 31:5f039cbddee8 880 if (sendingLoopForcesLight) { // ATTN: the force is the TOTAL force on the point (interesting perhaps for making sound...)
mbedalvaro 31:5f039cbddee8 881 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 882 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 883 sprintf(auxstring, "/g%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 31:5f039cbddee8 884 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 31:5f039cbddee8 885 x=(long)(1000*lightForce[i].x);
mbedalvaro 31:5f039cbddee8 886 y=(long)(1000*lightForce[i].y);
mbedalvaro 31:5f039cbddee8 887 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 31:5f039cbddee8 888 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 889 }
mbedalvaro 31:5f039cbddee8 890 }
mbedalvaro 31:5f039cbddee8 891
mbedalvaro 31:5f039cbddee8 892 if (sendingLoopRegions) {
mbedalvaro 31:5f039cbddee8 893 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 894 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 895 sprintf(auxstring, "/r%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 31:5f039cbddee8 896 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 31:5f039cbddee8 897 x=(long)(displaySensingBuffer.lsdTrajectory[i].lightZone>0? 1 : 0);
mbedalvaro 31:5f039cbddee8 898 sendMes.setArgs( "i", &x);
mbedalvaro 31:5f039cbddee8 899 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 900 }
mbedalvaro 31:5f039cbddee8 901 }
mbedalvaro 31:5f039cbddee8 902 if (sendingLoopTouchWall) { // global touch wall for the loop (not per point)
mbedalvaro 31:5f039cbddee8 903 long wall; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 904 sprintf(auxstring, "/bWall");
mbedalvaro 31:5f039cbddee8 905 sendMes.setSubAddress(auxstring);
mbedalvaro 31:5f039cbddee8 906 wall=(long)(blobWallCollision? 1 : 0);
mbedalvaro 31:5f039cbddee8 907 sendMes.setArgs( "i", &wall);
mbedalvaro 31:5f039cbddee8 908 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 909 }
mbedalvaro 31:5f039cbddee8 910 // (c) Blob geometry:
mbedalvaro 31:5f039cbddee8 911 if (sendingBlobArea) {
mbedalvaro 31:5f039cbddee8 912 /* sendMes.setSubAddress("/a");
mbedalvaro 31:5f039cbddee8 913 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 914 // x=(long)(area);//approxArea); // area or approxArea
mbedalvaro 31:5f039cbddee8 915 x=(long)(area>0? approxArea : -approxArea);
mbedalvaro 31:5f039cbddee8 916 sendMes.setArgs( "i", &x); // ATTENTION: AREA CAN BE NEGATIVE!!! (does MAX handles this well? test this!)
mbedalvaro 31:5f039cbddee8 917 */
mbedalvaro 31:5f039cbddee8 918 // HACK for the time being (for Daito):
mbedalvaro 31:5f039cbddee8 919 sendMes.setSubAddress("/a");
mbedalvaro 31:5f039cbddee8 920 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 921 // x=(long)(area);//approxArea); // area or approxArea
mbedalvaro 31:5f039cbddee8 922 x=(long)(w); y=(long)(h);
mbedalvaro 31:5f039cbddee8 923 sendMes.setArgs( "ii", &x, &y); // ATTENTION: AREA CAN BE NEGATIVE!!! (does MAX handles this well? test this!)
mbedalvaro 31:5f039cbddee8 924
mbedalvaro 31:5f039cbddee8 925 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 926 }
mbedalvaro 31:5f039cbddee8 927 if (sendingBlobNormals) {
mbedalvaro 31:5f039cbddee8 928 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 929 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 930 sprintf(auxstring, "nf%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 31:5f039cbddee8 931 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 31:5f039cbddee8 932 x=(long)(hairVector[i].x);
mbedalvaro 31:5f039cbddee8 933 y=(long)(hairVector[i].y);
mbedalvaro 31:5f039cbddee8 934 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 31:5f039cbddee8 935 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 936 }
mbedalvaro 31:5f039cbddee8 937 }
mbedalvaro 31:5f039cbddee8 938 if (sendingBlobAngles) {
mbedalvaro 31:5f039cbddee8 939 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 940 for (int i = 0; i < numMasses; i++) {
mbedalvaro 31:5f039cbddee8 941 sprintf(auxstring, "/a%d", i); // auxstring read as "/f1", "/f2", ...
mbedalvaro 31:5f039cbddee8 942 sendMes.setSubAddress(auxstring); // ATTENTION: the host computer needs to know in advance how many points are in the loop (I did not implement "bundle" messages yet...)
mbedalvaro 31:5f039cbddee8 943 x=(long)(hairVector[i].angleDegHoriz());
mbedalvaro 31:5f039cbddee8 944 sendMes.setArgs( "i", &x);
mbedalvaro 31:5f039cbddee8 945 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 946 }
mbedalvaro 31:5f039cbddee8 947 }
mbedalvaro 31:5f039cbddee8 948 // (d) Light sensing statistics:
mbedalvaro 31:5f039cbddee8 949 if (sendingBlobMaxMin) {
mbedalvaro 31:5f039cbddee8 950 sendMes.setSubAddress("/maxmin");
mbedalvaro 31:5f039cbddee8 951 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 952 x=(long)(displaySensingBuffer.maxI);
mbedalvaro 31:5f039cbddee8 953 y=(long)(displaySensingBuffer.minI);
mbedalvaro 31:5f039cbddee8 954 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 31:5f039cbddee8 955 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 956 }
mbedalvaro 31:5f039cbddee8 957 if (sendingLightForce) {
mbedalvaro 31:5f039cbddee8 958 sendMes.setSubAddress("/lforce");
mbedalvaro 31:5f039cbddee8 959 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 960 x=(long)(totalLightForce.x);
mbedalvaro 31:5f039cbddee8 961 y=(long)(totalLightForce.y);
mbedalvaro 31:5f039cbddee8 962 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 31:5f039cbddee8 963 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 964 }
mbedalvaro 31:5f039cbddee8 965 // (e) Recentering vector: (note: redundant with sendingLightForce, IF the correction angle is known).
mbedalvaro 31:5f039cbddee8 966 if (sendingRecenteringVector) {
mbedalvaro 31:5f039cbddee8 967 sendMes.setSubAddress("/rvector");
mbedalvaro 31:5f039cbddee8 968 long x, y; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 969 x=(long)(recenteringVectorLoop.x);
mbedalvaro 31:5f039cbddee8 970 y=(long)(recenteringVectorLoop.y);
mbedalvaro 31:5f039cbddee8 971 sendMes.setArgs( "ii", &x, &y);
mbedalvaro 31:5f039cbddee8 972 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 973 }
mbedalvaro 31:5f039cbddee8 974 if (sendingRecenteringAngle) {
mbedalvaro 31:5f039cbddee8 975 sendMes.setSubAddress("/rangle");
mbedalvaro 31:5f039cbddee8 976 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 977 x=(long)(angleRecenteringVector);
mbedalvaro 31:5f039cbddee8 978 sendMes.setArgs( "i", &x);
mbedalvaro 31:5f039cbddee8 979 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 980 }
mbedalvaro 31:5f039cbddee8 981 if (sendingRecenteringNorm) {
mbedalvaro 31:5f039cbddee8 982 sendMes.setSubAddress("/rnorm");
mbedalvaro 31:5f039cbddee8 983 long x; //ATTENTION: parameters to setArgs should be long or unsigned long only (not int!!)
mbedalvaro 31:5f039cbddee8 984 x=(long)(normRecenteringVector);
mbedalvaro 31:5f039cbddee8 985 sendMes.setArgs( "i", &x);
mbedalvaro 31:5f039cbddee8 986 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 987 }
mbedalvaro 31:5f039cbddee8 988
mbedalvaro 31:5f039cbddee8 989 if (sendingTouched) {
mbedalvaro 31:5f039cbddee8 990 if (displaySensingBuffer.lightTouched) {
mbedalvaro 31:5f039cbddee8 991 sendMes.clearArgs(); // there are no arguments to send
mbedalvaro 31:5f039cbddee8 992 sendMes.setSubAddress("/touched");
mbedalvaro 31:5f039cbddee8 993 osc.sendOsc( &sendMes );
mbedalvaro 31:5f039cbddee8 994 }
mbedalvaro 31:5f039cbddee8 995 }
mbedalvaro 31:5f039cbddee8 996
mbedalvaro 31:5f039cbddee8 997 } // end of OSC sending per-spot
mbedalvaro 31:5f039cbddee8 998
mbedalvaro 31:5f039cbddee8 999 // ===================== SERIAL ======================
mbedalvaro 31:5f039cbddee8 1000 if (sendSerial) {
mbedalvaro 31:5f039cbddee8 1001 //.. to do
mbedalvaro 31:5f039cbddee8 1002 }
mbedalvaro 31:5f039cbddee8 1003
mbedalvaro 31:5f039cbddee8 1004 myled2=0; // for tests...
mbedalvaro 31:5f039cbddee8 1005 }
mbedalvaro 31:5f039cbddee8 1006