在论坛里看到了这个问题,基本上都是平面几何里的问题。把点,线做成了结构。
//
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 ;
}
// 已知三点 求过这三点的圆心坐标和圆的半径
// 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)
这里只解出了三角形的外接圆,如果要得到内切圆,也很简单,只要计算经过任意两个顶点的角平分线,
再计算这两条角平分线的交点就可以了。另外还可以推算出三角形的面积,周长等,都只是公式的应用,写
成表达式就可以了。