just a test

Dependencies:   mbed

Fork of scoreLight_Advanced by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Tue Apr 01 10:08:49 2014 +0000
Revision:
45:a3b984a79d5d
Parent:
44:46e25fa1669b
Child:
46:90516893793a
working on tracking mode;

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