rt300@4: // rt300@4: // grid.cpp rt300@4: // oscSenderExample rt300@4: // rt300@4: // Created by Robert Tubb on 03/10/2012. rt300@4: // rt300@37: // This is the grid view, i.e. the viewable representation of hilbert surface rt300@4: rt300@4: #include "grid.h" rt300@4: rt300@4: rt300@4: #include rt300@4: rt300@4: extern PresetManager presetManager; rt300@4: extern EventLogger eventLogger; rt300@34: extern Hilbert hilbert; rt300@4: //-------------------------------------------------------------- rt300@35: Grid::Grid(): maxValue(pow(32.0,7.0)-1), minValue(30), paramsPerDim(5), paramBitDepth(7){ rt300@4: rt300@37: interpLevel = 4; rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: //-------------------------------------------------------------- rt300@4: Grid::~Grid(){ rt300@4: rt300@4: } rt300@4: void Grid::init(){ rt300@34: rt300@37: interpolateMode = INTERPOLATE_GRID; rt300@37: rt300@4: maxZoom = false; rt300@4: minZoom = false; rt300@4: rt300@4: pixSize.setCoord(ofGetWidth(), ofGetHeight()); rt300@4: rt300@35: //set scale and position to random rt300@27: scale = 15500.0; rt300@35: rt300@37: smallestGridSpacing = 3; //pixels rt300@37: rt300@8: snapDist = TwoVector(9,9); rt300@5: snapped = false; rt300@4: rt300@4: size.setCoord(pixSize.x*scale, pixSize.y*scale); rt300@4: centre.setCoord(maxValue/2 , maxValue/2); rt300@4: topLeft.setCoord(centre.x - size.x/2, centre.y - size.y/2); rt300@34: rt300@34: hilbert.init(paramBitDepth, paramsPerDim); rt300@4: rt300@4: // set a starting param value, find coord that does it. rt300@4: vector params(paramsPerDim*2); rt300@4: for(int i = 0;i<2*paramsPerDim;i++){ rt300@4: midiCC[i] = 12; rt300@4: params[i] = 12; rt300@4: } rt300@35: rt300@35: rt300@4: TwoVector coord = calculateCoordFromParams(params); rt300@4: setCoord(coord); rt300@4: rt300@4: viewWasChanged(); rt300@37: calculateInterpolateLevel(); rt300@4: } rt300@4: rt300@4: template int sgn(T val) { rt300@4: return (T(0) < val) - (val < T(0)); rt300@4: } rt300@37: //-------------------------------------------------------------- rt300@37: int Grid::calculateInterpolateLevel(){ rt300@37: if(interpolateMode == INTERPOLATE_GRID){ rt300@37: // calculate according to smallest gridlines rt300@37: // exactly same algorithm as for drawing lines rt300@37: // i.e. kinda duplicated code. rt300@37: float markpow = pow(paramsPerDim,2.0); rt300@37: for(int p = 0; p < paramBitDepth; p++){ rt300@37: rt300@37: double gridSize = pow(markpow,p); rt300@37: double divsr = size.x / gridSize; rt300@37: rt300@37: // return the spacing rt300@37: if( ofGetWidth()/divsr >= smallestGridSpacing){ rt300@37: interpLevel = p; rt300@37: return p; rt300@37: } rt300@37: } rt300@37: interpLevel = 0; rt300@37: return 0; rt300@37: }else{ rt300@37: interpLevel = 0; rt300@37: return 0; // ??? rt300@37: } rt300@37: } rt300@37: //-------------------------------------------------------------- rt300@4: rt300@37: void Grid::draw(){ rt300@37: if(interpolateMode == NO_INTERPOLATION){ rt300@37: drawGridLines(); rt300@37: drawPresets(); rt300@37: }else if(interpolateMode == INTERPOLATE_GRID){ rt300@37: // calculate according to smallest gridlines rt300@37: drawGridLines(); rt300@37: rt300@37: }else if(interpolateMode == INTERPOLATE_PRESET){ rt300@37: drawPresets(); rt300@37: return; // ??? rt300@37: } rt300@37: rt300@37: rt300@37: rt300@37: // draw centre cross hairs rt300@37: drawCrossHairs(); rt300@37: rt300@37: rt300@37: // draw the undo history trail, given viewing area rt300@37: eventLogger.drawTrail(topLeft, topLeft + size); rt300@37: } rt300@4: //-------------------------------------------------------------- rt300@37: void Grid::drawGridLines(){ // draw lines rt300@4: // TODO too friggin long rt300@4: rt300@16: pixSize.setCoord(ofGetWidth(), ofGetHeight()); // incase of rotation? rt300@37: rt300@4: int power = 0; rt300@4: rt300@4: // these get big! rt300@4: double divsr; rt300@4: double yl,xl; rt300@4: double gridSize = 0; rt300@4: rt300@4: double firstLineXPos, lastLineXPos,firstLineYPos, lastLineYPos, remleft, xoffset, yoffset = 0.0; rt300@4: double xstart, xfinish, ystart,yfinish; rt300@4: // these don't rt300@4: int xpos, ypos = 0; rt300@4: rt300@4: float alpha; rt300@4: bool done = false; rt300@37: float markpow = 1 << paramsPerDim; // power that denotes next grid markings e.g. 32 rt300@4: int lineWidth = 0; rt300@4: int colCycle = 0; rt300@4: rt300@4: rt300@37: // loop thru powers of (base?) smallest to biggest rt300@37: // to determine which should be shown as grids rt300@4: while (!done){ rt300@4: gridSize = pow(markpow,power); rt300@4: rt300@37: colCycle = power % paramBitDepth; rt300@4: rt300@4: divsr = size.x / gridSize; rt300@4: rt300@4: // if (divisor i.e. number of lines is less than 1000 rt300@37: if( ofGetWidth()/divsr >= smallestGridSpacing){ rt300@4: rt300@4: // calculate transparency rt300@37: float visCont = log10(divsr*2); // 0 if only 1 line, 3 if 1000 lines rt300@4: alpha = 90*(3 - visCont); rt300@4: ofSetLineWidth(lineWidth); rt300@4: rt300@4: // cycle colors for different scales rt300@4: if(colCycle == 0){ rt300@4: ofSetColor(255,255,255,alpha); rt300@4: }else if(colCycle == 1){ rt300@4: ofSetColor(255,0,0,alpha); rt300@4: }else if(colCycle == 2){ rt300@4: ofSetColor(0,0,255,alpha); rt300@4: }else if(colCycle == 3){ rt300@4: ofSetColor(0,255,0,alpha); rt300@4: }else if(colCycle == 4){ rt300@4: ofSetColor(255,0,255,alpha); rt300@4: }else if(colCycle == 5){ rt300@4: ofSetColor(0,255,255,alpha); rt300@4: }else if(colCycle == 6){ rt300@4: ofSetColor(255,255,0,alpha); rt300@4: }else if(colCycle == 7){ rt300@4: ofSetColor(255,255,255,alpha); rt300@4: }else{ rt300@4: cout << "err colour messed up\n"; rt300@4: } rt300@4: rt300@4: rt300@4: // draw level numbers associated with each color. This would not be true if markpow wasnt 2^d rt300@4: ////////-------///////// rt300@4: /* rt300@4: temp << "THIS LEVEL = " << (int)pow(2.0,power) << " "; rt300@4: string s = temp.str(); rt300@4: ofDrawBitmapString( s, 10, line ); rt300@4: line+=30; rt300@4: temp.str(""); rt300@4: *////////-------///////// rt300@4: rt300@4: // draw presets at this level rt300@4: // fill in smallest squares if they contain a preset rt300@4: // how to do this efficiently? rt300@4: rt300@4: rt300@4: if(topLeft.x < 0.0){ rt300@4: firstLineXPos = 0.0; rt300@4: xoffset = firstLineXPos - topLeft.x; rt300@4: xstart = xoffset/scale; rt300@4: }else{ rt300@4: firstLineXPos = topLeft.x; rt300@4: // kinda float version of % operator rt300@4: remleft = ceil(firstLineXPos/gridSize); rt300@4: xoffset = (remleft * gridSize) - topLeft.x; rt300@4: xstart = 0; rt300@4: } rt300@4: if(topLeft.x + size.x > maxValue){ rt300@4: lastLineXPos = maxValue+1 - topLeft.x; rt300@4: rt300@4: rt300@4: }else{ rt300@4: lastLineXPos = size.x; rt300@4: rt300@4: } rt300@4: xfinish = lastLineXPos/scale; rt300@4: rt300@4: //////////------------------------ rt300@4: // same for y rt300@4: rt300@4: if(topLeft.y < 0.0){ rt300@4: firstLineYPos = 0.0; rt300@4: yoffset = firstLineYPos - topLeft.y; rt300@4: ystart = yoffset/scale; rt300@4: }else{ rt300@4: firstLineYPos = topLeft.y; rt300@4: // kinda float version of % operator rt300@4: remleft = ceil(firstLineYPos/gridSize); rt300@4: yoffset = (remleft * gridSize) - topLeft.y; rt300@4: ystart = 0; rt300@4: } rt300@4: if(topLeft.y + size.y > maxValue){ rt300@4: lastLineYPos = maxValue+1 - topLeft.y; rt300@4: rt300@4: }else{ rt300@4: lastLineYPos = size.y; rt300@4: rt300@4: } rt300@4: yfinish = lastLineYPos/scale; rt300@4: // ------------------------------------------- rt300@4: // now draw rt300@4: for(xl = xoffset; xl <= (lastLineXPos); xl+= gridSize){ rt300@4: rt300@4: xpos = xl/scale; rt300@4: ofLine(xpos, ystart, xpos, yfinish); rt300@4: rt300@4: } rt300@4: rt300@4: for(yl = yoffset; yl <= (lastLineYPos); yl+= gridSize){ rt300@4: rt300@4: ypos = yl/scale; rt300@4: ofLine(xstart, ypos, xfinish, ypos); rt300@4: } rt300@4: rt300@4: rt300@37: } rt300@37: /*else if (divsr < 1){ rt300@37: // maximum only one line. worth checking so that bigger lines still show up? rt300@4: done = true; rt300@4: } rt300@37: */ rt300@4: power++; rt300@37: if(power > paramBitDepth) rt300@37: done = true; rt300@37: rt300@4: } rt300@4: //cout << "draw done" << "\n"; rt300@4: //displayInfo(); rt300@4: rt300@33: rt300@33: rt300@4: ////////-------//////// rt300@4: /* rt300@4: ostringstream temp; rt300@4: temp << "Centre x = " << centre.x << "\n y = " << centre.y << " "; rt300@4: string s = temp.str(); rt300@4: ofDrawBitmapString( s, pixSize.x/2+10, pixSize.y/2+10 ); rt300@4: */ rt300@4: } rt300@5: //----------------------------------------------------------------------- rt300@5: void Grid::drawCrossHairs(){ rt300@5: // snapping rt300@5: TwoVector pos; rt300@5: if(snapped){ rt300@5: pos = coordToPixel(snapCentre); rt300@5: }else{ rt300@5: pos = coordToPixel(centre); rt300@5: rt300@5: } rt300@5: ofSetColor(255, 0, 0); rt300@5: ofNoFill(); rt300@5: ofLine(pos.x-20, pos.y, pos.x+20, pos.y); rt300@5: ofLine(pos.x, pos.y-20, pos.x, pos.y+20); rt300@5: ofEllipse(pos.x, pos.y, 20, 20); rt300@5: ofFill(); rt300@5: } rt300@5: //----------------------------------------------------------------------- rt300@4: TwoVector Grid::coordToPixel(TwoVector coord){ rt300@4: TwoVector pix; rt300@4: pix.x = (coord.x - topLeft.x)/scale; rt300@4: pix.y = (coord.y - topLeft.y)/scale; rt300@4: return pix; rt300@4: rt300@4: } rt300@4: rt300@4: //----------------------------------------------------------------------- rt300@4: void Grid::drawPresets(){ rt300@5: presetManager.drawPresetsInRange(topLeft, topLeft + size); rt300@7: // draw snapped preset info rt300@7: if(snapped && closestPreset != NULL){ rt300@8: ofDrawBitmapString( closestPreset->displayTextDescription(), pixSize.x/2+10, pixSize.y/2+10 ); rt300@7: } rt300@33: rt300@4: } rt300@4: rt300@4: //----------------------------------------------------------------------- rt300@4: void Grid::displayInfo(){ rt300@4: rt300@4: // display some "useful information" rt300@4: rt300@4: ofSetColor(255,255,255,255); rt300@4: rt300@4: ostringstream temp; rt300@4: int line = 10; // text output pos rt300@4: rt300@4: rt300@4: ////////-------///////// rt300@4: temp << "scale = " << scale << " "; rt300@4: string s = temp.str(); rt300@4: ofDrawBitmapString( s, 10, line ); rt300@4: line+=30; rt300@4: temp.str(""); rt300@4: ////////-------///////// rt300@4: temp << "Top Left = " << topLeft.x << "," << topLeft.y << " "; rt300@4: s = temp.str(); rt300@4: ofDrawBitmapString( s, 10, line ); rt300@4: line+=60; rt300@4: temp.str(""); rt300@4: rt300@4: ////////-------///////// rt300@4: temp << "View Size = " << size.x << "," << size.y << " "; rt300@4: s = temp.str(); rt300@4: ofDrawBitmapString( s, 10, line ); rt300@4: line+=60; rt300@4: temp.str(""); rt300@4: rt300@4: ////////-------///////// rt300@4: rt300@4: for(int i=0;i<10;i++){ // TODO 5bit specific rt300@4: temp << midiCC[i] << " "; rt300@4: s = temp.str(); rt300@4: ofDrawBitmapString( s, 10, line ); rt300@4: line+=20; rt300@4: temp.str(""); rt300@4: } rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: void Grid::update(){ // ? rt300@4: rt300@4: rt300@4: } rt300@5: rt300@4: //-------------------------------------------------------------- rt300@33: rt300@4: void Grid::move(TwoVector moveP){ rt300@4: // numspacing, pixelspacing stay the same rt300@4: rt300@4: // convert pixels to surf units rt300@4: TwoVector moveS; rt300@4: moveS = moveP * scale; rt300@4: rt300@4: topLeft = topLeft - moveS; // - because moving to the right means taking away from offset rt300@4: centre = centre - moveS; rt300@4: rt300@4: viewWasChanged(); rt300@5: eventLogger.logEvent(SCROLL, centre, scale); rt300@4: rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: void Grid::zoom(float factor){ rt300@5: if(snapped)centre = (centre + snapCentre)*0.5; // clunky rt300@5: rt300@4: if(maxZoom && factor > 1.0){ rt300@4: return; rt300@4: rt300@4: } rt300@4: if(factor < 1.0){ rt300@4: maxZoom = false; rt300@4: } rt300@4: if(minZoom && factor < 1.0){ rt300@4: return; rt300@4: rt300@4: } rt300@4: if(factor > 1.0){ rt300@4: minZoom = false; rt300@4: } rt300@4: scale = scale*factor; // simple eh? rt300@4: rt300@4: // update view size using centre rt300@4: // and scale... rt300@4: size.x = size.x*factor; // zooming in, size gets SMALLER (view less) rt300@4: size.y = size.y*factor; rt300@4: rt300@4: rt300@4: rt300@4: viewWasChanged(); rt300@37: calculateInterpolateLevel(); rt300@5: eventLogger.logEvent(ZOOM, centre, scale); rt300@4: rt300@5: } rt300@5: //-------------------------------------------------------------- rt300@20: void Grid::shiftCentreToSnapped(){ rt300@20: // TODO just in case we're freezing something rt300@20: // snapping actually change centre rt300@20: centre = snapCentre; rt300@20: rt300@20: } rt300@20: //-------------------------------------------------------------- rt300@5: void Grid::snapCheck(){ rt300@5: // check environs for presets. rt300@7: rt300@5: vector closePresets = presetManager.getPresetsInRange(centre - snapDist*scale, centre + snapDist*scale); rt300@5: if(closePresets.size() > 0){ rt300@5: snapped = true; rt300@5: // find closest rt300@5: double dist, mindist = maxValue; rt300@5: closestPreset = closePresets[0]; rt300@5: rt300@5: for(vector::iterator piter = closePresets.begin(); piter < closePresets.end(); piter++){ rt300@5: dist = (*piter)->coordinates.distanceTo(centre); rt300@5: rt300@5: if(dist < mindist){ rt300@5: mindist = dist; rt300@5: closestPreset = *piter; rt300@5: } rt300@5: } rt300@5: snapCentre = closestPreset->coordinates; rt300@22: eventLogger.logEvent(SNAPPED_TO_PRESET, getCoord(),closestPreset->creationTime ); rt300@35: //cout << "SNAPPED CHECK\n"; rt300@5: }else{ rt300@5: snapped = false; rt300@7: closestPreset = NULL; rt300@5: snapCentre = centre; rt300@5: } rt300@5: rt300@4: rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@5: void Grid::setMaxZoom(){ // got to smallest (white) rt300@5: if(snapped)centre = snapCentre; rt300@5: size.x = maxValue*2.0; rt300@5: scale = size.x/pixSize.x; rt300@5: size.y = scale * pixSize.y; rt300@7: maxZoom = true; rt300@7: minZoom = false; rt300@5: viewWasChanged(); rt300@5: } rt300@5: //-------------------------------------------------------------- rt300@5: void Grid::setMinZoom(){ // go to entire space (orange) rt300@5: if(snapped)centre = snapCentre; rt300@5: size.x = minValue*2.0; rt300@5: scale = size.x/pixSize.x; rt300@5: size.y = scale * pixSize.y; rt300@7: minZoom = true; rt300@7: maxZoom = false; rt300@5: viewWasChanged(); rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: void Grid::viewWasChanged(){ rt300@5: snapCheck(); rt300@4: checkLimits(); rt300@5: // calculate new params? rt300@5: vector params; rt300@5: if(snapped){ rt300@5: params = calculateParamsFromCoord(snapCentre); rt300@5: }else{ rt300@37: if(interpolateMode == NO_INTERPOLATION){ rt300@37: params = calculateParamsFromCoord(centre); rt300@37: }else if(interpolateMode == INTERPOLATE_GRID){ rt300@37: params = calculateInterpolatedParamsFromCoord(centre); rt300@37: } rt300@5: } rt300@4: for(int i = 0;i<2*paramsPerDim;i++){ rt300@4: midiCC[i] = params[i]; rt300@4: } rt300@4: rt300@4: } rt300@4: rt300@4: //-------------------------------------------------------------- rt300@4: void Grid::checkLimits(){ rt300@4: // check for maximum zoom level rt300@5: rt300@4: rt300@4: if(size.x > maxValue*2.0){ rt300@4: cout << "maxZoom\n"; rt300@4: maxZoom = true; rt300@4: size.x = maxValue*2.0; rt300@4: // need to also set y size back to rt300@4: } rt300@4: if(size.y > maxValue*2.0){ rt300@4: cout << "maxZoom\n"; rt300@4: maxZoom = true; rt300@4: size.y = maxValue*2.0; rt300@4: } rt300@4: rt300@4: if(size.x < minValue){ rt300@4: cout << "min Zoom\n"; rt300@4: minZoom = true; rt300@4: size.x = minValue; rt300@4: // need to also set y size back to rt300@4: } rt300@4: if(size.y < minValue){ rt300@4: minZoom = true; rt300@4: cout << "min Zoom\n"; rt300@4: size.y = minValue; rt300@4: } rt300@4: rt300@4: scale = size.x/pixSize.x; rt300@4: size.y = scale * pixSize.y; rt300@4: rt300@4: topLeft.x = centre.x - size.x/2; rt300@4: topLeft.y = centre.y - size.y/2; rt300@4: // check for negatives rt300@4: rt300@4: // allow centre to be at limits rt300@4: if((topLeft.x + size.x*0.5) < 0.0){ rt300@4: cout << "left Wall\n"; rt300@4: topLeft.x = 0.0 - size.x*0.5; rt300@4: centre.x = 0.0; rt300@4: } rt300@4: rt300@4: if(topLeft.y + size.y*0.5 < 0.0) { rt300@4: cout << "top Wall\n"; rt300@4: topLeft.y = 0.0 - size.y*0.5; rt300@4: centre.y = 0.0; rt300@4: } rt300@4: rt300@4: // does topleft refer to lines or view? rt300@4: rt300@4: // check max rt300@4: if(topLeft.x + size.x/2 > maxValue){ rt300@4: cout << "right Wall\n"; rt300@4: topLeft.x = maxValue - size.x/2; rt300@4: centre.x = maxValue; rt300@4: } rt300@4: if(topLeft.y + size.y/2 > maxValue) { rt300@4: cout << "bottom Wall\n"; rt300@4: topLeft.y = maxValue - size.y/2; rt300@4: centre.y = maxValue; rt300@4: } rt300@4: rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: void Grid::checkConsistencies(){ rt300@4: // debug function to check all the parameters are consistent maybe rt300@4: rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: void Grid::setCoord(TwoVector coord){ rt300@4: rt300@4: centre = coord; rt300@5: rt300@4: viewWasChanged(); rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: TwoVector Grid::getCoord(){ rt300@5: // return read point crosshairs rt300@5: if(snapped){ rt300@5: return snapCentre; rt300@5: } rt300@4: return centre; rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: vector Grid::getParams(){ rt300@4: // return a vector with midiCCs in rt300@4: // should we store params somewhere and use this as a low computation get ? rt300@4: vector params(2*paramsPerDim,0); rt300@4: // rt300@4: for(int i = 0;i<2*paramsPerDim;i++){ rt300@4: params[i] = midiCC[i]; rt300@4: } rt300@4: return params; rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: void Grid::setParams(vector params){ rt300@4: // input midiCCs, and go to the appropriate coordinate rt300@4: rt300@4: for(int i = 0;i<2*paramsPerDim;i++){ rt300@4: midiCC[i] = 64; rt300@4: } rt300@4: TwoVector coord = calculateCoordFromParams(params); rt300@4: setCoord(coord); rt300@4: rt300@20: // snapping? rt300@4: viewWasChanged(); rt300@4: rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@5: //-------------------------------------------------------------- rt300@5: //-------------------------------------------------------------- rt300@5: //-------------------------------------------------------------- rt300@5: //-------------------------------------------------------------- rt300@5: #pragma mark const utils rt300@5: rt300@37: TwoVector Grid::calculateCoordFromParams(vector params){ rt300@4: rt300@4: vector ccValueX(paramsPerDim); rt300@4: vector ccValueY(paramsPerDim); rt300@4: for(int i=0;i Grid::calculateParamsFromCoord(TwoVector coord){ rt300@35: rt300@4: if (coord.x > maxValue || coord.y > maxValue){ rt300@4: cout << "calculateParams Error: centre double value is too large" << "\n"; rt300@4: vector empty; rt300@4: return empty; rt300@4: } rt300@35: if (coord.x < 0 || coord.y < 0){ rt300@35: cout << "calculateParams Error: centre double value is negative" << "\n"; rt300@35: vector empty; rt300@35: return empty; rt300@4: } rt300@4: rt300@35: // X rt300@35: vector resultX; rt300@35: resultX = hilbert.calculateParamsFromIndex(coord.x); rt300@35: // Y rt300@4: vector resultY; rt300@35: resultY = hilbert.calculateParamsFromIndex(coord.y); rt300@4: rt300@4: // concatenate rt300@35: vector result = resultX; rt300@35: rt300@4: result.insert( result.end(), resultY.begin(), resultY.end() ); rt300@4: return result; rt300@4: } rt300@37: //-------------------------------------------------------------- rt300@37: vector Grid::calculateInterpolatedParamsFromCoord(TwoVector coord){ rt300@4: rt300@37: vector result; rt300@37: // round by masking according to interpLevel rt300@37: rt300@37: long long x = coord.x; rt300@37: long long y = coord.y; rt300@37: cout << interpLevel << "\n"; rt300@37: int roundDigits = (paramsPerDim*interpLevel); rt300@37: // knock off last digits rt300@37: x = x >> roundDigits; rt300@37: x = x << roundDigits; rt300@37: float frac = (coord.x - x)/(1 << roundDigits); rt300@37: long long xlower = x; rt300@37: long long xupper = x + (1 << roundDigits); rt300@37: rt300@37: vector pupper = hilbert.calculateParamsFromIndex(xupper); rt300@37: vector plower = hilbert.calculateParamsFromIndex(xlower); rt300@37: rt300@37: result = interpVector(pupper,plower,frac); rt300@37: // now Y rt300@37: y = y >> roundDigits; rt300@37: y = y << roundDigits; rt300@37: frac = (coord.y - y)/(1 << roundDigits); rt300@37: long long ylower = y; rt300@37: long long yupper = y + (1 << roundDigits); rt300@37: rt300@37: pupper = hilbert.calculateParamsFromIndex(yupper); rt300@37: plower = hilbert.calculateParamsFromIndex(ylower); rt300@37: rt300@37: vector resultY = interpVector(pupper,plower,frac); rt300@37: // stickem together rt300@37: result.insert( result.end(), resultY.begin(), resultY.end() ); rt300@37: return result; rt300@37: } rt300@37: //-------------------------------------------------------------- rt300@37: vector Grid::interpVector(vector upper, vector lower, float frac){ rt300@37: vector result; rt300@37: if(upper.size() != lower.size()){ rt300@37: cout << "Error: interpVector takes vectors of same length" << "\n"; rt300@37: return result; rt300@37: } rt300@37: if(frac > 1){ rt300@37: cout << "Error: bad fraction for vector interpolation" << "\n"; rt300@37: return result; rt300@37: } rt300@37: int N = upper.size(); rt300@37: for(int i=0; i Grid::walkDiff(vector left, vector right){ rt300@4: // horrible rt300@4: vector result(2,0); rt300@4: rt300@4: int size = left.size(); rt300@4: for(int i = 0; i < size; i++){ rt300@4: if(left[i] && !right[i]){ // 1 - 0 rt300@4: // dim rt300@4: result[0] = i; rt300@4: result[1] = 1; rt300@4: }else if(!left[i] && right[i]){ // 0 - 1 rt300@4: result[0] = i; rt300@4: result[1] = -1; rt300@4: }else{ // equal do nothing rt300@4: rt300@4: rt300@4: } rt300@4: } rt300@4: rt300@4: return result; rt300@4: } rt300@4: //-------------------------------------------------------------- rt300@4: //-------------------------------------------------------------- rt300@4: //--------------------------------------------------------------