#include<windows.h>
#include<math.h>
#include <gl/Glut.h>
#include <iostream>
using namespace std;
const GLint screenWidth = 600;
const GLint screenHeight = 600;
struct GLPoint{
GLdouble x, y;
};
static GLPoint ptA,ptB,ptC;
static GLPoint pt={0.0,0.0};
GLdouble radius=0.0;
void myDisplay(void);
void myInit(void);
bool draw = false;
static GLint pointsNum = 0;
const GLdouble PI = 3.1415926;
void setWindow(GLdouble left, GLdouble right , GLdouble botton, GLdouble top);
void setViewport(GLdouble left, GLdouble right , GLdouble botton, GLdouble top);
void drawTween(GLPoint ptA[],GLPoint ptB[],int n, float t);
void myMouse(int button , int state, int x , int y);
void drawPoint(GLPoint p);
void drawCircle(GLPoint p,GLdouble r );
void calculateCenterAndRadius(GLPoint p1,GLPoint p2,GLPoint p3);
int main(int argc, char ** argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(screenWidth,screenHeight);
glutInitWindowPosition(100,100);
glutCreateWindow("过三点的圆:");
setWindow(0,screenWidth,0,screenHeight);
setViewport(0,screenWidth,0,screenHeight);
glutDisplayFunc(myDisplay);
glutMouseFunc(myMouse);
myInit();
glutMainLoop();
return 0;
}
void setViewport(GLdouble left, GLdouble right , GLdouble botton, GLdouble top){
glViewport(left,right,right-left,top-botton);
}
void setWindow(GLdouble left, GLdouble right , GLdouble botton, GLdouble top){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(left,right,botton,top);
}
void drawPoint(GLPoint p){
glBegin(GL_POINTS);
glVertex2d(p.x,p.y);
glEnd();
glFlush();
}
void calculateCenterAndRadius(GLPoint p1,GLPoint p2,GLPoint p3){
// a = B - A ; b = C - B ; c = A - C;
// L(t) = 1/2 ( A + B ) + ( B - A )⊥ · t
// AB 中垂线; 1/2 ( A + B ) ==》 A、B重点坐标 ==》 又等于 A + a/2
//( B - A )⊥ ==> a⊥
// 即: AB中垂线: A + a/2 + a⊥ · t
//同理: AC 中垂线又等于 A + c/2 + c⊥ · u
/************************************************************************/
/* 圆心 A + a/2 + a⊥ · t = A + c/2 + c⊥ · u
a/2 + a⊥ · t = c/2 + c⊥ · u
a⊥ · t = b/2 + c⊥ · u (∵ a + b + c = 0; <== a = B - A ; b = C - B ; c = A - C;)
∴ S = A + 1/2(a + (b·c)/(a⊥·c)·a⊥)
*/
/************************************************************************/
cout<<"向量坐标:";
GLdouble ax= (GLdouble)p2.x - p1.x ;
GLdouble ay=(GLdouble) p2.y - p1.y ;
cout<<"( "<<ax<<" , "<<ay<<" )"<<endl;
GLdouble bx= p3.x - p2.x ;
GLdouble by= p3.y - p2.y ;
cout<<"( "<<bx<<" , "<<by<<" )"<<endl;
GLdouble cx= p1.x - p3.x ;
GLdouble cy= p1.y - p3.y ;
cout<<"( "<<cx<<" , "<<cy<<" )"<<endl;
GLdouble a1x= -ay ;
GLdouble a1y= ax;
cout<<"向量a的垂直向量:( "<<a1x<<" , "<<a1y<<" )"<<endl;
//外接圆圆心
/*pt.x = (GLdouble)p1.x + 0.5*(ax + (GLdouble)a1x*(bx*cx)/(a1x*cx)) ;
pt.y = (GLdouble)p1.y + 0.5*(ay + (GLdouble)a1y*(by*cy)/(a1y*cy)) ;*/
pt.x = p1.x+0.5*(ax + ((bx*cx + by*cy)/(a1x*cx + a1y*cy))*a1x );
pt.y = p1.y+0.5*(ay + ((bx*cx + by*cy)/(a1x*cx + a1y*cy))*a1y );
/************************************************************************/
/* radius = |a|/2 * sqrt( ( b * c / ( a⊥ * c)) * ( b * c / ( a⊥ * c)) +1 )
*
/************************************************************************/
radius = (GLdouble)sqrt(ax*ax + ay*ay)*0.5*sqrt( ( (bx * cx + by * cy) /(GLdouble) ( a1x * cx + a1y * cy)) * ( (bx * cx + by * cy) / (GLdouble)( a1x * cx + a1y * cy)) +1 );
cout<<endl;
cout<<"三点坐标"<<p1.x<<" , "<<p1.y<<" "<<p2.x<<" , "<<p2.y<<" "<<p3.x<<" , "<<p3.y<<endl;
cout<<"Center:"<<pt.x<<" , "<<pt.y<<endl;
cout<<"radius:"<<radius<<endl;
draw = true;
pointsNum = 0;
//glutPostRedisplay();
//三点到圆心距离
cout<<"三点到圆心距离:"<<endl;
GLdouble d1 = sqrt((pt.x - p1.x)*(pt.x - p1.x) +( pt.y - p1.y)*( pt.y - p1.y));
GLdouble d2 = sqrt((pt.x - p2.x)*(pt.x - p2.x) +( pt.y - p2.y)*( pt.y - p2.y));
GLdouble d3 = sqrt((pt.x - p3.x)*(pt.x - p3.x) +( pt.y - p3.y)*( pt.y - p3.y));
cout<<d1<<","<<d2<<","<<d3<<endl;
drawCircle(pt,radius);
}
void myMouse(int button , int state, int x , int y){
if (state == GLUT_DOWN)
{
if (button == GLUT_LEFT_BUTTON)
{
if (pointsNum>=0 &&pointsNum<=2)
{
switch(pointsNum){
case 0: ptA.x =x; ptA.y = screenHeight - y;drawPoint(ptA);cout<<"( "<<ptA.x<<" , "<<ptA.y<<" )"<<endl;break;
case 1: ptB.x = x; ptB.y = screenHeight - y;drawPoint(ptB);cout<<"( "<<ptB.x<<" , "<<ptB.y<<" )"<<endl;break;
case 2: ptC.x = x;
ptC.y = screenHeight - y;
drawPoint(ptC);
cout<<"( "<<ptC.x<<" , "<<ptC.y<<" )"<<endl;
calculateCenterAndRadius(ptA,ptB,ptC);
break;
}
pointsNum ++;
}else{
pointsNum = 0;
draw = false;
}
}
if (button == GLUT_RIGHT_BUTTON)
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
pointsNum = 0;
}
}
}
void drawCircle(GLPoint p,GLdouble r ){
cout<<"********************************"<<p.x <<" , " <<p.y<<endl;
glBegin(GL_LINE_LOOP);
for(GLdouble i= 0;i< (GLdouble)PI*2;i=i+0.01){
glVertex2d((GLdouble)r*sin(i)+p.x,(GLdouble)r*cos(i)+p.y);
}
glEnd();
cout<<endl;
cout<<endl;
glFlush();
}
void myDisplay(void){
glClear(GL_COLOR_BUFFER_BIT);
/*cout<<"draw is "<<draw<<endl;
if (draw)
{
drawCircle(pt,radius);
}*/
}
void myInit(void){
glClearColor(1.0,1.0,1.0,0.0);
glColor3f(0.0f, 0.0f, 0.0f);
glPointSize(2.0);
glLineWidth(2.0);
}
过三点的圆: