天天看點

C++練習:已知三點,求過這三點的圓

    在論壇裡看到了這個問題,基本上都是平面幾何裡的問題。把點,線做成了結構。

//  3point.cpp : Defines the entry point for the console application.

// 已知三點 求過這三點的圓心坐标和圓的半徑

//  xmxoxo 2006.11.8 at XiaMen

#include  " stdafx.h "

#include  " stdlib.h "

#include  " math.h "

#include  " stdio.h "

#include  " iostream.h "

// 常數

double   const  pai  =   3.1415926535897932384626 ;

// 坐标點結構

struct  point

{

     double  x;     // 橫坐标

     double  y;     // 縱坐标

};

// 直線方程結構

struct  line

{

     double  k;     // 斜率

     double  b;     // 截距

};

// 判斷兩點是否相同

bool  samep(point p1,point p2)

{

     if  ((p1.x == p2.x) && (p1.y == p2.y))

    {

         return   1 ;

    }

     else

    {

         return   0 ;

    }

}

// 求兩點距離

double  dist(point p1,point p2)

{

     double  ret = 0 ;

    ret = sqrt((p1.x - p2.x) * (p1.x - p2.x) +  (p1.y - p2.y) * (p1.y - p2.y));

     return  ret;

}

point midpoint(point p1, point p2)

{

    point ret;

    ret.x  =  (p1.x  +  p2.x ) / 2 ;

    ret.y  =  (p1.y  +  p2.y ) / 2 ;

     return  ret;

}

line line2p(point p1,point p2)

{

    line ret;

     if  ((p1.x == p2.x)  &&  (p1.y  =  p2.y))

    {

        ret.k  =   0 ;

        ret.b  =   0 ;

    }

     else

    {

        ret.k  =  (p1.y  -  p2.y) /  (p1.x  - p2.x);

        ret.b  =  p1.y  -  p1.x  *  ret.k ;

    }

     return  ret;

}

// 判斷兩直線是否相交

bool  iscross(line l1,line l2)

{

     if  (l1.k == l2.k)

    {

         return   0 ;

    }

     else

    {

         return   1 ;

    }

}

point crosspoint(line l1,line l2)

{

    point ret;

     if  ( ! iscross(l1,l2))

    {

        ret.x  =   0 ;

        ret.y  =   0 ;

    }

     else

    {

        ret.x  =  (l2.b - l1.b )  /  (l1.k  -  l2.k);

        ret.y  =  (l1.k * l2.b - l2.k * l1.b) / (l1.k - l2.k);

    }

     return  ret;

}

line linepoint(point p, double  k, double  n)  // 過某點直線方程

{

    line ret;

    ret.k  =  tan(atan(k) + n);

    ret.b  =  p.y  -   ret.k  *  p.x ;

     return  ret;

}

point p1,p2,p3;

point m1,m2,m3;

line l1,l2,l3;

line lm1,lm2,lm3;

point circlep;

double  circler,dis2,dis3;

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

{

    printf( " 幾何問題圖解 2006.11.8 Xmxoxo " );

     while  ( 1 )

    {

        cout << " 請輸入第1點坐标: " ;

        cin >> p1.x >> p1.y;

        printf( " 請輸入第2點坐标: " );

        cin >> p2.x >> p2.y;

        printf( " 請輸入第3點坐标: " );

        cin >> p3.x >> p3.y;

         if  (samep(p1,p2))

        {

            printf( " 兩點相同! " );

             break ;

        }

         // cout<<setprecision(10)<<setiosflags(ios::showpos);

        cout << " 第1點坐标是: ( " << p1.x  << " , "   << p1.y  << " ) " ;

        cout << " 第2點坐标是: ( " << p2.x  << " , "   << p2.y  << " ) " ;

        cout << " 第3點坐标是: ( " << p3.x  << " , "   << p3.y  << " ) " ;

        m1 = midpoint(p1,p2);

        m2 = midpoint(p2,p3);

        m3 = midpoint(p3,p1);

        cout << " p1,p2中點坐标是: ( " << m1.x  << " , "   << m1.y  << " ) " ;

        l1 = line2p(p1,p2);

        l2 = line2p(p2,p3);

        l3 = line2p(p3,p1);

        cout << " P1,P2連線方程是: Y=( " <<  ( float ) l1.k  << " )X+( "   <<  ( float ) l1.b  << " ) " ;

        cout << " P2,P3連線方程是: Y=( " <<  ( float ) l2.k  << " )X+( "   <<  ( float ) l2.b  << " ) " ;

        cout << " P3,P1連線方程是: Y=( " <<  ( float ) l3.k  << " )X+( "   <<  ( float ) l3.b  << " ) " ;

        lm1 = linepoint(m1,l1.k,pai / 2 );

        lm2 = linepoint(m2,l2.k,pai / 2 );

        lm3 = linepoint(m3,l3.k,pai / 2 );

        cout << " P1,P2連線的垂線方程是: Y=( "   <<  ( float ) lm1.k  <<   " )X+( " <<  ( float ) lm1.b  <<   " ) " ;

        cout << " P2,P3連線的垂線方程是: Y=( "   <<  ( float ) lm2.k  <<   " )X+( " <<  ( float ) lm2.b  <<   " ) " ;

        cout << " P3,P1連線的垂線方程是: Y=( "   <<  ( float ) lm3.k  <<   " )X+( " <<  ( float ) lm3.b  <<   " ) " ;

        circlep = crosspoint(lm1,lm2);

        circler = dist(circlep,p1);

        dis2 = dist(circlep,p2);

        dis3 = dist(circlep,p3);

        cout <<   " 圓心坐标是: ( "   <<  circlep.x  <<   " , "   <<  circlep.y  <<   " ) " ;

        cout <<   " 半徑是: ( "   <<  circler  <<   " ) " ;

        cout <<   " 到另兩點的距離是: ( "   <<  dis2  <<   " , "   <<  dis3  <<   " ) " ;

         // break;

    }

     return   0 ;

}

 運作情況如下:

幾何問題圖解 2006.11.8 Xmxoxo

請輸入第1點坐标:158.25 352.25

請輸入第2點坐标:15.88 36.58

請輸入第3點坐标:78.06 105.43

第1點坐标是: (158.25,352.25)

第2點坐标是: (15.88,36.58)

第3點坐标是: (78.06,105.43)

p1,p2中點坐标是: (87.065,194.415)

P1,P2連線方程是: Y=(2.21725)X+(1.37006)

P2,P3連線方程是: Y=(1.10727)X+(18.9966)

P3,P1連線方程是: Y=(3.07794)X+(-134.834)

P1,P2連線的垂線方程是: Y=(-0.451009)X+(233.682)

P2,P3連線的垂線方程是: Y=(-0.903123)X+(113.425)

P3,P1連線的垂線方程是: Y=(-0.324893)X+(267.228)

圓心坐标是: (-265.989,353.646)

半徑是: (424.242)

到另兩點的距離是: (424.242,424.242)

這裡隻解出了三角形的外接圓,如果要得到内切圓,也很簡單,隻要計算經過任意兩個頂點的角平分線,

再計算這兩條角平分線的交點就可以了。另外還可以推算出三角形的面積,周長等,都隻是公式的應用,寫

成表達式就可以了。