rt300@0: // rt300@0: // grid.cpp rt300@0: // oscSenderExample rt300@0: // rt300@0: // Created by Robert Tubb on 03/10/2012. rt300@0: // rt300@0: // rt300@0: #include "ofMain.h" rt300@0: #include "grid.h" rt300@1: #include "eventLogger.h" rt300@0: rt300@0: #include rt300@0: rt300@0: //extern PresetManager presetManager; rt300@1: extern EventLogger eventLogger; rt300@0: //-------------------------------------------------------------- rt300@0: Grid::Grid(){ rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: Grid::~Grid(){ rt300@0: rt300@0: } rt300@0: void Grid::init(){ rt300@0: maxValue = pow(32.0,7.0)-1; rt300@0: minValue = 60; // number of 1-size divisions at smallest scale rt300@0: maxZoom = false; rt300@0: minZoom = false; rt300@0: paramsPerDim = 5; rt300@0: paramBitDepth = 7; rt300@0: codeLength = pow(2.0,paramsPerDim); rt300@0: rt300@0: pixSize.setCoord(ofGetWidth(), ofGetHeight()); rt300@0: rt300@0: //set scale and position to mid way rt300@0: scale = pow(32.0,6.0); rt300@0: rt300@0: rt300@0: size.setCoord(pixSize.x*scale, pixSize.y*scale); rt300@0: centre.setCoord(maxValue/2 , maxValue/2); rt300@0: topLeft.setCoord(centre.x - size.x/2, centre.y - size.y/2); rt300@0: rt300@0: rt300@0: makeCode(); rt300@0: rt300@0: // set a starting param value, find coord that does it. rt300@0: vector params(paramsPerDim*2); rt300@0: for(int i = 0;i<2*paramsPerDim;i++){ rt300@0: midiCC[i] = 64; rt300@0: params[i] = 64; rt300@0: } rt300@0: TwoVector coord = calculateCoordFromParams(params); rt300@0: setCoord(coord); rt300@0: rt300@0: viewWasChanged(); rt300@0: rt300@0: rt300@0: rt300@0: } rt300@0: rt300@0: template int sgn(T val) { rt300@0: return (T(0) < val) - (val < T(0)); rt300@0: } rt300@0: rt300@0: void Grid::makeCode(){ rt300@0: rt300@0: ////////////////////////////////~~~,,,,,,,,......... rt300@0: ////////// gray code generation rt300@0: ////// rt300@0: /// rt300@0: // TODO 5bit specific rt300@0: // transition sequence.... what a palaver! only need to do once though. rt300@0: 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: rt300@0: rt300@0: int code[codeLength][paramsPerDim]; // start with normal array rt300@0: rt300@0: rt300@0: rt300@0: for(int j=0; j()); rt300@0: rt300@0: for(int j=0; j >::iterator cit; rt300@0: //vector::iterator bit; rt300@0: vector::iterator bit; rt300@0: int i = 0; rt300@0: for(cit=vcode.begin(); cit!=vcode.end() ; cit++){ // fill vector rt300@0: i++; rt300@0: cout << i << " = "; rt300@0: bit = (*cit).begin(); rt300@0: for(bit=(*cit).begin(); bit!=(*cit).end() ; bit++){ rt300@0: rt300@0: cout << *bit; rt300@0: } rt300@0: cout << "\n"; rt300@0: rt300@0: } rt300@0: /* rt300@0: // codeToInt unit test rt300@0: vector aCode = vcode[12]; rt300@0: int result = grayToInt(aCode); rt300@0: cout << "GRAY TO INT : " << result << "\n"; rt300@0: rt300@0: cout << "-------------------------------\n"; rt300@0: rt300@0: // base32toFloat unit test rt300@0: rt300@0: vector test32 = coordTobase32(869437.0); rt300@0: double cresult = base32toCoord(test32); rt300@0: cout << "base32toCoord : " << cresult << "\n"; rt300@0: rt300@0: cout << "-------------------------------\n"; rt300@0: rt300@0: rt300@0: rt300@0: // midiToGray unit test rt300@0: rt300@0: vector > incodes(paramBitDepth, vector(paramsPerDim)); rt300@0: for(int i=0;i<7;i++){ rt300@0: incodes[i] = vcode[i+5]; rt300@0: } rt300@0: rt300@0: vector midiTest; rt300@0: midiTest = grayToMidi(incodes); rt300@0: vector > outcodes = midiToGray(midiTest); rt300@0: rt300@0: vector< vector >::iterator cit1; rt300@0: //vector::iterator bit; rt300@0: vector::iterator bit1; rt300@0: cout << "midiToGray Unit test\n"; rt300@0: for(int i=0;i checkParam; rt300@0: checkParam = calculateParamsFromCoord(inCoord); rt300@0: for(int i=0; i<2*paramsPerDim;i++){ rt300@0: cout << checkParam[i] << "_"; rt300@0: } rt300@0: TwoVector outCoord = calculateCoordFromParams(checkParam); rt300@0: cout << "Unit TEst coord = " << outCoord.x << "," << outCoord.y << "\n"; rt300@0: */ rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void Grid::draw(){ // draw lines rt300@0: // TODO too friggin long rt300@0: rt300@0: //scale++; rt300@0: // nice loopy thing rt300@0: int power = 0; rt300@0: rt300@0: // these get big! rt300@0: double divsr; rt300@0: double yl,xl; rt300@0: double gridSize = 0; rt300@0: rt300@0: double firstLineXPos, lastLineXPos,firstLineYPos, lastLineYPos, remleft, xoffset, yoffset = 0.0; rt300@0: double xstart, xfinish, ystart,yfinish; rt300@0: // these don't rt300@0: int xpos, ypos = 0; rt300@0: rt300@0: float alpha; rt300@0: bool done = false; rt300@0: float markpow = 32.0; // power that denotes next grid markings rt300@0: int lineWidth = 0; rt300@0: int colCycle = 0; rt300@0: rt300@0: // get all the preset points within this view rt300@0: //presetManager.getPresetsInRange(topLeft, topLeft+size); rt300@0: rt300@0: // loop thru powers of (base?) to determine which should be shown as grids rt300@0: while (!done){ rt300@0: gridSize = pow(markpow,power); rt300@0: rt300@0: colCycle = power % 7; rt300@0: rt300@0: divsr = size.x / gridSize; rt300@0: rt300@0: // if (divisor i.e. number of lines is less than 1000 rt300@0: if( divsr >= 1 && divsr < 1000){ rt300@0: rt300@0: // calculate transparency rt300@0: float visCont = log10(divsr); // 0 if only 1 line, 3 if 1000 lines rt300@0: alpha = 90*(3 - visCont); rt300@0: ofSetLineWidth(lineWidth); rt300@0: rt300@0: // cycle colors for different scales rt300@0: if(colCycle == 0){ rt300@0: ofSetColor(255,255,255,alpha); rt300@0: }else if(colCycle == 1){ rt300@0: ofSetColor(255,0,0,alpha); rt300@0: }else if(colCycle == 2){ rt300@0: ofSetColor(0,0,255,alpha); rt300@0: }else if(colCycle == 3){ rt300@0: ofSetColor(0,255,0,alpha); rt300@0: }else if(colCycle == 4){ rt300@0: ofSetColor(255,0,255,alpha); rt300@0: }else if(colCycle == 5){ rt300@0: ofSetColor(0,255,255,alpha); rt300@0: }else if(colCycle == 6){ rt300@0: ofSetColor(255,255,0,alpha); rt300@0: }else if(colCycle == 7){ rt300@0: ofSetColor(255,255,255,alpha); rt300@0: }else{ rt300@0: cout << "err colour messed up\n"; rt300@0: } rt300@0: rt300@0: rt300@0: // draw level numbers associated with each color. This would not be true if markpow wasnt 2^d rt300@0: ////////-------///////// rt300@0: /* rt300@0: temp << "THIS LEVEL = " << (int)pow(2.0,power) << " "; rt300@0: string s = temp.str(); rt300@0: ofDrawBitmapString( s, 10, line ); rt300@0: line+=30; rt300@0: temp.str(""); rt300@0: *////////-------///////// rt300@0: rt300@0: // draw presets at this level rt300@0: // fill in smallest squares if they contain a preset rt300@0: // how to do this efficiently? rt300@0: rt300@0: rt300@0: if(topLeft.x < 0.0){ rt300@0: firstLineXPos = 0.0; rt300@0: xoffset = firstLineXPos - topLeft.x; rt300@0: xstart = xoffset/scale; rt300@0: }else{ rt300@0: firstLineXPos = topLeft.x; rt300@0: // kinda float version of % operator rt300@0: remleft = ceil(firstLineXPos/gridSize); rt300@0: xoffset = (remleft * gridSize) - topLeft.x; rt300@0: xstart = 0; rt300@0: } rt300@0: if(topLeft.x + size.x > maxValue){ rt300@0: lastLineXPos = maxValue+1 - topLeft.x; rt300@0: rt300@0: rt300@0: }else{ rt300@0: lastLineXPos = size.x; rt300@0: rt300@0: } rt300@0: xfinish = lastLineXPos/scale; rt300@0: rt300@0: //////////------------------------ rt300@0: // same for y rt300@0: rt300@0: if(topLeft.y < 0.0){ rt300@0: firstLineYPos = 0.0; rt300@0: yoffset = firstLineYPos - topLeft.y; rt300@0: ystart = yoffset/scale; rt300@0: }else{ rt300@0: firstLineYPos = topLeft.y; rt300@0: // kinda float version of % operator rt300@0: remleft = ceil(firstLineYPos/gridSize); rt300@0: yoffset = (remleft * gridSize) - topLeft.y; rt300@0: ystart = 0; rt300@0: } rt300@0: if(topLeft.y + size.y > maxValue){ rt300@0: lastLineYPos = maxValue+1 - topLeft.y; rt300@0: rt300@0: }else{ rt300@0: lastLineYPos = size.y; rt300@0: rt300@0: } rt300@0: yfinish = lastLineYPos/scale; rt300@0: // ------------------------------------------- rt300@0: // now draw rt300@0: for(xl = xoffset; xl <= (lastLineXPos); xl+= gridSize){ rt300@0: rt300@0: xpos = xl/scale; rt300@0: ofLine(xpos, ystart, xpos, yfinish); rt300@0: rt300@0: } rt300@0: rt300@0: for(yl = yoffset; yl <= (lastLineYPos); yl+= gridSize){ rt300@0: rt300@0: ypos = yl/scale; rt300@0: ofLine(xstart, ypos, xfinish, ypos); rt300@0: } rt300@0: rt300@0: rt300@0: }else if (divsr < 1){ rt300@0: // ignore... rt300@0: done = true; rt300@0: } rt300@0: rt300@0: power++; rt300@0: } rt300@0: //cout << "draw done" << "\n"; rt300@0: //displayInfo(); rt300@0: rt300@0: ////////-------///////// rt300@0: rt300@0: ////////-------///////// rt300@0: rt300@0: // draw centre cross hairs rt300@0: ofSetColor(255, 0, 0); rt300@0: ofNoFill(); rt300@0: ofLine(pixSize.x/2-20, pixSize.y/2, pixSize.x/2+20, pixSize.y/2); rt300@0: ofLine(pixSize.x/2, pixSize.y/2-20, pixSize.x/2, pixSize.y/2+20); rt300@0: ofEllipse(pixSize.x/2, pixSize.y/2, 20, 20); rt300@0: ofFill(); rt300@0: ////////-------//////// rt300@0: /* rt300@0: ostringstream temp; rt300@0: temp << "Centre x = " << centre.x << "\n y = " << centre.y << " "; rt300@0: string s = temp.str(); rt300@0: ofDrawBitmapString( s, pixSize.x/2+10, pixSize.y/2+10 ); rt300@0: */ rt300@0: } rt300@0: //----------------------------------------------------------------------- rt300@0: void Grid::displayInfo(){ rt300@0: rt300@0: // display some "useful information" rt300@0: rt300@0: ofSetColor(255,255,255,255); rt300@0: rt300@0: ostringstream temp; rt300@0: int line = 10; // text output pos rt300@0: rt300@0: rt300@0: ////////-------///////// rt300@0: temp << "scale = " << scale << " "; rt300@0: string s = temp.str(); rt300@0: ofDrawBitmapString( s, 10, line ); rt300@0: line+=30; rt300@0: temp.str(""); rt300@0: ////////-------///////// rt300@0: temp << "Top Left = " << topLeft.x << "," << topLeft.y << " "; rt300@0: s = temp.str(); rt300@0: ofDrawBitmapString( s, 10, line ); rt300@0: line+=60; rt300@0: temp.str(""); rt300@0: rt300@0: ////////-------///////// rt300@0: temp << "View Size = " << size.x << "," << size.y << " "; rt300@0: s = temp.str(); rt300@0: ofDrawBitmapString( s, 10, line ); rt300@0: line+=60; rt300@0: temp.str(""); rt300@0: rt300@0: ////////-------///////// rt300@0: rt300@0: for(int i=0;i<10;i++){ // TODO 5bit specific rt300@0: temp << midiCC[i] << " "; rt300@0: s = temp.str(); rt300@0: ofDrawBitmapString( s, 10, line ); rt300@0: line+=20; rt300@0: temp.str(""); rt300@0: } rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void Grid::update(){ // ? rt300@0: // "update" bit of a crap name - all we do here is calculate the dimension params from the x,y position rt300@0: rt300@0: vector params = calculateParamsFromCoord(centre); rt300@0: for(int i = 0;i<2*paramsPerDim;i++){ rt300@0: midiCC[i] = params[i]; rt300@0: } rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void Grid::move(int moveX, int moveY){ rt300@0: // numspacing, pixelspacing stay the same rt300@0: rt300@0: // convert pixels to surf units rt300@0: TwoVector moveS; rt300@0: moveS.setCoord(moveX * scale, moveY * scale); rt300@0: rt300@0: topLeft = topLeft - moveS; // - because moving to the right means taking away from offset rt300@0: centre = centre - moveS; rt300@1: eventLogger.logEvent(-1, centre, scale); rt300@0: viewWasChanged(); rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void Grid::zoom(float factor){ rt300@0: if(maxZoom && factor > 1.0){ rt300@0: return; rt300@0: rt300@0: } rt300@0: if(factor < 1.0){ rt300@0: maxZoom = false; rt300@0: } rt300@0: if(minZoom && factor < 1.0){ rt300@0: return; rt300@0: rt300@0: } rt300@0: if(factor > 1.0){ rt300@0: minZoom = false; rt300@0: } rt300@0: scale = scale*factor; // simple eh? rt300@0: rt300@0: // update view size using centre rt300@0: // and scale... rt300@0: size.x = size.x*factor; // zooming in, size gets SMALLER (view less) rt300@0: size.y = size.y*factor; rt300@0: rt300@1: rt300@1: eventLogger.logEvent(-2, centre, scale); rt300@0: viewWasChanged(); rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void Grid::viewWasChanged(){ rt300@0: checkLimits(); rt300@0: // and calculate new params? rt300@0: rt300@0: rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: void Grid::checkLimits(){ rt300@0: // check for maximum zoom level rt300@0: // TODO: DODGY rt300@0: rt300@0: if(size.x > maxValue*2.0){ rt300@0: cout << "maxZoom\n"; rt300@0: maxZoom = true; rt300@0: size.x = maxValue*2.0; rt300@0: // need to also set y size back to rt300@0: } rt300@0: if(size.y > maxValue*2.0){ rt300@0: cout << "maxZoom\n"; rt300@0: maxZoom = true; rt300@0: size.y = maxValue*2.0; rt300@0: } rt300@0: rt300@0: if(size.x < minValue){ rt300@0: cout << "min Zoom\n"; rt300@0: minZoom = true; rt300@0: size.x = minValue; rt300@0: // need to also set y size back to rt300@0: } rt300@0: if(size.y < minValue){ rt300@0: minZoom = true; rt300@0: cout << "min Zoom\n"; rt300@0: size.y = minValue; rt300@0: } rt300@0: rt300@0: scale = size.x/pixSize.x; rt300@0: size.y = scale * pixSize.y; rt300@0: rt300@0: topLeft.x = centre.x - size.x/2; rt300@0: topLeft.y = centre.y - size.y/2; rt300@0: // check for negatives rt300@0: rt300@0: // allow centre to be at limits rt300@0: if((topLeft.x + size.x*0.5) < 0.0){ rt300@0: cout << "left Wall\n"; rt300@0: topLeft.x = 0.0 - size.x*0.5; rt300@0: centre.x = 0.0; rt300@0: } rt300@0: rt300@0: if(topLeft.y + size.y*0.5 < 0.0) { rt300@0: cout << "top Wall\n"; rt300@0: topLeft.y = 0.0 - size.y*0.5; rt300@0: centre.y = 0.0; rt300@0: } rt300@0: rt300@0: // does topleft refer to lines or view? rt300@0: rt300@0: // check max rt300@0: if(topLeft.x + size.x/2 > maxValue){ rt300@0: cout << "right Wall\n"; rt300@0: topLeft.x = maxValue - size.x/2; rt300@0: centre.x = maxValue; rt300@0: } rt300@0: if(topLeft.y + size.y/2 > maxValue) { rt300@0: cout << "bottom Wall\n"; rt300@0: topLeft.y = maxValue - size.y/2; rt300@0: centre.y = maxValue; rt300@0: } rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void Grid::checkConsistencies(){ rt300@0: // debug function to check all the parameters are consistent maybe rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void Grid::setCoord(TwoVector coord){ rt300@0: rt300@0: centre = coord; rt300@0: viewWasChanged(); rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: TwoVector Grid::getCoord(){ rt300@0: rt300@0: return centre; rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: vector Grid::getParams(){ rt300@0: // return a vector with midiCCs in rt300@0: // should we store params somewhere and use this as a low computation get ? rt300@0: vector params(2*paramsPerDim,0); rt300@0: // rt300@0: for(int i = 0;i<2*paramsPerDim;i++){ rt300@0: params[i] = midiCC[i]; rt300@0: } rt300@0: return params; rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: void Grid::setParams(vector params){ rt300@0: // input midiCCs, and go to the appropriate coordinate rt300@0: rt300@0: for(int i = 0;i<2*paramsPerDim;i++){ rt300@0: midiCC[i] = 64; rt300@0: } rt300@0: TwoVector coord = calculateCoordFromParams(params); rt300@0: setCoord(coord); rt300@0: rt300@0: viewWasChanged(); rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: TwoVector Grid::calculateCoordFromParams(vector params){ rt300@0: rt300@0: vector ccValueX(paramsPerDim); rt300@0: vector ccValueY(paramsPerDim); rt300@0: for(int i=0;i > codesX = midiToGray(ccValueX); rt300@0: vector > codesY = midiToGray(ccValueY); rt300@0: rt300@0: vector base32X = codesToBase32(codesX); rt300@0: vector base32Y = codesToBase32(codesY); rt300@0: rt300@0: TwoVector result; rt300@0: result.x = base32toCoord(base32X); rt300@0: result.y = base32toCoord(base32Y); rt300@0: return result; rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: vector Grid::calculateParamsFromCoord(TwoVector coord){ rt300@0: // some arrays in reverse order of power from normal numbers! 1,2,4, rt300@0: rt300@0: // centre to base 32 rt300@0: if (coord.x > maxValue || coord.y > maxValue){ rt300@0: cout << "calculateParams Error: centre double value is too large" << "\n"; rt300@0: vector empty; rt300@0: return empty; rt300@0: } rt300@0: rt300@0: //-------------------------- rt300@0: // X rt300@0: vector base32x = coordTobase32(coord.x); // 7 numbers from 0 to 31 rt300@0: vector > grayCodesX; rt300@0: rt300@0: int size = base32x.size(); rt300@0: for(int i=0;i result; rt300@0: result = grayToMidi(grayCodesX); rt300@0: //-------------------------- rt300@0: // AND FOR Y rt300@0: vector base32y = coordTobase32(coord.y); rt300@0: vector > grayCodesY; rt300@0: rt300@0: size = base32y.size(); rt300@0: for(int i=0;i resultY; rt300@0: resultY = grayToMidi(grayCodesY); rt300@0: rt300@0: // concatenate rt300@0: result.insert( result.end(), resultY.begin(), resultY.end() ); rt300@0: return result; rt300@0: } rt300@0: //------------------------------------------------------------------- rt300@0: rt300@0: // for 1 dimension!!! i.e. call this twice rt300@0: vector Grid::grayToMidi(vector > grayCodes){ rt300@0: rt300@0: // gray to midi CC values rt300@0: // loop thru the scales to build up a CC number per dimension rt300@0: int midiCCresult[paramsPerDim]; // TODO dims specific rt300@0: for(int i=0;i >::iterator piter = grayCodes.begin(); rt300@0: for(;piter < grayCodes.end();piter++){ // each lesser power of 2 rt300@0: midP = 0; // reset rt300@0: vector::iterator diter = (*piter).begin(); rt300@0: for(; diter <= (*piter).end();diter++){ // each one is different dimension rt300@0: int ig = int(*diter); // convert binary to int rt300@0: //cout << "ig: " << ig; rt300@0: midiCCresult[midP] += ig*bin; // mult by power of two rt300@0: midP++; rt300@0: } rt300@0: bin = bin >> 1; // next power of 2 down rt300@0: rt300@0: } rt300@0: rt300@0: // put in vector rt300@0: vector result; rt300@0: for(int i=0;i Grid::intToGray(int num, int dimToTravel){ rt300@0: rt300@0: // dimToTravel - this is the dimension that we want the walk to traverse, i.e. the last non zero digit of the code rt300@0: // so swap it for 3 to produce correct orientation rt300@0: rt300@0: // just use look up table... until it gets huuuge. rt300@0: vector grayCode = vcode[num]; rt300@0: grayCode[3] = vcode[num][dimToTravel]; rt300@0: grayCode[dimToTravel] = vcode[num][3]; rt300@0: return grayCode; rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: vector Grid::walkDiff(vector left, vector right){ rt300@0: // horrible rt300@0: vector result(2,0); rt300@0: rt300@0: int size = left.size(); rt300@0: for(int i = 0; i < size; i++){ rt300@0: if(left[i] && !right[i]){ // 1 - 0 rt300@0: // dim rt300@0: result[0] = i; rt300@0: result[1] = 1; rt300@0: }else if(!left[i] && right[i]){ // 0 - 1 rt300@0: result[0] = i; rt300@0: result[1] = -1; rt300@0: }else{ // equal do nothing rt300@0: rt300@0: rt300@0: } rt300@0: } rt300@0: rt300@0: return result; rt300@0: } rt300@0: rt300@0: //-------------------------------------------------------------- rt300@0: /* rt300@0: breaks down float into a base 32 number (2^D) rt300@0: each of these is converted to gray code rt300@0: this is then converted to 10 parameters, where each 32-digit becomes separate power of 2 rt300@0: 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: */ rt300@0: vector Grid::coordTobase32(double value){ rt300@0: //double base = 32.0; rt300@0: if(value < 0.0){ rt300@0: cout << "coordTobase32 error: input value is negative\n"; rt300@0: value = 0.0; rt300@0: }else if(value > maxValue){ rt300@0: cout << "coordTobase32 error: input value too big!\n"; rt300@0: } rt300@0: double rem, divdr = 0.0; rt300@0: int digit32; rt300@0: rt300@0: // what power of 32 to start at? rt300@0: int maxpow = 7; // midi cc specific rt300@0: vector result; rt300@0: rt300@0: rem = value; rt300@0: for(;maxpow >=0;maxpow--){ rt300@0: // repeatedly get digit and remainder. This is exactly what we're doing in draw !?... could put all this in one place? rt300@0: divdr = pow((double)codeLength,(double)maxpow); rt300@0: digit32 = floor(rem/divdr); rt300@0: rem = rem - digit32*divdr; rt300@0: result.push_back(digit32); // array, biggest index is smallest power rt300@0: } rt300@0: // at this point rem should be fractional... use for interp? rt300@0: rt300@0: return result; rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: rt300@0: // WHY HERE XCODE? rt300@0: vector Grid::codesToBase32(vector > inCodes){ rt300@0: vector result; rt300@0: for(int i=0;i incode){ rt300@0: // look for match in table rt300@0: rt300@0: int s = vcode.size(); rt300@0: rt300@0: for(int i=0; i base32Digs){ rt300@0: // build up the big float from a base 32 number rt300@0: double result = 0.0; rt300@0: rt300@0: // what power of 32 to start at? rt300@0: int mpow = base32Digs.size() - 1; // should be 7... rt300@0: rt300@0: for(int p=0;p<=mpow;p++){ // biggest index is smallest power rt300@0: result += ((double)base32Digs[p]) * pow(32.0, (double)mpow-p); rt300@0: rt300@0: } rt300@0: return result; rt300@0: rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: // for 1 dimension - takes in 5 cc params and outputs 7 codes rt300@0: vector > Grid::midiToGray(vector ccValue){ rt300@0: int pow2 = 1 << (paramBitDepth-1); rt300@0: rt300@0: vector aCode(paramsPerDim); rt300@0: vector > theXCodes(paramBitDepth,aCode); rt300@0: rt300@0: // build up binary gray code representations from the bits of the midi ccs rt300@0: rt300@0: vector > theCodes(paramBitDepth, vector(paramsPerDim)); rt300@0: rt300@0: // x rt300@0: for(int p=0;p> 1; rt300@0: rt300@0: } rt300@0: return theCodes; rt300@0: } rt300@0: //-------------------------------------------------------------- rt300@0: //-------------------------------------------------------------- rt300@0: //--------------------------------------------------------------