这些天做C#实验以及这个KMeans算法演示器,学了一下openGL,感觉有待加强。
//Point.h/*Point 结构体定义及实现结构体重载了2个运算符:1.== //推断两个Point的坐标值是否相等2.<< //用于显示(以友元函数的方式重载)*/#ifndef Point_h_#define Point_h_#include#include #include using namespace std;const int mWidth=3; //显示时每一个字符宽度 //存放点坐标的结构 struct Point{ string name; //点名称 double x; //x轴坐标 double y; //y轴坐标 //默认的结构体构造器 Point() :x(-999),y(-999){ } Point(double xx,double yy,string n) :x(xx),y(yy),name(n){ } //复制构造函数 Point(const Point &p) :x(p.x),y(p.y),name(p.name){ } //赋值复制函数 Point operator=(const Point &p){ if(this==&p) return *this; x=p.x; y=p.y; name=p.name; return *this; } //推断两个Point坐标值是否相等 bool operator==(const Point &point)const{ return x==point.x&&y==point.y; } //重载<< friend ostream& operator<<(ostream &os,const Point &p){ os< < < << "("< < < <<","< < <<")"<<" "; return os; } }; #endif
functions.h主要是一些函数
//functions.h#ifndef functions_h_#define functions_h_#include#include #include #include #include #include #include #include #include #include #include "Point.h"#include #include using namespace std; const int MAX=20; //聚类点数 const int M_GROUP=3; //簇数 const int LIMIT=20; //同意聚类的最大次数 const int X_LIMIT=15; //X轴最大坐标 const int Y_LIMIT=15; //Y---- //数字转字符串string numberToString(int i){ stringstream s; s< &vp,int size){ vp.clear(); srand(time(0)); int i=0; //生成随机点 while(i &vp){ countTimes=0; for_each(vp.begin(),vp.end(),outPoint);};//清空流内容 void eatLine(){ while(cin.get()!='\n') continue; }; //选择起始中心点输入//center 存储中心点的数组//vp 全部点bool inputCenter(vector ¢er,vector &vp){ //可分簇的最大数目 int vpSize=vp.size(); //清空center中内容 center.clear(); cout<<"\n请输入分簇的数目:0--"< < >group; while(group<=0||group>vpSize){ cout<<"输入有误!"< >group; } //选择起始中心点 int j=0; while(j >locate; if(locate>0&&locate<=vpSize){ Point temp=vp[locate-1]; cout<<"已经成功选择了"< <<"个起始点!"<
//kmeans.h#ifndef kmeans_h_#define kmeans_h_/* @author:天下无双 @date:2014-6-5 @version:9.0 聚类算法K-means实现:採用强算算法 随机生成20个点,然后进行分成三个聚类 change:坐标点改为double类型//已经完毕聚类算法//弃用指针,所有使用vector取代//界面版openGL*/ #include "functions.h"#include "openglFunc.h"#include "Point.h"#include #include //參数为一维数组,数组大小,簇大小,选择的初始点 //返回值为聚类进行次数 //推断两次中心是否相等bool isEqual(vector &lhs,vector &rhs){ int size=rhs.size(); for(int i=0;i &arr){ int size=arr.size(); if(size!=0){ double xSum=0; double ySum=0; for(int i=0;i &vp,vector ¢er){ vector first;// 记录聚类上一次的中心 vector second; //记录这一次聚类的中心 vector > group;//存放簇/*center和group的关系下标相应 0 1 2 3 4center 0 1 2 3 4group 00 01 02 03 04 10 11 12 13 14 20 21 22 23 24 .. .. .. .. ..*/ int centerSize=center.size(); int vpSize=vp.size(); //先复制起始点到第一次聚类中心 for(int i=0;i p; group.push_back(p); } //将每一个点指派到数组里面去 for(int i=0;i group[locate].push_back(vp[i]); //输出点指派信息 //cout< <<"将被指派到簇"< <<";"< LIMIT){ cout<<"聚类次数超过了限制次数!"<
//openglFunc.h#ifndef opengl_kmeans_h_#define opengl_kmeans_h_#include#include #include #include #include #include "Point.h"#include "functions.h"//延时时间#define DELAYTIME 0.2//点的大小#define POINTSIZE 8//显示比例#define BILI 10//边#define BIAN 1//X,Y边#define XLIMIT 1.5#define YLIMIT 1.5void drawString(const char *str);//在屏幕上绘制单个点void paintPoint(Point &p){ float x=p.x*1.0/BILI; float y=p.y*1.0/BILI; glPointSize(POINTSIZE); glBegin(GL_POINTS); glVertex2f(x,y); glEnd(); const char *name=p.name.c_str(); glRasterPos2f(x+0.02f,y+0.0f); drawString(name); glFlush();};//绘制一个数组的点void paintVectorPoint(vector &vp){ int size=vp.size(); for(int i=0;i &vp){ int size=vp.size(); glColor3f(1.0,0.0,0.0); for(int i=0;i &vp){ int size=vp.size(); glColor3f(1.0,1.0,1.0); for(int i=0;i 黄色 case 1:glColor3f(0.0, 0.0, 1.0);break; //--> 蓝色 case 0:glColor3f(0.0, 1.0, 0.0);break; //--> 绿色 //case 3:glColor3f(1.0, 0.0, 0.0);break; //--> 红色 case 4:glColor3f(0.0, 1.0, 1.0);break; //--> 青色 case 5:glColor3f(1.0, 0.0, 1.0);break; //--> 品红色 case 3:glColor3f(0.0, 0.0, 0.0);break; //--> 黑色 default:break; }}#endif
//tFunc.h#ifndef tFunc_h_#define tFunc_h_#include#include "functions.h"#include #include "openglFunc.h"#include "kmeans.h"#include "functions.h"#include using namespace std;void yourChoice(){ cout<<"请输入生成的随机点个数:(建议小于20点能够看得更清晰)"< >num; eatLine(); vector vp; vector center; randPoint(vp,num); cout<<"随机生成的坐标点例如以下:"< vp; vector center; for(int i=0;i<10;i++) vp.push_back(p[i]); center.push_back(p[6]); center.push_back(p[9]); paintVectorPoint(vp); kMeans(vp,center);};#endif
//main.cpp#include "openglFunc.h"#include "functions.h"#include "tFunc.h"#include "displayFunc.h"int main(int argc,char **argv){ glutInit(&argc,argv); Init(); glutMainLoop();}DOS界面+openGL绘图 演演示样例如以下: