日更第5期-2015-1-25-openFrameworks系列第四讲-我胡汉三又回来了!(误)一个画线方法模拟程序
不得不说,我真的是跳票了好久。。。。。从1月20日至1月24日都没有更新。说好的日更,简直成了周更!
其实找理由也是不难的,最近我摔了一跤,牙磕碎了一颗,腿脚不便,头脑眩晕,实在不是写博客的心情......
不过说借口又有什么用!我不还是每天上着B站吗?之所以不更新博客,没有别的原因,就是懒!
那么我再说几句闲话,反正也没人看。╮(╯▽╰)╭
恩,最近有点失落。Kinect被收回去了啊!唉唉唉,真是的,那个老师,真是靠不住.....期末也只给我63。
没见过这种给他出了大力气还受累不讨好的啊!!不过。。。说这个其实还是算是一种掩饰,真正的原因,
还是在于又一次怀疑自己的能力了,又一次怀疑自己所做的事情的意义了。我在这里写博客,反正也没人看,
OpenFrameworks你们也都不用,我写的基础部分不好,概念也讲不清,拔高也做不到,真是失败,那还
做什么?
因为我想写。就算我做不好,就算我讲不好,只要我想讲,我就有权利讲,就应该讲!于是,开始!
//commonline.h #pragma once #include "ofMain.h" class CommonLine { public: CommonLine(void); ~CommonLine(void); void setStartPoint(double percentX, double percentY); void setEndPoint(double percentX, double percentY); void releaseDrag(); void drawPath(double gridWidth, double gridHeight, double startX, double startY); ofPoint getStartPoint(); ofPoint getEndPoint(); bool isHasPath(); private: ofPoint startPoint; ofPoint endPoint; bool hasPath; };
//CommonLine.cpp #include "CommonLine.h" CommonLine::CommonLine(void) { this->hasPath = false; } CommonLine::~CommonLine(void) { } void CommonLine::setStartPoint(double percentX, double percentY) { if(this->hasPath == true) { return; } this->hasPath = true; this->startPoint.set(percentX,percentY); this->endPoint.set(percentX,percentY); }; void CommonLine::setEndPoint(double percentX, double percentY) { this->endPoint.set(percentX,percentY); if(percentX >1) { if(percentY<1 && percentY >0) { this->endPoint.y = (1-this->startPoint.x) *(percentY-this->startPoint.y) /(percentX-this->startPoint.x) + this->startPoint.y; } if(percentY <0) { this->endPoint.y = (1-this->startPoint.x) *(-percentY-this->startPoint.y) /(percentX-this->startPoint.x) + this->startPoint.y; } this->endPoint.x = 1; } if(percentX <0) { if(percentY>0 && percentY<1) { this->endPoint.y = this->startPoint.x *(percentY-this->startPoint.y) /(this->startPoint.x-percentX) +this->startPoint.y; } if(percentY<0) { this->endPoint.y = this->startPoint.x *(-percentY-this->startPoint.y) /(this->startPoint.x-percentX) +this->startPoint.y; } this->endPoint.x = 0; } if(percentY >1) { if(percentX>0 && percentX<1) { this->endPoint.x = (1-this->startPoint.y) *(percentX-this->startPoint.x) /(percentY-this->startPoint.y) + this->startPoint.x; } if(percentX<0) { this->endPoint.x = (1-this->startPoint.y) *(-percentX-this->startPoint.x) /(percentY-this->startPoint.y) + this->startPoint.x; } this->endPoint.y = 1; } if(percentY <0 && percentX>0 && percentX<1) { if(percentX>0 && percentX<1) { this->endPoint.x = this->startPoint.y *(percentX-this->startPoint.x) /(this->startPoint.y-percentY) +this->startPoint.x; } if(percentX<0) { this->endPoint.x = this->startPoint.y *(percentX-this->startPoint.x) /(this->startPoint.y-percentY) +this->startPoint.x; } this->endPoint.y = 0; } }; void CommonLine::releaseDrag() { this->hasPath = false; } void CommonLine::drawPath(double gridWidth, double gridHeight , double startX, double startY) { if(this->hasPath == true) { ofSetColor(255,0,0); ofLine(gridWidth*this->startPoint.x+startX,gridHeight*this->startPoint.y+startY, gridWidth*this->endPoint.x+startX,gridHeight*this->endPoint.y+startY); } }; ofPoint CommonLine::getStartPoint() { return this->startPoint; }; ofPoint CommonLine::getEndPoint() { return this->endPoint; }; bool CommonLine::isHasPath() { return this->hasPath; }
//gridbox.h #pragma once #include "ofMain.h" #include "LinePath.h" #include "CommonLine.h" class Gridbox { public: Gridbox(void); ~Gridbox(void); void setUpGridBox(int windowX, int windowY); void drawGridBoxWithDots(); void drawCurrentLineDots(); void updateGridDotSize(int windowX, int windowY); void addCurrentLineDots(); void addDotToGridBox(int x, int y); void clearAllDots(); void clickLeft(int mouseX, int mouseY); void clickRight(); void drag(int mouseX, int mouseY); void releaseDrag(); void drawPath(); bool isClickInBox(int mouseX, int mouseY); private: void calculateEdgeStart(int windowX, int windowY); int currentLineNum; int pastWindowX; int pastWindowY; bool dots[41][41]; double dotRadius; double dotPGridRatial; double minEageRatial; int gridStartposX; int gridStartposY; int gridWidth; int minLineNum; int maxLineNum; LinePath thisLinePath; CommonLine thisCommonLine; };
//gridbox.cpp #include "Gridbox.h" #include "ofMain.h" Gridbox::Gridbox(void) { } Gridbox::~Gridbox(void) { } void Gridbox::setUpGridBox(int windowX, int windowY) { this->minLineNum = 10; this->maxLineNum = 40; this->currentLineNum = 40; this->dotPGridRatial = 0.85; this->minEageRatial = 0.05; this->pastWindowX = windowX; this->pastWindowY = windowY; this->calculateEdgeStart(windowX,windowY); this->clearAllDots(); } void Gridbox::drawGridBoxWithDots() { int lineLength = this->currentLineNum * this->gridWidth; ofSetHexColor(0x000000); for(int i=0; i<this->currentLineNum+1; i++) { ofLine(this->gridStartposX,this->gridStartposY+this->gridWidth*i, this->gridStartposX+lineLength,this->gridStartposY+this->gridWidth*i); ofLine(this->gridStartposX+this->gridWidth*i,this->gridStartposY, this->gridStartposX+this->gridWidth*i,this->gridStartposY+lineLength); } ofFill(); ofSetColor(0,0,0); for(int j=0; j<this->currentLineNum+1; j++) { for(int k=0; k<this->currentLineNum+1; k++) { if(this->dots[j][k] == true) { ofEllipse(ofPoint(this->gridStartposX + j*this->gridWidth, this->gridStartposY + k*this->gridWidth),this->dotRadius,this->dotRadius); } } } this->drawCurrentLineDots(); } void Gridbox::updateGridDotSize(int windowX, int windowY) { if(this->pastWindowX != windowX || this->pastWindowY != windowY) { this->pastWindowX = windowX; this->pastWindowY = windowY; this->calculateEdgeStart(windowX,windowY); } } void Gridbox::addCurrentLineDots() { if(this->thisCommonLine.isHasPath() == false) { return; } ofPoint startP; ofPoint endP; ofPoint tempP = this->thisCommonLine.getStartPoint(); startP.x = tempP.x; startP.y = tempP.y; tempP = this->thisCommonLine.getEndPoint(); endP.x = tempP.x; endP.y = tempP.y; startP.x *= (int)(this->currentLineNum+1.5); startP.y *= (int)(this->currentLineNum+1.5); endP.x *= (int)(this->currentLineNum+1.5); endP.y *= (int)(this->currentLineNum+1.5); double k = ( endP.y - startP.y ) / ( endP.x - startP.x ); if( k > 1 || k < -1) { if(startP.y > endP.y ) { ofPoint tempP; tempP.x = startP.x; tempP.y = startP.y; startP.x = endP.x; startP.y = endP.y; endP.x = tempP.x; endP.y = tempP.y; } int a,b,dt1,dt2,d,x,y,ystp=1; a = startP.x - endP.x; b = endP.y - startP.y; if(k<0) { a=-a; ystp = -1; } d = (a<<1)+b; dt1 = a<<1; dt2 = (a+b)<<1; x = startP.x; y = startP.y; this->addDotToGridBox(x,y); while(y<endP.y-1) { if(d<0) { y++; x+=ystp; d+=dt2; } else { y++; d+=dt1; } this->addDotToGridBox(x,y); } } else { if(startP.x > endP.x ) { ofPoint tempP; tempP.x = startP.x; tempP.y = startP.y; startP.x = endP.x; startP.y = endP.y; endP.x = tempP.x; endP.y = tempP.y; } int a,b,dt1,dt2,d,x,y,ystp=1; a = startP.y - endP.y; b = endP.x - startP.x; if(k<0) { a=-a; ystp = -1; } d = (a<<1)+b; dt1 = a<<1; dt2 = (a+b)<<1; x = startP.x; y = startP.y; this->addDotToGridBox(x,y); while(x<endP.x-1) { if(d<0) { x++; y+=ystp; d+=dt2; } else { x++; d+=dt1; } this->addDotToGridBox(x,y); } } } void Gridbox::drawCurrentLineDots() { if(this->thisCommonLine.isHasPath() == false) { return; } ofPoint startP; ofPoint endP; ofPoint tempP = this->thisCommonLine.getStartPoint(); startP.x = tempP.x; startP.y = tempP.y; tempP = this->thisCommonLine.getEndPoint(); endP.x = tempP.x; endP.y = tempP.y; startP.x *= (int)(this->currentLineNum+1.5); startP.y *= (int)(this->currentLineNum+1.5); endP.x *= (int)(this->currentLineNum+1.5); endP.y *= (int)(this->currentLineNum+1.5); double k = ( endP.y - startP.y ) / ( endP.x - startP.x ); if( k > 1 || k < -1) { if(startP.y > endP.y ) { ofPoint tempP; tempP.x = startP.x; tempP.y = startP.y; startP.x = endP.x; startP.y = endP.y; endP.x = tempP.x; endP.y = tempP.y; } int a,b,dt1,dt2,d,x,y,ystp=1; a = startP.x - endP.x; b = endP.y - startP.y; if(k<0) { a=-a; ystp = -1; } d = (a<<1)+b; dt1 = a<<1; dt2 = (a+b)<<1; ofFill(); ofSetColor(0,0,0); x = startP.x; y = startP.y; ofEllipse(ofPoint(this->gridStartposX + x*this->gridWidth, this->gridStartposY + y*this->gridWidth),this->dotRadius,this->dotRadius); while(y<endP.y-1) { if(d<0) { y++; x+=ystp; d+=dt2; } else { y++; d+=dt1; } ofEllipse(ofPoint(this->gridStartposX + x*this->gridWidth, this->gridStartposY + y*this->gridWidth),this->dotRadius,this->dotRadius); } } else { if(startP.x > endP.x ) { ofPoint tempP; tempP.x = startP.x; tempP.y = startP.y; startP.x = endP.x; startP.y = endP.y; endP.x = tempP.x; endP.y = tempP.y; } int a,b,dt1,dt2,d,x,y,ystp=1; a = startP.y - endP.y; b = endP.x - startP.x; if(k<0) { a=-a; ystp = -1; } d = (a<<1)+b; dt1 = a<<1; dt2 = (a+b)<<1; x = startP.x; y = startP.y; ofEllipse(ofPoint(this->gridStartposX + x*this->gridWidth, this->gridStartposY + y*this->gridWidth),this->dotRadius,this->dotRadius); while(x<endP.x-1) { if(d<0) { x++; y+=ystp; d+=dt2; } else { x++; d+=dt1; } ofEllipse(ofPoint(this->gridStartposX + x*this->gridWidth, this->gridStartposY + y*this->gridWidth),this->dotRadius,this->dotRadius); } } } void Gridbox::addDotToGridBox(int x, int y) { this->dots[x][y]=true; } void Gridbox::clearAllDots() { for(int j=0; j<this->maxLineNum+1; j++) { for(int k=0; k<this->maxLineNum+1; k++) { this->dots[j][k] = false; } } } void Gridbox::calculateEdgeStart(int windowX, int windowY) { int miniLine; miniLine = windowY; if(windowX < windowY) { miniLine = windowX; } this->gridWidth = miniLine*(1-2*this->minEageRatial) / this->currentLineNum; this->dotRadius = this->gridWidth * this->dotPGridRatial; this->gridStartposX = ( windowX - this->currentLineNum * this->gridWidth ) / 2; this->gridStartposY = ( windowY - this->currentLineNum * this->gridWidth ) / 2; } void Gridbox::clickLeft(int mouseX, int mouseY) { if(this->isClickInBox(mouseX,mouseY) == true) { /* if(this->thisLinePath.isFull() == true) { this->thisLinePath.clearPath(); this->clearAllDots(); } double gridLength = this->gridWidth * this->currentLineNum; double perX = ( mouseX - this->gridStartposX ) / gridLength; double perY = ( mouseY - this->gridStartposY ) / gridLength; this->thisLinePath.addPathDot(perX,perY); */ double gridLength = this->gridWidth * this->currentLineNum; double perX = ( mouseX - this->gridStartposX ) / gridLength; double perY = ( mouseY - this->gridStartposY ) / gridLength; this->thisCommonLine.setStartPoint(perX,perY); } } void Gridbox::clickRight() { //this->thisLinePath.clearPath(); this->thisCommonLine.releaseDrag(); this->clearAllDots(); } void Gridbox::drag(int mouseX, int mouseY) { double gridLength = this->gridWidth * this->currentLineNum; double perX = ( mouseX - this->gridStartposX ) / gridLength; double perY = ( mouseY - this->gridStartposY ) / gridLength; this->thisCommonLine.setEndPoint(perX,perY); } void Gridbox::releaseDrag() { if(this->thisCommonLine.isHasPath()==true) { this->addCurrentLineDots(); this->thisCommonLine.releaseDrag(); } } bool Gridbox::isClickInBox(int mouseX, int mouseY) { ofRectangle box; double gridLength = this->gridWidth * this->currentLineNum; box.set(ofPoint(this->gridStartposX,this->gridStartposY),gridLength,gridLength); return box.inside(mouseX,mouseY); } void Gridbox::drawPath() { double gridLength = this->gridWidth * this->currentLineNum; //this->thisLinePath.drawPath(this->gridStartposX,this->gridStartposY,gridLength); this->thisCommonLine.drawPath(gridLength,gridLength,this->gridStartposX,this->gridStartposY); }
//linepath.h #pragma once #include "ofMain.h" class LinePath { public: LinePath(void); ~LinePath(void); void clearPath(); void addPathDot(double percentX, double percentY); void drawPath(double startPathposX, double startPathposY, int gridLength); bool isFull(); private: ofPoint storedPathDots[11]; int currentPathDotNum; };
//linepath.cpp #include "LinePath.h" LinePath::LinePath(void) { } LinePath::~LinePath(void) { } void LinePath::clearPath() { this->currentPathDotNum = 0; } bool LinePath::isFull() { if(this->currentPathDotNum >= 10) { return true; } else { return false; } } void LinePath::addPathDot(double percentX, double percenrY) { this->storedPathDots[this->currentPathDotNum].set(percentX,percenrY); this->currentPathDotNum++; } void LinePath::drawPath(double startPathposX, double startPathposY, int gridLength) { ofSetColor(255,0,0); for(int i=0; i<this->currentPathDotNum-1; i++) { ofLine(startPathposX+gridLength*this->storedPathDots[i].x, startPathposY+gridLength*this->storedPathDots[i].y, startPathposX+gridLength*this->storedPathDots[i+1].x, startPathposY+gridLength*this->storedPathDots[i+1].y); } }
//ofapp.h #pragma once #include "ofMain.h" class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); void keyPressed(int key); void keyReleased(int key); void mouseMoved(int x, int y ); void mouseDragged(int x, int y, int button); void mousePressed(int x, int y, int button); void mouseReleased(int x, int y, int button); void windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); };
//ofapp.cpp #include "ofApp.h" #include "Gridbox.h" Gridbox thisGridBox; //-------------------------------------------------------------- void ofApp::setup(){ int x = ofGetWindowWidth(); int y = ofGetWindowHeight(); thisGridBox.setUpGridBox(x,y); thisGridBox.addDotToGridBox(12,8); thisGridBox.addDotToGridBox(10,6); thisGridBox.addDotToGridBox(11,7); } //-------------------------------------------------------------- void ofApp::update(){ int x = ofGetWindowWidth(); int y = ofGetWindowHeight(); thisGridBox.updateGridDotSize(x,y); } //-------------------------------------------------------------- void ofApp::draw(){ ofBackground(255,255,255); thisGridBox.drawGridBoxWithDots(); thisGridBox.drawPath(); } //-------------------------------------------------------------- void ofApp::keyPressed(int key){ } //-------------------------------------------------------------- void ofApp::keyReleased(int key){ } //-------------------------------------------------------------- void ofApp::mouseMoved(int x, int y ){ } //-------------------------------------------------------------- void ofApp::mouseDragged(int x, int y, int button){ if(button == OF_MOUSE_BUTTON_LEFT) { thisGridBox.drag(x,y); } } //-------------------------------------------------------------- void ofApp::mousePressed(int x, int y, int button){ if(button == OF_MOUSE_BUTTON_LEFT) { thisGridBox.clickLeft(x,y); } if(button == OF_MOUSE_BUTTON_RIGHT) { thisGridBox.clickRight(); } } //-------------------------------------------------------------- void ofApp::mouseReleased(int x, int y, int button){ /* if(button == OF_MOUSE_BUTTON_LEFT) { thisGridBox.clickLeft(x,y); } if(button == OF_MOUSE_BUTTON_RIGHT) { thisGridBox.clickRight(); } */ thisGridBox.releaseDrag(); } //-------------------------------------------------------------- void ofApp::windowResized(int w, int h){ } //-------------------------------------------------------------- void ofApp::gotMessage(ofMessage msg){ } //-------------------------------------------------------------- void ofApp::dragEvent(ofDragInfo dragInfo){ }
//main.cpp #include "ofMain.h" #include "ofApp.h" //======================================================================== int main( ){ ofSetupOpenGL(800,600,OF_WINDOW); // <-------- setup the GL context // this kicks off the running of my app // can be OF_WINDOW or OF_FULLSCREEN // pass in width and height too: ofRunApp(new ofApp()); }
不知道同学们有没有学过计算机图形学?一般上来就会学习一个怎么画直线。可能有人会不解,就一个直线还有什么好教的?
对,你会在纸面上画直线,但是,这可不是说你就会在计算机的屏幕上画一条直线出来。实际上,计算机图形学在画直线的
时候是以像素为基本点的,所以,一般,书上的图示会画得很大,然后把像素画成圆的。
但是捏,老师在做样例程序的时候就完全不管那么多了,直接画像素。那么结果就是,只是画了一条平凡无奇的直线,根本
没法看懂这个线是怎么画的。所以呢,我就以画出书上插图那样的程序为目标,开始了编程。然后,产生的就是上面的那个程序。
我还是多少截个图。
(红线是鼠标拖出来的路径,黑点是拟合出来的直线)
这个程序现在还是一个试玩版,所以很多内容还比较粗糙,但是呢,总有一天我会把这个程序完全做好的!(真的)
到时候,除了画直线,画曲线,画圆画方,还可以填色,还有橡皮擦,画刷。
恩,最后我再扯扯淡。
写博客的价值就是在于看的。如果有人说,我写博客就是为了好玩,就是为了给自己看,就是为了整理资料,那么我只能说
他是在自欺欺人。这世上自由很多种方式来记录文字、心情。当然,在技术类博客里,主要还是记录技术。之所以挑选博客
这种方式,就正是看上了它能便捷的传播给不特定多数人的特征。起码我写博客就是这个目的。
到现在为止,没有除了我以外的任何人看过这个博客——当然我也没有尝试过推荐它到首页。因为,我知道,现在的它还远远
没有那个资格。但是,总有一天它会的。我要做的就是坚持到那一天。
明天,我还会回来。
对了,关于以后具体讲解什么内容的事,我在下次日更时会说清楚的。
再见~O(∩_∩)O~