annotate grid.cpp @ 49:178642d134a7 tip

xtra files
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Wed, 01 May 2013 17:34:33 +0100
parents 23efe1f0cd8a
children
rev   line source
rt300@0 1 //
rt300@0 2 // grid.cpp
rt300@0 3 // oscSenderExample
rt300@0 4 //
rt300@0 5 // Created by Robert Tubb on 03/10/2012.
rt300@0 6 //
rt300@0 7 //
rt300@0 8 #include "ofMain.h"
rt300@0 9 #include "grid.h"
rt300@1 10 #include "eventLogger.h"
rt300@0 11
rt300@0 12 #include <sstream>
rt300@0 13
rt300@0 14 //extern PresetManager presetManager;
rt300@1 15 extern EventLogger eventLogger;
rt300@0 16 //--------------------------------------------------------------
rt300@0 17 Grid::Grid(){
rt300@0 18
rt300@0 19 }
rt300@0 20 //--------------------------------------------------------------
rt300@0 21 //--------------------------------------------------------------
rt300@0 22 Grid::~Grid(){
rt300@0 23
rt300@0 24 }
rt300@0 25 void Grid::init(){
rt300@0 26 maxValue = pow(32.0,7.0)-1;
rt300@0 27 minValue = 60; // number of 1-size divisions at smallest scale
rt300@0 28 maxZoom = false;
rt300@0 29 minZoom = false;
rt300@0 30 paramsPerDim = 5;
rt300@0 31 paramBitDepth = 7;
rt300@0 32 codeLength = pow(2.0,paramsPerDim);
rt300@0 33
rt300@0 34 pixSize.setCoord(ofGetWidth(), ofGetHeight());
rt300@0 35
rt300@0 36 //set scale and position to mid way
rt300@0 37 scale = pow(32.0,6.0);
rt300@0 38
rt300@0 39
rt300@0 40 size.setCoord(pixSize.x*scale, pixSize.y*scale);
rt300@0 41 centre.setCoord(maxValue/2 , maxValue/2);
rt300@0 42 topLeft.setCoord(centre.x - size.x/2, centre.y - size.y/2);
rt300@0 43
rt300@0 44
rt300@0 45 makeCode();
rt300@0 46
rt300@0 47 // set a starting param value, find coord that does it.
rt300@0 48 vector<int> params(paramsPerDim*2);
rt300@0 49 for(int i = 0;i<2*paramsPerDim;i++){
rt300@0 50 midiCC[i] = 64;
rt300@0 51 params[i] = 64;
rt300@0 52 }
rt300@0 53 TwoVector coord = calculateCoordFromParams(params);
rt300@0 54 setCoord(coord);
rt300@0 55
rt300@0 56 viewWasChanged();
rt300@0 57
rt300@0 58
rt300@0 59
rt300@0 60 }
rt300@0 61
rt300@0 62 template <typename T> int sgn(T val) {
rt300@0 63 return (T(0) < val) - (val < T(0));
rt300@0 64 }
rt300@0 65
rt300@0 66 void Grid::makeCode(){
rt300@0 67
rt300@0 68 ////////////////////////////////~~~,,,,,,,,.........
rt300@0 69 ////////// gray code generation
rt300@0 70 //////
rt300@0 71 ///
rt300@0 72 // TODO 5bit specific
rt300@0 73 // transition sequence.... what a palaver! only need to do once though.
rt300@0 74 int trans[] = {0,1,2,3,0,4,2,1,0,3,2,1,0,4,2,3,0,1,2,3,0,4,2,1,0,3,2,1,0,4,2,3};
rt300@0 75
rt300@0 76
rt300@0 77 int code[codeLength][paramsPerDim]; // start with normal array
rt300@0 78
rt300@0 79
rt300@0 80
rt300@0 81 for(int j=0; j<paramsPerDim; j++){
rt300@0 82 code[0][j] = 0;
rt300@0 83 }
rt300@0 84
rt300@0 85 for(int i=0; i < codeLength-1; i++){ // TODO went off end??
rt300@0 86 transSeq.push_back(trans[i]); // member vector
rt300@0 87 for(int j=0; j<paramsPerDim; j++){
rt300@0 88
rt300@0 89 if (j == abs(trans[i])){
rt300@0 90 code[i+1][j] = !code[i][j];
rt300@0 91 }else{
rt300@0 92 code[i+1][j] = code[i][j];
rt300@0 93 }
rt300@0 94 }
rt300@0 95
rt300@0 96 }
rt300@0 97
rt300@0 98 for(int i=0; i < codeLength; i++){ // fill vector
rt300@0 99
rt300@0 100 vcode.push_back(vector<bool>());
rt300@0 101
rt300@0 102 for(int j=0; j<paramsPerDim; j++){
rt300@0 103 vcode[i].push_back(code[i][j]);
rt300@0 104 }
rt300@0 105 }
rt300@0 106
rt300@0 107 // now try with iterators to print...
rt300@0 108 vector< vector<bool> >::iterator cit;
rt300@0 109 //vector<bool>::iterator bit;
rt300@0 110 vector<bool>::iterator bit;
rt300@0 111 int i = 0;
rt300@0 112 for(cit=vcode.begin(); cit!=vcode.end() ; cit++){ // fill vector
rt300@0 113 i++;
rt300@0 114 cout << i << " = ";
rt300@0 115 bit = (*cit).begin();
rt300@0 116 for(bit=(*cit).begin(); bit!=(*cit).end() ; bit++){
rt300@0 117
rt300@0 118 cout << *bit;
rt300@0 119 }
rt300@0 120 cout << "\n";
rt300@0 121
rt300@0 122 }
rt300@0 123 /*
rt300@0 124 // codeToInt unit test
rt300@0 125 vector<bool> aCode = vcode[12];
rt300@0 126 int result = grayToInt(aCode);
rt300@0 127 cout << "GRAY TO INT : " << result << "\n";
rt300@0 128
rt300@0 129 cout << "-------------------------------\n";
rt300@0 130
rt300@0 131 // base32toFloat unit test
rt300@0 132
rt300@0 133 vector<int> test32 = coordTobase32(869437.0);
rt300@0 134 double cresult = base32toCoord(test32);
rt300@0 135 cout << "base32toCoord : " << cresult << "\n";
rt300@0 136
rt300@0 137 cout << "-------------------------------\n";
rt300@0 138
rt300@0 139
rt300@0 140
rt300@0 141 // midiToGray unit test
rt300@0 142
rt300@0 143 vector<vector<bool> > incodes(paramBitDepth, vector<bool>(paramsPerDim));
rt300@0 144 for(int i=0;i<7;i++){
rt300@0 145 incodes[i] = vcode[i+5];
rt300@0 146 }
rt300@0 147
rt300@0 148 vector<int> midiTest;
rt300@0 149 midiTest = grayToMidi(incodes);
rt300@0 150 vector<vector<bool> > outcodes = midiToGray(midiTest);
rt300@0 151
rt300@0 152 vector< vector<bool> >::iterator cit1;
rt300@0 153 //vector<bool>::iterator bit;
rt300@0 154 vector<bool>::iterator bit1;
rt300@0 155 cout << "midiToGray Unit test\n";
rt300@0 156 for(int i=0;i<paramBitDepth;i++){ // fill vector
rt300@0 157
rt300@0 158 for(int j=0;j<paramsPerDim;j++){
rt300@0 159
rt300@0 160 cout << (incodes[i][j] == outcodes[i][j]) << ",";
rt300@0 161 }
rt300@0 162 cout << "\n";
rt300@0 163
rt300@0 164 }
rt300@0 165 cout << "-------------------------------\n";
rt300@0 166
rt300@0 167
rt300@0 168 // whole process unit test(?)
rt300@0 169
rt300@0 170 TwoVector inCoord(888999777,777666555);
rt300@0 171 vector<int> checkParam;
rt300@0 172 checkParam = calculateParamsFromCoord(inCoord);
rt300@0 173 for(int i=0; i<2*paramsPerDim;i++){
rt300@0 174 cout << checkParam[i] << "_";
rt300@0 175 }
rt300@0 176 TwoVector outCoord = calculateCoordFromParams(checkParam);
rt300@0 177 cout << "Unit TEst coord = " << outCoord.x << "," << outCoord.y << "\n";
rt300@0 178 */
rt300@0 179
rt300@0 180 }
rt300@0 181 //--------------------------------------------------------------
rt300@0 182 void Grid::draw(){ // draw lines
rt300@0 183 // TODO too friggin long
rt300@0 184
rt300@0 185 //scale++;
rt300@0 186 // nice loopy thing
rt300@0 187 int power = 0;
rt300@0 188
rt300@0 189 // these get big!
rt300@0 190 double divsr;
rt300@0 191 double yl,xl;
rt300@0 192 double gridSize = 0;
rt300@0 193
rt300@0 194 double firstLineXPos, lastLineXPos,firstLineYPos, lastLineYPos, remleft, xoffset, yoffset = 0.0;
rt300@0 195 double xstart, xfinish, ystart,yfinish;
rt300@0 196 // these don't
rt300@0 197 int xpos, ypos = 0;
rt300@0 198
rt300@0 199 float alpha;
rt300@0 200 bool done = false;
rt300@0 201 float markpow = 32.0; // power that denotes next grid markings
rt300@0 202 int lineWidth = 0;
rt300@0 203 int colCycle = 0;
rt300@0 204
rt300@0 205 // get all the preset points within this view
rt300@0 206 //presetManager.getPresetsInRange(topLeft, topLeft+size);
rt300@0 207
rt300@0 208 // loop thru powers of (base?) to determine which should be shown as grids
rt300@0 209 while (!done){
rt300@0 210 gridSize = pow(markpow,power);
rt300@0 211
rt300@0 212 colCycle = power % 7;
rt300@0 213
rt300@0 214 divsr = size.x / gridSize;
rt300@0 215
rt300@0 216 // if (divisor i.e. number of lines is less than 1000
rt300@0 217 if( divsr >= 1 && divsr < 1000){
rt300@0 218
rt300@0 219 // calculate transparency
rt300@0 220 float visCont = log10(divsr); // 0 if only 1 line, 3 if 1000 lines
rt300@0 221 alpha = 90*(3 - visCont);
rt300@0 222 ofSetLineWidth(lineWidth);
rt300@0 223
rt300@0 224 // cycle colors for different scales
rt300@0 225 if(colCycle == 0){
rt300@0 226 ofSetColor(255,255,255,alpha);
rt300@0 227 }else if(colCycle == 1){
rt300@0 228 ofSetColor(255,0,0,alpha);
rt300@0 229 }else if(colCycle == 2){
rt300@0 230 ofSetColor(0,0,255,alpha);
rt300@0 231 }else if(colCycle == 3){
rt300@0 232 ofSetColor(0,255,0,alpha);
rt300@0 233 }else if(colCycle == 4){
rt300@0 234 ofSetColor(255,0,255,alpha);
rt300@0 235 }else if(colCycle == 5){
rt300@0 236 ofSetColor(0,255,255,alpha);
rt300@0 237 }else if(colCycle == 6){
rt300@0 238 ofSetColor(255,255,0,alpha);
rt300@0 239 }else if(colCycle == 7){
rt300@0 240 ofSetColor(255,255,255,alpha);
rt300@0 241 }else{
rt300@0 242 cout << "err colour messed up\n";
rt300@0 243 }
rt300@0 244
rt300@0 245
rt300@0 246 // draw level numbers associated with each color. This would not be true if markpow wasnt 2^d
rt300@0 247 ////////-------/////////
rt300@0 248 /*
rt300@0 249 temp << "THIS LEVEL = " << (int)pow(2.0,power) << " ";
rt300@0 250 string s = temp.str();
rt300@0 251 ofDrawBitmapString( s, 10, line );
rt300@0 252 line+=30;
rt300@0 253 temp.str("");
rt300@0 254 *////////-------/////////
rt300@0 255
rt300@0 256 // draw presets at this level
rt300@0 257 // fill in smallest squares if they contain a preset
rt300@0 258 // how to do this efficiently?
rt300@0 259
rt300@0 260
rt300@0 261 if(topLeft.x < 0.0){
rt300@0 262 firstLineXPos = 0.0;
rt300@0 263 xoffset = firstLineXPos - topLeft.x;
rt300@0 264 xstart = xoffset/scale;
rt300@0 265 }else{
rt300@0 266 firstLineXPos = topLeft.x;
rt300@0 267 // kinda float version of % operator
rt300@0 268 remleft = ceil(firstLineXPos/gridSize);
rt300@0 269 xoffset = (remleft * gridSize) - topLeft.x;
rt300@0 270 xstart = 0;
rt300@0 271 }
rt300@0 272 if(topLeft.x + size.x > maxValue){
rt300@0 273 lastLineXPos = maxValue+1 - topLeft.x;
rt300@0 274
rt300@0 275
rt300@0 276 }else{
rt300@0 277 lastLineXPos = size.x;
rt300@0 278
rt300@0 279 }
rt300@0 280 xfinish = lastLineXPos/scale;
rt300@0 281
rt300@0 282 //////////------------------------
rt300@0 283 // same for y
rt300@0 284
rt300@0 285 if(topLeft.y < 0.0){
rt300@0 286 firstLineYPos = 0.0;
rt300@0 287 yoffset = firstLineYPos - topLeft.y;
rt300@0 288 ystart = yoffset/scale;
rt300@0 289 }else{
rt300@0 290 firstLineYPos = topLeft.y;
rt300@0 291 // kinda float version of % operator
rt300@0 292 remleft = ceil(firstLineYPos/gridSize);
rt300@0 293 yoffset = (remleft * gridSize) - topLeft.y;
rt300@0 294 ystart = 0;
rt300@0 295 }
rt300@0 296 if(topLeft.y + size.y > maxValue){
rt300@0 297 lastLineYPos = maxValue+1 - topLeft.y;
rt300@0 298
rt300@0 299 }else{
rt300@0 300 lastLineYPos = size.y;
rt300@0 301
rt300@0 302 }
rt300@0 303 yfinish = lastLineYPos/scale;
rt300@0 304 // -------------------------------------------
rt300@0 305 // now draw
rt300@0 306 for(xl = xoffset; xl <= (lastLineXPos); xl+= gridSize){
rt300@0 307
rt300@0 308 xpos = xl/scale;
rt300@0 309 ofLine(xpos, ystart, xpos, yfinish);
rt300@0 310
rt300@0 311 }
rt300@0 312
rt300@0 313 for(yl = yoffset; yl <= (lastLineYPos); yl+= gridSize){
rt300@0 314
rt300@0 315 ypos = yl/scale;
rt300@0 316 ofLine(xstart, ypos, xfinish, ypos);
rt300@0 317 }
rt300@0 318
rt300@0 319
rt300@0 320 }else if (divsr < 1){
rt300@0 321 // ignore...
rt300@0 322 done = true;
rt300@0 323 }
rt300@0 324
rt300@0 325 power++;
rt300@0 326 }
rt300@0 327 //cout << "draw done" << "\n";
rt300@0 328 //displayInfo();
rt300@0 329
rt300@0 330 ////////-------/////////
rt300@0 331
rt300@0 332 ////////-------/////////
rt300@0 333
rt300@0 334 // draw centre cross hairs
rt300@0 335 ofSetColor(255, 0, 0);
rt300@0 336 ofNoFill();
rt300@0 337 ofLine(pixSize.x/2-20, pixSize.y/2, pixSize.x/2+20, pixSize.y/2);
rt300@0 338 ofLine(pixSize.x/2, pixSize.y/2-20, pixSize.x/2, pixSize.y/2+20);
rt300@0 339 ofEllipse(pixSize.x/2, pixSize.y/2, 20, 20);
rt300@0 340 ofFill();
rt300@0 341 ////////-------////////
rt300@0 342 /*
rt300@0 343 ostringstream temp;
rt300@0 344 temp << "Centre x = " << centre.x << "\n y = " << centre.y << " ";
rt300@0 345 string s = temp.str();
rt300@0 346 ofDrawBitmapString( s, pixSize.x/2+10, pixSize.y/2+10 );
rt300@0 347 */
rt300@0 348 }
rt300@0 349 //-----------------------------------------------------------------------
rt300@0 350 void Grid::displayInfo(){
rt300@0 351
rt300@0 352 // display some "useful information"
rt300@0 353
rt300@0 354 ofSetColor(255,255,255,255);
rt300@0 355
rt300@0 356 ostringstream temp;
rt300@0 357 int line = 10; // text output pos
rt300@0 358
rt300@0 359
rt300@0 360 ////////-------/////////
rt300@0 361 temp << "scale = " << scale << " ";
rt300@0 362 string s = temp.str();
rt300@0 363 ofDrawBitmapString( s, 10, line );
rt300@0 364 line+=30;
rt300@0 365 temp.str("");
rt300@0 366 ////////-------/////////
rt300@0 367 temp << "Top Left = " << topLeft.x << "," << topLeft.y << " ";
rt300@0 368 s = temp.str();
rt300@0 369 ofDrawBitmapString( s, 10, line );
rt300@0 370 line+=60;
rt300@0 371 temp.str("");
rt300@0 372
rt300@0 373 ////////-------/////////
rt300@0 374 temp << "View Size = " << size.x << "," << size.y << " ";
rt300@0 375 s = temp.str();
rt300@0 376 ofDrawBitmapString( s, 10, line );
rt300@0 377 line+=60;
rt300@0 378 temp.str("");
rt300@0 379
rt300@0 380 ////////-------/////////
rt300@0 381
rt300@0 382 for(int i=0;i<10;i++){ // TODO 5bit specific
rt300@0 383 temp << midiCC[i] << " ";
rt300@0 384 s = temp.str();
rt300@0 385 ofDrawBitmapString( s, 10, line );
rt300@0 386 line+=20;
rt300@0 387 temp.str("");
rt300@0 388 }
rt300@0 389 }
rt300@0 390 //--------------------------------------------------------------
rt300@0 391 void Grid::update(){ // ?
rt300@0 392 // "update" bit of a crap name - all we do here is calculate the dimension params from the x,y position
rt300@0 393
rt300@0 394 vector<int> params = calculateParamsFromCoord(centre);
rt300@0 395 for(int i = 0;i<2*paramsPerDim;i++){
rt300@0 396 midiCC[i] = params[i];
rt300@0 397 }
rt300@0 398
rt300@0 399 }
rt300@0 400 //--------------------------------------------------------------
rt300@0 401 void Grid::move(int moveX, int moveY){
rt300@0 402 // numspacing, pixelspacing stay the same
rt300@0 403
rt300@0 404 // convert pixels to surf units
rt300@0 405 TwoVector moveS;
rt300@0 406 moveS.setCoord(moveX * scale, moveY * scale);
rt300@0 407
rt300@0 408 topLeft = topLeft - moveS; // - because moving to the right means taking away from offset
rt300@0 409 centre = centre - moveS;
rt300@1 410 eventLogger.logEvent(-1, centre, scale);
rt300@0 411 viewWasChanged();
rt300@0 412 }
rt300@0 413 //--------------------------------------------------------------
rt300@0 414 void Grid::zoom(float factor){
rt300@0 415 if(maxZoom && factor > 1.0){
rt300@0 416 return;
rt300@0 417
rt300@0 418 }
rt300@0 419 if(factor < 1.0){
rt300@0 420 maxZoom = false;
rt300@0 421 }
rt300@0 422 if(minZoom && factor < 1.0){
rt300@0 423 return;
rt300@0 424
rt300@0 425 }
rt300@0 426 if(factor > 1.0){
rt300@0 427 minZoom = false;
rt300@0 428 }
rt300@0 429 scale = scale*factor; // simple eh?
rt300@0 430
rt300@0 431 // update view size using centre
rt300@0 432 // and scale...
rt300@0 433 size.x = size.x*factor; // zooming in, size gets SMALLER (view less)
rt300@0 434 size.y = size.y*factor;
rt300@0 435
rt300@1 436
rt300@1 437 eventLogger.logEvent(-2, centre, scale);
rt300@0 438 viewWasChanged();
rt300@0 439
rt300@0 440 }
rt300@0 441 //--------------------------------------------------------------
rt300@0 442 void Grid::viewWasChanged(){
rt300@0 443 checkLimits();
rt300@0 444 // and calculate new params?
rt300@0 445
rt300@0 446
rt300@0 447 }
rt300@0 448
rt300@0 449 //--------------------------------------------------------------
rt300@0 450 void Grid::checkLimits(){
rt300@0 451 // check for maximum zoom level
rt300@0 452 // TODO: DODGY
rt300@0 453
rt300@0 454 if(size.x > maxValue*2.0){
rt300@0 455 cout << "maxZoom\n";
rt300@0 456 maxZoom = true;
rt300@0 457 size.x = maxValue*2.0;
rt300@0 458 // need to also set y size back to
rt300@0 459 }
rt300@0 460 if(size.y > maxValue*2.0){
rt300@0 461 cout << "maxZoom\n";
rt300@0 462 maxZoom = true;
rt300@0 463 size.y = maxValue*2.0;
rt300@0 464 }
rt300@0 465
rt300@0 466 if(size.x < minValue){
rt300@0 467 cout << "min Zoom\n";
rt300@0 468 minZoom = true;
rt300@0 469 size.x = minValue;
rt300@0 470 // need to also set y size back to
rt300@0 471 }
rt300@0 472 if(size.y < minValue){
rt300@0 473 minZoom = true;
rt300@0 474 cout << "min Zoom\n";
rt300@0 475 size.y = minValue;
rt300@0 476 }
rt300@0 477
rt300@0 478 scale = size.x/pixSize.x;
rt300@0 479 size.y = scale * pixSize.y;
rt300@0 480
rt300@0 481 topLeft.x = centre.x - size.x/2;
rt300@0 482 topLeft.y = centre.y - size.y/2;
rt300@0 483 // check for negatives
rt300@0 484
rt300@0 485 // allow centre to be at limits
rt300@0 486 if((topLeft.x + size.x*0.5) < 0.0){
rt300@0 487 cout << "left Wall\n";
rt300@0 488 topLeft.x = 0.0 - size.x*0.5;
rt300@0 489 centre.x = 0.0;
rt300@0 490 }
rt300@0 491
rt300@0 492 if(topLeft.y + size.y*0.5 < 0.0) {
rt300@0 493 cout << "top Wall\n";
rt300@0 494 topLeft.y = 0.0 - size.y*0.5;
rt300@0 495 centre.y = 0.0;
rt300@0 496 }
rt300@0 497
rt300@0 498 // does topleft refer to lines or view?
rt300@0 499
rt300@0 500 // check max
rt300@0 501 if(topLeft.x + size.x/2 > maxValue){
rt300@0 502 cout << "right Wall\n";
rt300@0 503 topLeft.x = maxValue - size.x/2;
rt300@0 504 centre.x = maxValue;
rt300@0 505 }
rt300@0 506 if(topLeft.y + size.y/2 > maxValue) {
rt300@0 507 cout << "bottom Wall\n";
rt300@0 508 topLeft.y = maxValue - size.y/2;
rt300@0 509 centre.y = maxValue;
rt300@0 510 }
rt300@0 511
rt300@0 512 }
rt300@0 513 //--------------------------------------------------------------
rt300@0 514 void Grid::checkConsistencies(){
rt300@0 515 // debug function to check all the parameters are consistent maybe
rt300@0 516
rt300@0 517 }
rt300@0 518 //--------------------------------------------------------------
rt300@0 519 void Grid::setCoord(TwoVector coord){
rt300@0 520
rt300@0 521 centre = coord;
rt300@0 522 viewWasChanged();
rt300@0 523 }
rt300@0 524 //--------------------------------------------------------------
rt300@0 525 TwoVector Grid::getCoord(){
rt300@0 526
rt300@0 527 return centre;
rt300@0 528 }
rt300@0 529 //--------------------------------------------------------------
rt300@0 530 vector<int> Grid::getParams(){
rt300@0 531 // return a vector with midiCCs in
rt300@0 532 // should we store params somewhere and use this as a low computation get ?
rt300@0 533 vector<int> params(2*paramsPerDim,0);
rt300@0 534 //
rt300@0 535 for(int i = 0;i<2*paramsPerDim;i++){
rt300@0 536 params[i] = midiCC[i];
rt300@0 537 }
rt300@0 538 return params;
rt300@0 539 }
rt300@0 540 //--------------------------------------------------------------
rt300@0 541 void Grid::setParams(vector<int> params){
rt300@0 542 // input midiCCs, and go to the appropriate coordinate
rt300@0 543
rt300@0 544 for(int i = 0;i<2*paramsPerDim;i++){
rt300@0 545 midiCC[i] = 64;
rt300@0 546 }
rt300@0 547 TwoVector coord = calculateCoordFromParams(params);
rt300@0 548 setCoord(coord);
rt300@0 549
rt300@0 550 viewWasChanged();
rt300@0 551
rt300@0 552 }
rt300@0 553 //--------------------------------------------------------------
rt300@0 554 TwoVector Grid::calculateCoordFromParams(vector<int> params){
rt300@0 555
rt300@0 556 vector<int> ccValueX(paramsPerDim);
rt300@0 557 vector<int> ccValueY(paramsPerDim);
rt300@0 558 for(int i=0;i<paramsPerDim;i++){
rt300@0 559 ccValueX[i] = params[i];
rt300@0 560 ccValueY[i] = params[i+paramsPerDim];
rt300@0 561 }
rt300@0 562 vector<vector <bool> > codesX = midiToGray(ccValueX);
rt300@0 563 vector<vector <bool> > codesY = midiToGray(ccValueY);
rt300@0 564
rt300@0 565 vector<int> base32X = codesToBase32(codesX);
rt300@0 566 vector<int> base32Y = codesToBase32(codesY);
rt300@0 567
rt300@0 568 TwoVector result;
rt300@0 569 result.x = base32toCoord(base32X);
rt300@0 570 result.y = base32toCoord(base32Y);
rt300@0 571 return result;
rt300@0 572 }
rt300@0 573
rt300@0 574 //--------------------------------------------------------------
rt300@0 575 vector<int> Grid::calculateParamsFromCoord(TwoVector coord){
rt300@0 576 // some arrays in reverse order of power from normal numbers! 1,2,4,
rt300@0 577
rt300@0 578 // centre to base 32
rt300@0 579 if (coord.x > maxValue || coord.y > maxValue){
rt300@0 580 cout << "calculateParams Error: centre double value is too large" << "\n";
rt300@0 581 vector<int> empty;
rt300@0 582 return empty;
rt300@0 583 }
rt300@0 584
rt300@0 585 //--------------------------
rt300@0 586 // X
rt300@0 587 vector<int> base32x = coordTobase32(coord.x); // 7 numbers from 0 to 31
rt300@0 588 vector<vector <bool> > grayCodesX;
rt300@0 589
rt300@0 590 int size = base32x.size();
rt300@0 591 for(int i=0;i<size;i++){
rt300@0 592 grayCodesX.push_back(intToGray(base32x[i]));
rt300@0 593 }
rt300@0 594
rt300@0 595 vector<int> result;
rt300@0 596 result = grayToMidi(grayCodesX);
rt300@0 597 //--------------------------
rt300@0 598 // AND FOR Y
rt300@0 599 vector<int> base32y = coordTobase32(coord.y);
rt300@0 600 vector<vector <bool> > grayCodesY;
rt300@0 601
rt300@0 602 size = base32y.size();
rt300@0 603 for(int i=0;i<size;i++){
rt300@0 604 grayCodesY.push_back(intToGray(base32y[i]));
rt300@0 605 }
rt300@0 606
rt300@0 607 vector<int> resultY;
rt300@0 608 resultY = grayToMidi(grayCodesY);
rt300@0 609
rt300@0 610 // concatenate
rt300@0 611 result.insert( result.end(), resultY.begin(), resultY.end() );
rt300@0 612 return result;
rt300@0 613 }
rt300@0 614 //-------------------------------------------------------------------
rt300@0 615
rt300@0 616 // for 1 dimension!!! i.e. call this twice
rt300@0 617 vector<int> Grid::grayToMidi(vector<vector <bool> > grayCodes){
rt300@0 618
rt300@0 619 // gray to midi CC values
rt300@0 620 // loop thru the scales to build up a CC number per dimension
rt300@0 621 int midiCCresult[paramsPerDim]; // TODO dims specific
rt300@0 622 for(int i=0;i<paramsPerDim;i++){
rt300@0 623 midiCCresult[i] = 0;
rt300@0 624 }
rt300@0 625
rt300@0 626 int bin = 1;
rt300@0 627 bin = bin << grayCodes.size()-1;
rt300@0 628
rt300@0 629 int midP = 0;
rt300@0 630
rt300@0 631 vector<vector <bool> >::iterator piter = grayCodes.begin();
rt300@0 632 for(;piter < grayCodes.end();piter++){ // each lesser power of 2
rt300@0 633 midP = 0; // reset
rt300@0 634 vector<bool>::iterator diter = (*piter).begin();
rt300@0 635 for(; diter <= (*piter).end();diter++){ // each one is different dimension
rt300@0 636 int ig = int(*diter); // convert binary to int
rt300@0 637 //cout << "ig: " << ig;
rt300@0 638 midiCCresult[midP] += ig*bin; // mult by power of two
rt300@0 639 midP++;
rt300@0 640 }
rt300@0 641 bin = bin >> 1; // next power of 2 down
rt300@0 642
rt300@0 643 }
rt300@0 644
rt300@0 645 // put in vector
rt300@0 646 vector<int> result;
rt300@0 647 for(int i=0;i<paramsPerDim;i++){
rt300@0 648 result.push_back(midiCCresult[i]);
rt300@0 649 }
rt300@0 650
rt300@0 651 return result;
rt300@0 652
rt300@0 653
rt300@0 654 }
rt300@0 655
rt300@0 656
rt300@0 657 //--------------------------------------------------------------
rt300@0 658
rt300@0 659 vector<bool> Grid::intToGray(int num, int dimToTravel){
rt300@0 660
rt300@0 661 // dimToTravel - this is the dimension that we want the walk to traverse, i.e. the last non zero digit of the code
rt300@0 662 // so swap it for 3 to produce correct orientation
rt300@0 663
rt300@0 664 // just use look up table... until it gets huuuge.
rt300@0 665 vector<bool> grayCode = vcode[num];
rt300@0 666 grayCode[3] = vcode[num][dimToTravel];
rt300@0 667 grayCode[dimToTravel] = vcode[num][3];
rt300@0 668 return grayCode;
rt300@0 669 }
rt300@0 670 //--------------------------------------------------------------
rt300@0 671 vector<int> Grid::walkDiff(vector<bool> left, vector<bool> right){
rt300@0 672 // horrible
rt300@0 673 vector<int> result(2,0);
rt300@0 674
rt300@0 675 int size = left.size();
rt300@0 676 for(int i = 0; i < size; i++){
rt300@0 677 if(left[i] && !right[i]){ // 1 - 0
rt300@0 678 // dim
rt300@0 679 result[0] = i;
rt300@0 680 result[1] = 1;
rt300@0 681 }else if(!left[i] && right[i]){ // 0 - 1
rt300@0 682 result[0] = i;
rt300@0 683 result[1] = -1;
rt300@0 684 }else{ // equal do nothing
rt300@0 685
rt300@0 686
rt300@0 687 }
rt300@0 688 }
rt300@0 689
rt300@0 690 return result;
rt300@0 691 }
rt300@0 692
rt300@0 693 //--------------------------------------------------------------
rt300@0 694 /*
rt300@0 695 breaks down float into a base 32 number (2^D)
rt300@0 696 each of these is converted to gray code
rt300@0 697 this is then converted to 10 parameters, where each 32-digit becomes separate power of 2
rt300@0 698 so "zoom" grid 32-patches are converted to 2-scales. 1,2,4,8,16,32,64,(128?) biggest number is 32^7
rt300@0 699 */
rt300@0 700 vector<int> Grid::coordTobase32(double value){
rt300@0 701 //double base = 32.0;
rt300@0 702 if(value < 0.0){
rt300@0 703 cout << "coordTobase32 error: input value is negative\n";
rt300@0 704 value = 0.0;
rt300@0 705 }else if(value > maxValue){
rt300@0 706 cout << "coordTobase32 error: input value too big!\n";
rt300@0 707 }
rt300@0 708 double rem, divdr = 0.0;
rt300@0 709 int digit32;
rt300@0 710
rt300@0 711 // what power of 32 to start at?
rt300@0 712 int maxpow = 7; // midi cc specific
rt300@0 713 vector<int> result;
rt300@0 714
rt300@0 715 rem = value;
rt300@0 716 for(;maxpow >=0;maxpow--){
rt300@0 717 // repeatedly get digit and remainder. This is exactly what we're doing in draw !?... could put all this in one place?
rt300@0 718 divdr = pow((double)codeLength,(double)maxpow);
rt300@0 719 digit32 = floor(rem/divdr);
rt300@0 720 rem = rem - digit32*divdr;
rt300@0 721 result.push_back(digit32); // array, biggest index is smallest power
rt300@0 722 }
rt300@0 723 // at this point rem should be fractional... use for interp?
rt300@0 724
rt300@0 725 return result;
rt300@0 726 }
rt300@0 727 //--------------------------------------------------------------
rt300@0 728
rt300@0 729 // WHY HERE XCODE?
rt300@0 730 vector<int> Grid::codesToBase32(vector<vector<bool> > inCodes){
rt300@0 731 vector<int> result;
rt300@0 732 for(int i=0;i<paramBitDepth;i++){
rt300@0 733 result.push_back(grayToInt(inCodes[i]));
rt300@0 734 }
rt300@0 735 return result;
rt300@0 736 }
rt300@0 737 //--------------------------------------------------------------
rt300@0 738
rt300@0 739 int Grid::grayToInt(vector<bool> incode){
rt300@0 740 // look for match in table
rt300@0 741
rt300@0 742 int s = vcode.size();
rt300@0 743
rt300@0 744 for(int i=0; i<s;i++){ // fill vector
rt300@0 745 if(vcode[i] == incode){
rt300@0 746 return i;
rt300@0 747 }
rt300@0 748
rt300@0 749 }
rt300@0 750 cout << "grayToInt error: no matching code found!";
rt300@0 751 return -1;
rt300@0 752 }
rt300@0 753 //--------------------------------------------------------------
rt300@0 754 double Grid::base32toCoord(vector<int> base32Digs){
rt300@0 755 // build up the big float from a base 32 number
rt300@0 756 double result = 0.0;
rt300@0 757
rt300@0 758 // what power of 32 to start at?
rt300@0 759 int mpow = base32Digs.size() - 1; // should be 7...
rt300@0 760
rt300@0 761 for(int p=0;p<=mpow;p++){ // biggest index is smallest power
rt300@0 762 result += ((double)base32Digs[p]) * pow(32.0, (double)mpow-p);
rt300@0 763
rt300@0 764 }
rt300@0 765 return result;
rt300@0 766
rt300@0 767 }
rt300@0 768 //--------------------------------------------------------------
rt300@0 769 // for 1 dimension - takes in 5 cc params and outputs 7 codes
rt300@0 770 vector<vector <bool> > Grid::midiToGray(vector<int> ccValue){
rt300@0 771 int pow2 = 1 << (paramBitDepth-1);
rt300@0 772
rt300@0 773 vector<int> aCode(paramsPerDim);
rt300@0 774 vector<vector<int> > theXCodes(paramBitDepth,aCode);
rt300@0 775
rt300@0 776 // build up binary gray code representations from the bits of the midi ccs
rt300@0 777
rt300@0 778 vector<vector<bool> > theCodes(paramBitDepth, vector<bool>(paramsPerDim));
rt300@0 779
rt300@0 780 // x
rt300@0 781 for(int p=0;p<paramBitDepth;p++){
rt300@0 782
rt300@0 783 for(int i=0;i<paramsPerDim;i++){
rt300@0 784
rt300@0 785 bool bit = (pow2 == (ccValue[i] & pow2));
rt300@0 786 theCodes[p][i] = bit;
rt300@0 787 }
rt300@0 788 pow2 = pow2 >> 1;
rt300@0 789
rt300@0 790 }
rt300@0 791 return theCodes;
rt300@0 792 }
rt300@0 793 //--------------------------------------------------------------
rt300@0 794 //--------------------------------------------------------------
rt300@0 795 //--------------------------------------------------------------