如何用OpenCV的绘图函数解《机械原理》的课后题?

如题,课后题是一道简单的四杆机构题,要求将四杆机构的运行情况表示出来。

简单来说,就是要求A、D为机架,DC为主动件,求AB得运行情况。


代码如下:

//

//  main.cpp

//  20171114机械原理习题解决

//

//  Created by 陈林蔚 on 2017/11/14.

//  Copyright © 2017 陈林蔚. All rights reserved.

//


#include <iostream>

#include <time.h>

#include <sys/timeb.h>

#include <sys/time.h>

#include <math.h>

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/imgproc/imgproc_c.h"

#include "opencv2/imgproc/imgproc.hpp"


//the size of Mat and  the value of pi setting

const int windowsize=600;

const double pi=3.1415926;


//namespace setting

using namespace std;

using namespace cv;


//declaring the Function to Draw the line and circle, add the text;

void DrawLine(Mat img,Point start,Point end);

void DrawEllipse(Mat img,double angle,Point a,Size b,Scalar c);

void addtext(Mat img,string text,Point a);


int main(int argc, const char * argv[]) {

    Mat draft(windowsize,windowsize,CV_8UC3); //Mat to store the Solving process

    Mat result(windowsize,windowsize,CV_8UC3); //Mat to store the Final Result

    Mat GreenCirle(windowsize,windowsize,CV_8UC3);//Mat to store the Green circle

    

    double scale=2;// in case the length of machine is to long, use this to resize it

    double ad=200/scale,ab=300/scale,bc=365/scale,cd=360/scale;

    

    //initilize the Position of A and B

    Point a(windowsize/2-100,windowsize/2),d(windowsize/2+ad-100,windowsize/2);

    Point b(0,0),c;//initialize the Position fo C.

    

    time_t rawtime1,rawtime2;

    float millisec1,millisec2;

    struct timeb tmb1,tmb2;

    ftime(&tmb1);

    rawtime1=tmb1.time;

    millisec1= tmb1.millitm;

    

    //http://pubs.opengroup.org/onlinepubs/7908799/xsh/systimeb.h.html referrence about the struct timeb

    

    Point tc[100];//To store the Point which is equal to (255,255,0)

    

    while (1) {

        ftime(&tmb2);

        //http://blog.csdn.net/reille/article/details/6396634 referrence about ftime()

        

        rawtime2=tmb2.time;

        millisec2   = tmb2.millitm;//毫秒

        cout<<rawtime2<<endl;

        double second=rawtime2-rawtime1+(millisec2-millisec1)/1000;

        

        cout<<second<<endl;

        double rad=1;//秒钟每秒走过的角度为6度,即30分之1 pi

        double speed=rad*60.0/(2*pi)*6*second/180*pi;//6*second/180*pi=2π/60s

        

        c.x=d.x+cd*cos(speed);

        c.y=d.y+cd*sin(speed);

        

        DrawLine(draft, c, d);

        DrawLine(draft, a, d);

        DrawEllipse(draft, 0, d,Size(cd,cd),Scalar(0,0,255));

        DrawEllipse(draft, 0, c,Size(bc,bc),Scalar(255,0,0));

        DrawEllipse(GreenCirle, 0, a,Size(ab,ab),Scalar(0,255,0));

        

        addWeighted(draft, 1, GreenCirle, 1, 0, draft);

        

        //the point the blue circle and green circle

        int cfc=0;//count for tc[100]

        

        //the Point which equalt to (255,255,0) is not only one, to get the continuous and static position of B, we can use following steps to do this.

        for(int y=0;y<windowsize;y++)

        {

            for(int x=0;x<windowsize;x++)

            {

                if(draft.at<Vec3b>(y,x)[0]==255&&draft.at<Vec3b>(y,x)[1]==255)

                {

                    tc[cfc].x=x;

                    tc[cfc].y=y;

                    cfc++;

                }

            }

        }

        double dist2c=1<<30;

        int closer=0;

        for(int i=0;i<cfc;i++)

        {

            double dist2c_=sqrt( pow(tc[i].x-b.x,2)+pow(tc[i].y-b.y,2) );

            if(dist2c>dist2c_)

            {

                dist2c=dist2c_;

                closer=i;

            }

        }

        b.x=tc[closer].x;

        b.y=tc[closer].y;

        

        //all points' position is known, next step is to draw the final graph.

        DrawLine(draft, a, b);

        DrawLine(draft, b, c);

        

        //add text to mark the position of points

        addtext(result,"A",a);

        addtext(result,"B",b);

        addtext(result,"C",c);

        addtext(result,"D",d);

        

        DrawLine(result, a, b);

        DrawLine(result, a, d);

        DrawLine(result, d, c);

        DrawLine(result, b, c);

        

        imshow("draft", draft);

        imshow("result", result);

        draft.setTo(0);

        result.setTo(0);

        char ch=waitKey(10); // Wait for few millisecond and go back to loop.

        if(ch==2)break;

    }

}


//the function to draw a line

void DrawLine(Mat img,Point start,Point end)

{

    int thickness=2;

    int lineType=8;

    line(img,start,end,Scalar(0,0,255),thickness,lineType);

}


//the function to draw a circle

void DrawEllipse(Mat img,double angle,Point a,Size b,Scalar c)

{

    int thickness=2;

    int lineType=8;

    ellipse(img,

            a,

            b,

            angle,

            0,

            360,

            c,

            thickness,

            lineType);

}

//the function to add Text

//http://blog.csdn.net/keith_bb/article/details/53366674 referrence about putText()


void addtext(Mat img,string text,Point a)

{

    int fontFace = FONT_HERSHEY_SCRIPT_COMPLEX;

    double fontScale = 0.9;

    int thickness = 1;

    putText(img,text,a,fontFace,fontScale,Scalar::all(255),thickness,8);

}


运行结果如下:

draft:



result:



我大概是闲得发慌吧。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值