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