给你提供两个方法:
1.一个程序直接求
/* 用 途:求不共线的三点确定一个圆
输 入:三个点p1,p2,p3
返回值:如果三点共线,返回false;反之,返回true。圆心由q返回,半径由r返回
*/
bool cocircle(POINT p1,POINT p2,POINT p3,POINT &q,double &r)
{
double x12=p2.x-p1.x;
double y12=p2.y-p1.y;
double x13=p3.x-p1.x;
double y13=p3.y-p1.y;
double z2=x12*(p1.x+p2.x)+y12*(p1.y+p2.y);
double z3=x13*(p1.x+p3.x)+y13*(p1.y+p3.y);
double d=2.0*(x12*(p3.y-p2.y)-y12*(p3.x-p2.x));
if(abs(d) <EP) //共线,圆不存在
return false;
q.x=(y13*z2-y12*z3)/d;
q.y=(x12*z3-x13*z2)/d;
r=dist(p1,q);
return true;
}
向量的旋转
在2-D的迪卡尔坐标系中,一个位置向量的旋转公式可以由三角函数的几何意义推出。比如上图所示是位置向量R逆时针旋转角度B前后的情况。在左图中,我们有关系:
x0 = |R| * cosA
y0 = |R| * sinA
=>
cosA = x0 / |R|
sinA = y0 / |R|
在右图中,我们有关系:
x1 = |R| * cos(A+B)
y1 = |R| * sin(A+B)
其中(x1, y1)就是(x0, y0)旋转角B后得到的点,也就是位置向量R最后指向的点。我们展开cos(A+B)和sin(A+B),得到
x1 = |R| * (cosAcosB - sinAsinB)
y1 = |R| * (sinAcosB + cosAsinB)
现在把
cosA = x0 / |R|
sinA = y0 / |R|
代入上面的式子,得到
x1 = |R| * (x0 * cosB / |R| - y0 * sinB / |R|)
y1 = |R| * (y0 * cosB / |R| + x0 * sinB / |R|)
=>
x1 = x0 * cosB - y0 * sinB
y1 = x0 * sinB + y0 * cosB
这样我们就得到了2-D迪卡尔坐标下向量围绕圆点的逆时针旋转公式。顺时针旋转就把角度变为负:
x1 = x0 * cos(-B) - y0 * sin(-B)
y1 = x0 * sin(-B) + y0 * cos(-B)
=>
x1 = x0 * cosB + y0 * sinB
y1 = -x0 * sinB + y0 * cosB
现在我要把这个旋转公式写成矩阵的形式,有一个概念我简单提一下,平面或空间里的每个线性变换(这里就是旋转变换)都对应一个矩阵,叫做变换矩阵。对一个点实施线性变换就是通过乘上该线性变换的矩阵完成的。好了,打住,不然就跑题了。
所以2-D旋转变换矩阵就是:
[cosA sinA] [cosA -sinA]
[-sinA cosA] 或者 [sinA cosA]
我们对点进行旋转变换可以通过矩阵完成,比如我要点(x, y)绕原点逆时针旋转:
[cosA sinA][x, y] x [-sinA cosA] = [x*cosA-y*sinA x*sinA+y*cosA]
为了编程方便,我们把它写成两个方阵
[x, y] [cosA sinA] [x*cosA-y*sinA x*sinA+y*cosA]
[0, 0] x [-sinA cosA] = [0 0 ]
也可以写成
[cosA -sinA] [x 0] [x*cosA-y*sinA 0]
[sinA cosA] x [y 0] = [x*sinA+y*cosA 0]
三、2-D的绕任一点旋转
下面我们深入一些,思考另一种情况:求一个点围绕任一个非原点的中心点旋转。
我们刚刚导出的公式是围绕原点旋转的公式,所以我们要想继续使用它,就要把想要围绕的那个非原点的中心点移动到原点上来。按照这个思路,我们先将该中心点通过一个位移向量移动到原点,而围绕点要保持与中心点相对位置不变,也相应的按照这个位移向量位移,此时由于中心点已经移动到了圆点,就可以让同样位移后的围绕点使用上面的公式来计算旋转后的位置了,计算完后,再让计算出的点按刚才的位移向量 逆位移,就得到围绕点绕中心点旋转一定角度后的新位置了。看下面的图

在这个过程中,我们对围绕点进行了三次线性变换:位移变换-旋转变换-位移变换,我们把它写成矩阵形式:
设红色向量为(rtx, rty)
[x y 1] [1 0 0] [cosA sinA 0] [1 0 0] [x' y' -]
[0 1 0] x [0 1 0] x [-sinA cosA 0] x [0 1 0] = [- - -]
[0 0 1] [rtx rty 1] [0 0 1] [-rtx -rty 1] [- - -]
最后得到的矩阵的x'和y'就是我们旋转后的点坐标。