日更第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~

posted @ 2015-01-25 23:54  李农伯  阅读(1456)  评论(6编辑  收藏  举报