annotate grid.mm @ 37:8ed7522deaaa

Interpolation.
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Tue, 09 Apr 2013 17:14:31 +0100
parents 790939017078
children 0dfe9e0c01aa
rev   line source
rt300@4 1 //
rt300@4 2 // grid.cpp
rt300@4 3 // oscSenderExample
rt300@4 4 //
rt300@4 5 // Created by Robert Tubb on 03/10/2012.
rt300@4 6 //
rt300@37 7 // This is the grid view, i.e. the viewable representation of hilbert surface
rt300@4 8
rt300@4 9 #include "grid.h"
rt300@4 10
rt300@4 11
rt300@4 12 #include <sstream>
rt300@4 13
rt300@4 14 extern PresetManager presetManager;
rt300@4 15 extern EventLogger eventLogger;
rt300@34 16 extern Hilbert hilbert;
rt300@4 17 //--------------------------------------------------------------
rt300@35 18 Grid::Grid(): maxValue(pow(32.0,7.0)-1), minValue(30), paramsPerDim(5), paramBitDepth(7){
rt300@4 19
rt300@37 20 interpLevel = 4;
rt300@4 21 }
rt300@4 22 //--------------------------------------------------------------
rt300@4 23 //--------------------------------------------------------------
rt300@4 24 Grid::~Grid(){
rt300@4 25
rt300@4 26 }
rt300@4 27 void Grid::init(){
rt300@34 28
rt300@37 29 interpolateMode = INTERPOLATE_GRID;
rt300@37 30
rt300@4 31 maxZoom = false;
rt300@4 32 minZoom = false;
rt300@4 33
rt300@4 34 pixSize.setCoord(ofGetWidth(), ofGetHeight());
rt300@4 35
rt300@35 36 //set scale and position to random
rt300@27 37 scale = 15500.0;
rt300@35 38
rt300@37 39 smallestGridSpacing = 3; //pixels
rt300@37 40
rt300@8 41 snapDist = TwoVector(9,9);
rt300@5 42 snapped = false;
rt300@4 43
rt300@4 44 size.setCoord(pixSize.x*scale, pixSize.y*scale);
rt300@4 45 centre.setCoord(maxValue/2 , maxValue/2);
rt300@4 46 topLeft.setCoord(centre.x - size.x/2, centre.y - size.y/2);
rt300@34 47
rt300@34 48 hilbert.init(paramBitDepth, paramsPerDim);
rt300@4 49
rt300@4 50 // set a starting param value, find coord that does it.
rt300@4 51 vector<int> params(paramsPerDim*2);
rt300@4 52 for(int i = 0;i<2*paramsPerDim;i++){
rt300@4 53 midiCC[i] = 12;
rt300@4 54 params[i] = 12;
rt300@4 55 }
rt300@35 56
rt300@35 57
rt300@4 58 TwoVector coord = calculateCoordFromParams(params);
rt300@4 59 setCoord(coord);
rt300@4 60
rt300@4 61 viewWasChanged();
rt300@37 62 calculateInterpolateLevel();
rt300@4 63 }
rt300@4 64
rt300@4 65 template <typename T> int sgn(T val) {
rt300@4 66 return (T(0) < val) - (val < T(0));
rt300@4 67 }
rt300@37 68 //--------------------------------------------------------------
rt300@37 69 int Grid::calculateInterpolateLevel(){
rt300@37 70 if(interpolateMode == INTERPOLATE_GRID){
rt300@37 71 // calculate according to smallest gridlines
rt300@37 72 // exactly same algorithm as for drawing lines
rt300@37 73 // i.e. kinda duplicated code.
rt300@37 74 float markpow = pow(paramsPerDim,2.0);
rt300@37 75 for(int p = 0; p < paramBitDepth; p++){
rt300@37 76
rt300@37 77 double gridSize = pow(markpow,p);
rt300@37 78 double divsr = size.x / gridSize;
rt300@37 79
rt300@37 80 // return the spacing
rt300@37 81 if( ofGetWidth()/divsr >= smallestGridSpacing){
rt300@37 82 interpLevel = p;
rt300@37 83 return p;
rt300@37 84 }
rt300@37 85 }
rt300@37 86 interpLevel = 0;
rt300@37 87 return 0;
rt300@37 88 }else{
rt300@37 89 interpLevel = 0;
rt300@37 90 return 0; // ???
rt300@37 91 }
rt300@37 92 }
rt300@37 93 //--------------------------------------------------------------
rt300@4 94
rt300@37 95 void Grid::draw(){
rt300@37 96 if(interpolateMode == NO_INTERPOLATION){
rt300@37 97 drawGridLines();
rt300@37 98 drawPresets();
rt300@37 99 }else if(interpolateMode == INTERPOLATE_GRID){
rt300@37 100 // calculate according to smallest gridlines
rt300@37 101 drawGridLines();
rt300@37 102
rt300@37 103 }else if(interpolateMode == INTERPOLATE_PRESET){
rt300@37 104 drawPresets();
rt300@37 105 return; // ???
rt300@37 106 }
rt300@37 107
rt300@37 108
rt300@37 109
rt300@37 110 // draw centre cross hairs
rt300@37 111 drawCrossHairs();
rt300@37 112
rt300@37 113
rt300@37 114 // draw the undo history trail, given viewing area
rt300@37 115 eventLogger.drawTrail(topLeft, topLeft + size);
rt300@37 116 }
rt300@4 117 //--------------------------------------------------------------
rt300@37 118 void Grid::drawGridLines(){ // draw lines
rt300@4 119 // TODO too friggin long
rt300@4 120
rt300@16 121 pixSize.setCoord(ofGetWidth(), ofGetHeight()); // incase of rotation?
rt300@37 122
rt300@4 123 int power = 0;
rt300@4 124
rt300@4 125 // these get big!
rt300@4 126 double divsr;
rt300@4 127 double yl,xl;
rt300@4 128 double gridSize = 0;
rt300@4 129
rt300@4 130 double firstLineXPos, lastLineXPos,firstLineYPos, lastLineYPos, remleft, xoffset, yoffset = 0.0;
rt300@4 131 double xstart, xfinish, ystart,yfinish;
rt300@4 132 // these don't
rt300@4 133 int xpos, ypos = 0;
rt300@4 134
rt300@4 135 float alpha;
rt300@4 136 bool done = false;
rt300@37 137 float markpow = 1 << paramsPerDim; // power that denotes next grid markings e.g. 32
rt300@4 138 int lineWidth = 0;
rt300@4 139 int colCycle = 0;
rt300@4 140
rt300@4 141
rt300@37 142 // loop thru powers of (base?) smallest to biggest
rt300@37 143 // to determine which should be shown as grids
rt300@4 144 while (!done){
rt300@4 145 gridSize = pow(markpow,power);
rt300@4 146
rt300@37 147 colCycle = power % paramBitDepth;
rt300@4 148
rt300@4 149 divsr = size.x / gridSize;
rt300@4 150
rt300@4 151 // if (divisor i.e. number of lines is less than 1000
rt300@37 152 if( ofGetWidth()/divsr >= smallestGridSpacing){
rt300@4 153
rt300@4 154 // calculate transparency
rt300@37 155 float visCont = log10(divsr*2); // 0 if only 1 line, 3 if 1000 lines
rt300@4 156 alpha = 90*(3 - visCont);
rt300@4 157 ofSetLineWidth(lineWidth);
rt300@4 158
rt300@4 159 // cycle colors for different scales
rt300@4 160 if(colCycle == 0){
rt300@4 161 ofSetColor(255,255,255,alpha);
rt300@4 162 }else if(colCycle == 1){
rt300@4 163 ofSetColor(255,0,0,alpha);
rt300@4 164 }else if(colCycle == 2){
rt300@4 165 ofSetColor(0,0,255,alpha);
rt300@4 166 }else if(colCycle == 3){
rt300@4 167 ofSetColor(0,255,0,alpha);
rt300@4 168 }else if(colCycle == 4){
rt300@4 169 ofSetColor(255,0,255,alpha);
rt300@4 170 }else if(colCycle == 5){
rt300@4 171 ofSetColor(0,255,255,alpha);
rt300@4 172 }else if(colCycle == 6){
rt300@4 173 ofSetColor(255,255,0,alpha);
rt300@4 174 }else if(colCycle == 7){
rt300@4 175 ofSetColor(255,255,255,alpha);
rt300@4 176 }else{
rt300@4 177 cout << "err colour messed up\n";
rt300@4 178 }
rt300@4 179
rt300@4 180
rt300@4 181 // draw level numbers associated with each color. This would not be true if markpow wasnt 2^d
rt300@4 182 ////////-------/////////
rt300@4 183 /*
rt300@4 184 temp << "THIS LEVEL = " << (int)pow(2.0,power) << " ";
rt300@4 185 string s = temp.str();
rt300@4 186 ofDrawBitmapString( s, 10, line );
rt300@4 187 line+=30;
rt300@4 188 temp.str("");
rt300@4 189 *////////-------/////////
rt300@4 190
rt300@4 191 // draw presets at this level
rt300@4 192 // fill in smallest squares if they contain a preset
rt300@4 193 // how to do this efficiently?
rt300@4 194
rt300@4 195
rt300@4 196 if(topLeft.x < 0.0){
rt300@4 197 firstLineXPos = 0.0;
rt300@4 198 xoffset = firstLineXPos - topLeft.x;
rt300@4 199 xstart = xoffset/scale;
rt300@4 200 }else{
rt300@4 201 firstLineXPos = topLeft.x;
rt300@4 202 // kinda float version of % operator
rt300@4 203 remleft = ceil(firstLineXPos/gridSize);
rt300@4 204 xoffset = (remleft * gridSize) - topLeft.x;
rt300@4 205 xstart = 0;
rt300@4 206 }
rt300@4 207 if(topLeft.x + size.x > maxValue){
rt300@4 208 lastLineXPos = maxValue+1 - topLeft.x;
rt300@4 209
rt300@4 210
rt300@4 211 }else{
rt300@4 212 lastLineXPos = size.x;
rt300@4 213
rt300@4 214 }
rt300@4 215 xfinish = lastLineXPos/scale;
rt300@4 216
rt300@4 217 //////////------------------------
rt300@4 218 // same for y
rt300@4 219
rt300@4 220 if(topLeft.y < 0.0){
rt300@4 221 firstLineYPos = 0.0;
rt300@4 222 yoffset = firstLineYPos - topLeft.y;
rt300@4 223 ystart = yoffset/scale;
rt300@4 224 }else{
rt300@4 225 firstLineYPos = topLeft.y;
rt300@4 226 // kinda float version of % operator
rt300@4 227 remleft = ceil(firstLineYPos/gridSize);
rt300@4 228 yoffset = (remleft * gridSize) - topLeft.y;
rt300@4 229 ystart = 0;
rt300@4 230 }
rt300@4 231 if(topLeft.y + size.y > maxValue){
rt300@4 232 lastLineYPos = maxValue+1 - topLeft.y;
rt300@4 233
rt300@4 234 }else{
rt300@4 235 lastLineYPos = size.y;
rt300@4 236
rt300@4 237 }
rt300@4 238 yfinish = lastLineYPos/scale;
rt300@4 239 // -------------------------------------------
rt300@4 240 // now draw
rt300@4 241 for(xl = xoffset; xl <= (lastLineXPos); xl+= gridSize){
rt300@4 242
rt300@4 243 xpos = xl/scale;
rt300@4 244 ofLine(xpos, ystart, xpos, yfinish);
rt300@4 245
rt300@4 246 }
rt300@4 247
rt300@4 248 for(yl = yoffset; yl <= (lastLineYPos); yl+= gridSize){
rt300@4 249
rt300@4 250 ypos = yl/scale;
rt300@4 251 ofLine(xstart, ypos, xfinish, ypos);
rt300@4 252 }
rt300@4 253
rt300@4 254
rt300@37 255 }
rt300@37 256 /*else if (divsr < 1){
rt300@37 257 // maximum only one line. worth checking so that bigger lines still show up?
rt300@4 258 done = true;
rt300@4 259 }
rt300@37 260 */
rt300@4 261 power++;
rt300@37 262 if(power > paramBitDepth)
rt300@37 263 done = true;
rt300@37 264
rt300@4 265 }
rt300@4 266 //cout << "draw done" << "\n";
rt300@4 267 //displayInfo();
rt300@4 268
rt300@33 269
rt300@33 270
rt300@4 271 ////////-------////////
rt300@4 272 /*
rt300@4 273 ostringstream temp;
rt300@4 274 temp << "Centre x = " << centre.x << "\n y = " << centre.y << " ";
rt300@4 275 string s = temp.str();
rt300@4 276 ofDrawBitmapString( s, pixSize.x/2+10, pixSize.y/2+10 );
rt300@4 277 */
rt300@4 278 }
rt300@5 279 //-----------------------------------------------------------------------
rt300@5 280 void Grid::drawCrossHairs(){
rt300@5 281 // snapping
rt300@5 282 TwoVector pos;
rt300@5 283 if(snapped){
rt300@5 284 pos = coordToPixel(snapCentre);
rt300@5 285 }else{
rt300@5 286 pos = coordToPixel(centre);
rt300@5 287
rt300@5 288 }
rt300@5 289 ofSetColor(255, 0, 0);
rt300@5 290 ofNoFill();
rt300@5 291 ofLine(pos.x-20, pos.y, pos.x+20, pos.y);
rt300@5 292 ofLine(pos.x, pos.y-20, pos.x, pos.y+20);
rt300@5 293 ofEllipse(pos.x, pos.y, 20, 20);
rt300@5 294 ofFill();
rt300@5 295 }
rt300@5 296 //-----------------------------------------------------------------------
rt300@4 297 TwoVector Grid::coordToPixel(TwoVector coord){
rt300@4 298 TwoVector pix;
rt300@4 299 pix.x = (coord.x - topLeft.x)/scale;
rt300@4 300 pix.y = (coord.y - topLeft.y)/scale;
rt300@4 301 return pix;
rt300@4 302
rt300@4 303 }
rt300@4 304
rt300@4 305 //-----------------------------------------------------------------------
rt300@4 306 void Grid::drawPresets(){
rt300@5 307 presetManager.drawPresetsInRange(topLeft, topLeft + size);
rt300@7 308 // draw snapped preset info
rt300@7 309 if(snapped && closestPreset != NULL){
rt300@8 310 ofDrawBitmapString( closestPreset->displayTextDescription(), pixSize.x/2+10, pixSize.y/2+10 );
rt300@7 311 }
rt300@33 312
rt300@4 313 }
rt300@4 314
rt300@4 315 //-----------------------------------------------------------------------
rt300@4 316 void Grid::displayInfo(){
rt300@4 317
rt300@4 318 // display some "useful information"
rt300@4 319
rt300@4 320 ofSetColor(255,255,255,255);
rt300@4 321
rt300@4 322 ostringstream temp;
rt300@4 323 int line = 10; // text output pos
rt300@4 324
rt300@4 325
rt300@4 326 ////////-------/////////
rt300@4 327 temp << "scale = " << scale << " ";
rt300@4 328 string s = temp.str();
rt300@4 329 ofDrawBitmapString( s, 10, line );
rt300@4 330 line+=30;
rt300@4 331 temp.str("");
rt300@4 332 ////////-------/////////
rt300@4 333 temp << "Top Left = " << topLeft.x << "," << topLeft.y << " ";
rt300@4 334 s = temp.str();
rt300@4 335 ofDrawBitmapString( s, 10, line );
rt300@4 336 line+=60;
rt300@4 337 temp.str("");
rt300@4 338
rt300@4 339 ////////-------/////////
rt300@4 340 temp << "View Size = " << size.x << "," << size.y << " ";
rt300@4 341 s = temp.str();
rt300@4 342 ofDrawBitmapString( s, 10, line );
rt300@4 343 line+=60;
rt300@4 344 temp.str("");
rt300@4 345
rt300@4 346 ////////-------/////////
rt300@4 347
rt300@4 348 for(int i=0;i<10;i++){ // TODO 5bit specific
rt300@4 349 temp << midiCC[i] << " ";
rt300@4 350 s = temp.str();
rt300@4 351 ofDrawBitmapString( s, 10, line );
rt300@4 352 line+=20;
rt300@4 353 temp.str("");
rt300@4 354 }
rt300@4 355 }
rt300@4 356 //--------------------------------------------------------------
rt300@4 357 void Grid::update(){ // ?
rt300@4 358
rt300@4 359
rt300@4 360 }
rt300@5 361
rt300@4 362 //--------------------------------------------------------------
rt300@33 363
rt300@4 364 void Grid::move(TwoVector moveP){
rt300@4 365 // numspacing, pixelspacing stay the same
rt300@4 366
rt300@4 367 // convert pixels to surf units
rt300@4 368 TwoVector moveS;
rt300@4 369 moveS = moveP * scale;
rt300@4 370
rt300@4 371 topLeft = topLeft - moveS; // - because moving to the right means taking away from offset
rt300@4 372 centre = centre - moveS;
rt300@4 373
rt300@4 374 viewWasChanged();
rt300@5 375 eventLogger.logEvent(SCROLL, centre, scale);
rt300@4 376
rt300@4 377 }
rt300@4 378 //--------------------------------------------------------------
rt300@4 379 void Grid::zoom(float factor){
rt300@5 380 if(snapped)centre = (centre + snapCentre)*0.5; // clunky
rt300@5 381
rt300@4 382 if(maxZoom && factor > 1.0){
rt300@4 383 return;
rt300@4 384
rt300@4 385 }
rt300@4 386 if(factor < 1.0){
rt300@4 387 maxZoom = false;
rt300@4 388 }
rt300@4 389 if(minZoom && factor < 1.0){
rt300@4 390 return;
rt300@4 391
rt300@4 392 }
rt300@4 393 if(factor > 1.0){
rt300@4 394 minZoom = false;
rt300@4 395 }
rt300@4 396 scale = scale*factor; // simple eh?
rt300@4 397
rt300@4 398 // update view size using centre
rt300@4 399 // and scale...
rt300@4 400 size.x = size.x*factor; // zooming in, size gets SMALLER (view less)
rt300@4 401 size.y = size.y*factor;
rt300@4 402
rt300@4 403
rt300@4 404
rt300@4 405 viewWasChanged();
rt300@37 406 calculateInterpolateLevel();
rt300@5 407 eventLogger.logEvent(ZOOM, centre, scale);
rt300@4 408
rt300@5 409 }
rt300@5 410 //--------------------------------------------------------------
rt300@20 411 void Grid::shiftCentreToSnapped(){
rt300@20 412 // TODO just in case we're freezing something
rt300@20 413 // snapping actually change centre
rt300@20 414 centre = snapCentre;
rt300@20 415
rt300@20 416 }
rt300@20 417 //--------------------------------------------------------------
rt300@5 418 void Grid::snapCheck(){
rt300@5 419 // check environs for presets.
rt300@7 420
rt300@5 421 vector<Preset *> closePresets = presetManager.getPresetsInRange(centre - snapDist*scale, centre + snapDist*scale);
rt300@5 422 if(closePresets.size() > 0){
rt300@5 423 snapped = true;
rt300@5 424 // find closest
rt300@5 425 double dist, mindist = maxValue;
rt300@5 426 closestPreset = closePresets[0];
rt300@5 427
rt300@5 428 for(vector<Preset *>::iterator piter = closePresets.begin(); piter < closePresets.end(); piter++){
rt300@5 429 dist = (*piter)->coordinates.distanceTo(centre);
rt300@5 430
rt300@5 431 if(dist < mindist){
rt300@5 432 mindist = dist;
rt300@5 433 closestPreset = *piter;
rt300@5 434 }
rt300@5 435 }
rt300@5 436 snapCentre = closestPreset->coordinates;
rt300@22 437 eventLogger.logEvent(SNAPPED_TO_PRESET, getCoord(),closestPreset->creationTime );
rt300@35 438 //cout << "SNAPPED CHECK\n";
rt300@5 439 }else{
rt300@5 440 snapped = false;
rt300@7 441 closestPreset = NULL;
rt300@5 442 snapCentre = centre;
rt300@5 443 }
rt300@5 444
rt300@4 445
rt300@4 446 }
rt300@4 447 //--------------------------------------------------------------
rt300@5 448 void Grid::setMaxZoom(){ // got to smallest (white)
rt300@5 449 if(snapped)centre = snapCentre;
rt300@5 450 size.x = maxValue*2.0;
rt300@5 451 scale = size.x/pixSize.x;
rt300@5 452 size.y = scale * pixSize.y;
rt300@7 453 maxZoom = true;
rt300@7 454 minZoom = false;
rt300@5 455 viewWasChanged();
rt300@5 456 }
rt300@5 457 //--------------------------------------------------------------
rt300@5 458 void Grid::setMinZoom(){ // go to entire space (orange)
rt300@5 459 if(snapped)centre = snapCentre;
rt300@5 460 size.x = minValue*2.0;
rt300@5 461 scale = size.x/pixSize.x;
rt300@5 462 size.y = scale * pixSize.y;
rt300@7 463 minZoom = true;
rt300@7 464 maxZoom = false;
rt300@5 465 viewWasChanged();
rt300@4 466 }
rt300@4 467 //--------------------------------------------------------------
rt300@4 468 void Grid::viewWasChanged(){
rt300@5 469 snapCheck();
rt300@4 470 checkLimits();
rt300@5 471 // calculate new params?
rt300@5 472 vector<int> params;
rt300@5 473 if(snapped){
rt300@5 474 params = calculateParamsFromCoord(snapCentre);
rt300@5 475 }else{
rt300@37 476 if(interpolateMode == NO_INTERPOLATION){
rt300@37 477 params = calculateParamsFromCoord(centre);
rt300@37 478 }else if(interpolateMode == INTERPOLATE_GRID){
rt300@37 479 params = calculateInterpolatedParamsFromCoord(centre);
rt300@37 480 }
rt300@5 481 }
rt300@4 482 for(int i = 0;i<2*paramsPerDim;i++){
rt300@4 483 midiCC[i] = params[i];
rt300@4 484 }
rt300@4 485
rt300@4 486 }
rt300@4 487
rt300@4 488 //--------------------------------------------------------------
rt300@4 489 void Grid::checkLimits(){
rt300@4 490 // check for maximum zoom level
rt300@5 491
rt300@4 492
rt300@4 493 if(size.x > maxValue*2.0){
rt300@4 494 cout << "maxZoom\n";
rt300@4 495 maxZoom = true;
rt300@4 496 size.x = maxValue*2.0;
rt300@4 497 // need to also set y size back to
rt300@4 498 }
rt300@4 499 if(size.y > maxValue*2.0){
rt300@4 500 cout << "maxZoom\n";
rt300@4 501 maxZoom = true;
rt300@4 502 size.y = maxValue*2.0;
rt300@4 503 }
rt300@4 504
rt300@4 505 if(size.x < minValue){
rt300@4 506 cout << "min Zoom\n";
rt300@4 507 minZoom = true;
rt300@4 508 size.x = minValue;
rt300@4 509 // need to also set y size back to
rt300@4 510 }
rt300@4 511 if(size.y < minValue){
rt300@4 512 minZoom = true;
rt300@4 513 cout << "min Zoom\n";
rt300@4 514 size.y = minValue;
rt300@4 515 }
rt300@4 516
rt300@4 517 scale = size.x/pixSize.x;
rt300@4 518 size.y = scale * pixSize.y;
rt300@4 519
rt300@4 520 topLeft.x = centre.x - size.x/2;
rt300@4 521 topLeft.y = centre.y - size.y/2;
rt300@4 522 // check for negatives
rt300@4 523
rt300@4 524 // allow centre to be at limits
rt300@4 525 if((topLeft.x + size.x*0.5) < 0.0){
rt300@4 526 cout << "left Wall\n";
rt300@4 527 topLeft.x = 0.0 - size.x*0.5;
rt300@4 528 centre.x = 0.0;
rt300@4 529 }
rt300@4 530
rt300@4 531 if(topLeft.y + size.y*0.5 < 0.0) {
rt300@4 532 cout << "top Wall\n";
rt300@4 533 topLeft.y = 0.0 - size.y*0.5;
rt300@4 534 centre.y = 0.0;
rt300@4 535 }
rt300@4 536
rt300@4 537 // does topleft refer to lines or view?
rt300@4 538
rt300@4 539 // check max
rt300@4 540 if(topLeft.x + size.x/2 > maxValue){
rt300@4 541 cout << "right Wall\n";
rt300@4 542 topLeft.x = maxValue - size.x/2;
rt300@4 543 centre.x = maxValue;
rt300@4 544 }
rt300@4 545 if(topLeft.y + size.y/2 > maxValue) {
rt300@4 546 cout << "bottom Wall\n";
rt300@4 547 topLeft.y = maxValue - size.y/2;
rt300@4 548 centre.y = maxValue;
rt300@4 549 }
rt300@4 550
rt300@4 551 }
rt300@4 552 //--------------------------------------------------------------
rt300@4 553 void Grid::checkConsistencies(){
rt300@4 554 // debug function to check all the parameters are consistent maybe
rt300@4 555
rt300@4 556 }
rt300@4 557 //--------------------------------------------------------------
rt300@4 558 void Grid::setCoord(TwoVector coord){
rt300@4 559
rt300@4 560 centre = coord;
rt300@5 561
rt300@4 562 viewWasChanged();
rt300@4 563 }
rt300@4 564 //--------------------------------------------------------------
rt300@4 565 TwoVector Grid::getCoord(){
rt300@5 566 // return read point crosshairs
rt300@5 567 if(snapped){
rt300@5 568 return snapCentre;
rt300@5 569 }
rt300@4 570 return centre;
rt300@4 571 }
rt300@4 572 //--------------------------------------------------------------
rt300@4 573 vector<int> Grid::getParams(){
rt300@4 574 // return a vector with midiCCs in
rt300@4 575 // should we store params somewhere and use this as a low computation get ?
rt300@4 576 vector<int> params(2*paramsPerDim,0);
rt300@4 577 //
rt300@4 578 for(int i = 0;i<2*paramsPerDim;i++){
rt300@4 579 params[i] = midiCC[i];
rt300@4 580 }
rt300@4 581 return params;
rt300@4 582 }
rt300@4 583 //--------------------------------------------------------------
rt300@4 584 void Grid::setParams(vector<int> params){
rt300@4 585 // input midiCCs, and go to the appropriate coordinate
rt300@4 586
rt300@4 587 for(int i = 0;i<2*paramsPerDim;i++){
rt300@4 588 midiCC[i] = 64;
rt300@4 589 }
rt300@4 590 TwoVector coord = calculateCoordFromParams(params);
rt300@4 591 setCoord(coord);
rt300@4 592
rt300@20 593 // snapping?
rt300@4 594 viewWasChanged();
rt300@4 595
rt300@4 596 }
rt300@4 597 //--------------------------------------------------------------
rt300@5 598 //--------------------------------------------------------------
rt300@5 599 //--------------------------------------------------------------
rt300@5 600 //--------------------------------------------------------------
rt300@5 601 //--------------------------------------------------------------
rt300@5 602 #pragma mark const utils
rt300@5 603
rt300@37 604 TwoVector Grid::calculateCoordFromParams(vector<int> params){
rt300@4 605
rt300@4 606 vector<int> ccValueX(paramsPerDim);
rt300@4 607 vector<int> ccValueY(paramsPerDim);
rt300@4 608 for(int i=0;i<paramsPerDim;i++){
rt300@4 609 ccValueX[i] = params[i];
rt300@4 610 ccValueY[i] = params[i+paramsPerDim];
rt300@4 611 }
rt300@4 612
rt300@4 613 TwoVector result;
rt300@35 614 result.x = hilbert.calculateIndexFromParams(ccValueX);
rt300@35 615 result.y = hilbert.calculateIndexFromParams(ccValueY);
rt300@4 616 return result;
rt300@4 617 }
rt300@4 618
rt300@4 619 //--------------------------------------------------------------
rt300@37 620 vector<int> Grid::calculateParamsFromCoord(TwoVector coord){
rt300@35 621
rt300@4 622 if (coord.x > maxValue || coord.y > maxValue){
rt300@4 623 cout << "calculateParams Error: centre double value is too large" << "\n";
rt300@4 624 vector<int> empty;
rt300@4 625 return empty;
rt300@4 626 }
rt300@35 627 if (coord.x < 0 || coord.y < 0){
rt300@35 628 cout << "calculateParams Error: centre double value is negative" << "\n";
rt300@35 629 vector<int> empty;
rt300@35 630 return empty;
rt300@4 631 }
rt300@4 632
rt300@35 633 // X
rt300@35 634 vector<int> resultX;
rt300@35 635 resultX = hilbert.calculateParamsFromIndex(coord.x);
rt300@35 636 // Y
rt300@4 637 vector<int> resultY;
rt300@35 638 resultY = hilbert.calculateParamsFromIndex(coord.y);
rt300@4 639
rt300@4 640 // concatenate
rt300@35 641 vector<int> result = resultX;
rt300@35 642
rt300@4 643 result.insert( result.end(), resultY.begin(), resultY.end() );
rt300@4 644 return result;
rt300@4 645 }
rt300@37 646 //--------------------------------------------------------------
rt300@37 647 vector<int> Grid::calculateInterpolatedParamsFromCoord(TwoVector coord){
rt300@4 648
rt300@37 649 vector<int> result;
rt300@37 650 // round by masking according to interpLevel
rt300@37 651
rt300@37 652 long long x = coord.x;
rt300@37 653 long long y = coord.y;
rt300@37 654 cout << interpLevel << "\n";
rt300@37 655 int roundDigits = (paramsPerDim*interpLevel);
rt300@37 656 // knock off last digits
rt300@37 657 x = x >> roundDigits;
rt300@37 658 x = x << roundDigits;
rt300@37 659 float frac = (coord.x - x)/(1 << roundDigits);
rt300@37 660 long long xlower = x;
rt300@37 661 long long xupper = x + (1 << roundDigits);
rt300@37 662
rt300@37 663 vector<int> pupper = hilbert.calculateParamsFromIndex(xupper);
rt300@37 664 vector<int> plower = hilbert.calculateParamsFromIndex(xlower);
rt300@37 665
rt300@37 666 result = interpVector(pupper,plower,frac);
rt300@37 667 // now Y
rt300@37 668 y = y >> roundDigits;
rt300@37 669 y = y << roundDigits;
rt300@37 670 frac = (coord.y - y)/(1 << roundDigits);
rt300@37 671 long long ylower = y;
rt300@37 672 long long yupper = y + (1 << roundDigits);
rt300@37 673
rt300@37 674 pupper = hilbert.calculateParamsFromIndex(yupper);
rt300@37 675 plower = hilbert.calculateParamsFromIndex(ylower);
rt300@37 676
rt300@37 677 vector<int> resultY = interpVector(pupper,plower,frac);
rt300@37 678 // stickem together
rt300@37 679 result.insert( result.end(), resultY.begin(), resultY.end() );
rt300@37 680 return result;
rt300@37 681 }
rt300@37 682 //--------------------------------------------------------------
rt300@37 683 vector<int> Grid::interpVector(vector<int> upper, vector<int> lower, float frac){
rt300@37 684 vector<int> result;
rt300@37 685 if(upper.size() != lower.size()){
rt300@37 686 cout << "Error: interpVector takes vectors of same length" << "\n";
rt300@37 687 return result;
rt300@37 688 }
rt300@37 689 if(frac > 1){
rt300@37 690 cout << "Error: bad fraction for vector interpolation" << "\n";
rt300@37 691 return result;
rt300@37 692 }
rt300@37 693 int N = upper.size();
rt300@37 694 for(int i=0; i<N; i++){
rt300@37 695 result.push_back(frac*upper[i] + (1-frac)*lower[i]);
rt300@37 696 }
rt300@37 697 return result;
rt300@37 698 }
rt300@4 699 //--------------------------------------------------------------
rt300@4 700 vector<int> Grid::walkDiff(vector<bool> left, vector<bool> right){
rt300@4 701 // horrible
rt300@4 702 vector<int> result(2,0);
rt300@4 703
rt300@4 704 int size = left.size();
rt300@4 705 for(int i = 0; i < size; i++){
rt300@4 706 if(left[i] && !right[i]){ // 1 - 0
rt300@4 707 // dim
rt300@4 708 result[0] = i;
rt300@4 709 result[1] = 1;
rt300@4 710 }else if(!left[i] && right[i]){ // 0 - 1
rt300@4 711 result[0] = i;
rt300@4 712 result[1] = -1;
rt300@4 713 }else{ // equal do nothing
rt300@4 714
rt300@4 715
rt300@4 716 }
rt300@4 717 }
rt300@4 718
rt300@4 719 return result;
rt300@4 720 }
rt300@4 721 //--------------------------------------------------------------
rt300@4 722 //--------------------------------------------------------------
rt300@4 723 //--------------------------------------------------------------