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;
}


/*
已知两点,求连线中点坐标
---------------------------------
两点(x1,y1),(x2,y2)的连线中点坐标
((x1+x2)/2,(y1+y2)/2)
*/
point midpoint(point p1, point p2)
{
    point ret;
    ret.x 
=  (p1.x  +  p2.x ) / 2 ;
    ret.y 
=  (p1.y  +  p2.y ) / 2 ;
    
return  ret;
}

/*
已知两点,求连线方程
-------------------------------------
两点(x1,y1),(x2,y2)的连线方程表示成Y=ax+b
a=(y1-y2)/(x1-x2)

b= y2 - x2*a
或者
b= y1- x1*a
-------------------------------------

*/
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 ;
    }
}

/*
已知两直线,求交点坐标
两条直线

y1=ax+b
y2=cx+d
求交点
a<>c时有交点(不平行)
y1=y2时
=> ax+b=cx+d
=> x=(d-b)/(a-c)

x1=x2 时
y=(ad-cb)/(a-c)

交点坐标是( (d-b)/(a-c),(ad-cb)/(a-c))
*/
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;
}

/*
求斜率为k的直线,转过n弧度后,且经过某一点的方程
*/
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;
}

/*
-------------------------------------
直线Y=ax+b 与X轴夹角是
atan((-b)/a)
转90度只要加上90度(3.14/2)就可以了
---------------------------------
*/

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)

这里只解出了三角形的外接圆,如果要得到内切圆,也很简单,只要计算经过任意两个顶点的角平分线,

再计算这两条角平分线的交点就可以了。另外还可以推算出三角形的面积,周长等,都只是公式的应用,写

成表达式就可以了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值