过三点的圆 用鼠标点三个共线的点 生成过这三个点的外接圆 源代码

#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);

}


过三点的圆:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值