diff --git a/src/ofTypesSPTA.h b/src/ofTypesSPTA.h new file mode 100644 index 0000000..f2383e7 --- /dev/null +++ b/src/ofTypesSPTA.h @@ -0,0 +1,54 @@ + +#include "ofTypes.h" + +#pragma once + +class ofColorSPTA : public ofColor{ + +public: + ofColorSPTA() :ofColor() { + randomColor(); + a = 255; + } + + ofColorSPTA(int _r,int _g, int _b){ + r = _r; + g = _g; + b = _b; + a = 255; + } + + ofColorSPTA(int _r,int _g, int _b, int _a){ + r = _r; + g = _g; + b = _b; + a = _a; + } + + void set(int _r,int _g, int _b){ + r = _r; + g = _g; + b = _b; + } + + void set(int _r,int _g, int _b, int _a){ + r = _r; + g = _g; + b = _b; + a = _a; + } + + void randomColor(){ + r = ofRandom(0,255); + g = ofRandom(0,255); + b = ofRandom(0,255); + } + + ofColorSPTA operator+( const ofColorSPTA& color ) const { + return ofColorSPTA( r+color.r, g+color.g, b+color.b ); + } + + ofColorSPTA operator-( const ofColorSPTA& color ) const { + return ofColorSPTA( r-color.r, g-color.g, b-color.b ); + } +}; diff --git a/src/ofxVoronoiGL.cpp b/src/ofxVoronoiGL.cpp new file mode 100644 index 0000000..43d12ae --- /dev/null +++ b/src/ofxVoronoiGL.cpp @@ -0,0 +1,208 @@ +#include "ofxVoronoiGL.h" + +void ofxVoronoiGL::setup(int _width, int _height, float _error){ + width = _width; + height = _height; + error = _error; + + fbo.allocate(width,height,GL_RGB,1); + fboImage.allocate(width,height,OF_IMAGE_COLOR); + + R = sqrt(width*width + height*height); + //FXTODO musst be calculate by 2cos⁽⁻¹)(R-E / R) + alpha = 3; + steps = (int)(360.f / alpha)+1; + alphaUse = 360.f / (float)steps; +} + + +void ofxVoronoiGL::update(){ +// fbo.clear();//TODO hier stand ma clear + fbo.begin(); + createVoronoi(); + fbo.end(); + + //preDraw to be able to use opencv methods + ofSetColor(255,255,255); + fbo.draw(0,0); + fboImage.grabScreen(0,0,width,height); + ofFill(); + ofRect(0,0,width,height); +} +void ofxVoronoiGL::setPoint(int x,int y){ + points.push_back(ofxVoronoiCellFx(x,y,ofColorSPTA())); +} +void ofxVoronoiGL::setPoint(ofPoint & p){ + setPoint(p.x,p.y); +} +void ofxVoronoiGL::setPolygon(std::vector & points){ + std::vector cells; + std::vector::iterator pointIt; + for(pointIt = points.begin(); pointIt != points.end();pointIt++){ + ofPoint & p = *pointIt; + cells.push_back(ofxVoronoiCellFx(p.x,p.y,ofColorSPTA())); + } + polygons.push_back(cells); +} + +void ofxVoronoiGL::drawDirectOnScreen(int x,int y){ + ofPushMatrix(); + ofTranslate(x,y); + createVoronoi(); + ofPopMatrix(); +} + +void ofxVoronoiGL::createVoronoi(){ + glEnable(GL_DEPTH_TEST); + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + + //draw points + std::vector::iterator pointIt; + for(pointIt = points.begin(); pointIt!=points.end();pointIt++){ + ofxVoronoiCellFx& p = *pointIt; + drawCone(p,p.color); + } + + //draw polygons + std::vector >::iterator polyIt; + for(polyIt = polygons.begin();polyIt!=polygons.end();polyIt++){ + std::vector& poly = *polyIt; + drawPolygon(poly); + } + + glDisable(GL_DEPTH_TEST); //FXTODO instead of enable and disable -> popStyle + } + +void ofxVoronoiGL::drawCone(int peakX, int peakY, ofColor &color){ + ofSetColor(color.r,color.g,color.b); + + glPushMatrix(); + glTranslatef(peakX, peakY, 0); + + glBegin(GL_TRIANGLES); + for(int i=0;i & poly){ + std::vector::iterator pointIt; + std::vector::iterator pointIt2; + std::vector::iterator pointIt3; + + //Sonderfälle + if(poly.size()<3){ + if(poly.size() == 1){ + pointIt = poly.begin(); + ofxVoronoiCellFx& p = *pointIt; + drawCone(p,p.color); + }else if(poly.size() == 2){ + pointIt = poly.begin(); + pointIt2 = poly.begin(); + ofxVoronoiCellFx& p1 = *pointIt; + ofxVoronoiCellFx& p2 = *pointIt2; + drawCone(p1,p1.color); + drawCone(p2,p1.color); + drawTent(p1,p2,p1.color); + } + } + + pointIt = poly.begin(); + pointIt2 = poly.begin(); + pointIt3 = poly.begin(); + pointIt2++; + pointIt3++; + pointIt3++; + + ofColorSPTA color = (*pointIt).color; + bool end = false; + while(!end){ + //for(; pointIt3 != poly.end();pointIt++,pointIt2++,pointIt3++){ + if(pointIt3 == poly.end()){ + pointIt3 = poly.begin(); + }else if(pointIt2 == poly.end()){ + pointIt2 = poly.begin(); + end = true; + } + + ofxVoronoiCellFx& p1 = *pointIt; + ofxVoronoiCellFx& p2 = *pointIt2; + ofxVoronoiCellFx& p3 = *pointIt3; + + ofxVec2f v1 = ofxVec2f(p1.x-p2.x,p1.y-p2.y); + ofxVec2f v2 = ofxVec2f(p2.x-p3.x,p2.y-p3.y); + ofColorSPTA colorCone = color; + + if(skeleton){ + if(v1.angle(v2)<0){ + colorCone.set(0,0,0); + color = p2.color; + } + }else if(perFeatureV){ + colorCone = p2.color; + } + + drawCone(p2,colorCone); + drawTent(p2,p3,color); + + pointIt++,pointIt2++,pointIt3++; + } +} + +void ofxVoronoiGL::drawTent(ofxVoronoiCellFx p1, ofxVoronoiCellFx p2, ofColor &color){ + //vector between p1 and p2 => p1-p2 + ofPoint p1p2 = ofPoint(p1.x-p2.x,p1.y-p2.y); + ofxVec2f norm1 = ofxVec2f(-p1p2.y,p1p2.x); + ofxVec2f norm2 = ofxVec2f(p1p2.y,-p1p2.x); + norm1.normalize(); + norm2.normalize(); + norm1 *= R; + norm2 *= R; + + ofPoint pn1 = norm1; + ofPoint pn2 = norm2; + + if(perFeatureV){ + ofSetColor(255-p1.color.r,255-p1.color.g,255-p1.color.b); + }else{ + ofSetColor(color.r,color.g,color.b); + } + glBegin(GL_QUADS); + glVertex3f(p1.x,p1.y,0); + glVertex3f(p2.x,p2.y,0); + glVertex3f(p2.x + pn1.x ,p2.y + pn1.y ,-R); + glVertex3f(p1.x + pn1.x ,p1.y + pn1.y ,-R); + glEnd(); + + + if(skeleton){ + ofSetColor(0,0,0); + } + + glBegin(GL_QUADS); + glVertex3f(p1.x,p1.y,0); + glVertex3f(p2.x,p2.y,0); + glVertex3f(p2.x + pn2.x ,p2.y + pn2.y ,-R); + glVertex3f(p1.x + pn2.x ,p1.y + pn2.y ,-R); + glEnd(); + + if(drawCenters){ + ofSetColor(0,0,0); + ofLine(p1.x,p1.y,p2.x,p2.y); + } +} diff --git a/src/ofxVoronoiGL.h b/src/ofxVoronoiGL.h new file mode 100644 index 0000000..01beeea --- /dev/null +++ b/src/ofxVoronoiGL.h @@ -0,0 +1,76 @@ +#include "ofxVectorMath.h" +#include "ofxOpenCv.h" +#include "ofTypesSPTA.h" + +#pragma once + + +class ofxVoronoiCellFx{ +public: + ofxVoronoiCellFx(int _x, int _y, ofColorSPTA _color){ + x = _x; + y = _y; + color = _color; + } + ofColorSPTA color; + int x,y; +}; + +class ofxVoronoiGL{ + +public: + ofxVoronoiGL(){} + ofxVoronoiGL(float width, float height, float error = 1.0f){ + setup(width,height,error); + } + + void setup(int _width, int _height, float _error); + + void update(); + + void drawDirectOnScreen(int x=0,int y=0); + + void drawFBOOnScreen(int x,int y){ + fbo.draw(x,y); + } + + void drawFBOImg(int x,int y){ + fboImage.draw(x,y); + } + + unsigned char * getFBOPixels(){ + return fboImage.getPixels(); + } + + void setPoint(int x,int y); + void setPoint(ofPoint & p); + void setPolygon(std::vector & points); + void clear(){ + points.clear(); + polygons.clear(); + } + + float alpha; + bool drawPoly,perFeatureV,skeleton,drawCenters; + +protected: + ofFbo fbo; + ofImage fboImage; + + std::vector points; + std::vector > polygons; + + float width,height; + float alphaUse, R, error; + + int steps; + + void createVoronoi(); + + void drawCone(int x, int y, ofColor& color); + void drawCone(ofxVoronoiCellFx p, ofColor& color){ + drawCone(p.x,p.y,color); + } + void drawTent(ofxVoronoiCellFx p1, ofxVoronoiCellFx p2, ofColor& color); + void drawPolygon(std::vector & poly); +};