1
#include<stdio.h>
2
#include<math.h>
3
4
const double eps=1e-6;
5
6
//点(x,y)
7
typedef struct
8

{
9
double x,y;
10
} Point;
11
12
//直线方程ax+by+c=0
13
typedef struct
14

{
15
double a,b,c;
16
} Line;
17
18
//圆的标准方程(x-center.x)^2+(y-center.y)^2=r^2
19
typedef struct
20

{
21
Point center;
22
double r;
23
} Circle;
24
25
//浮点数符号函数
26
int DblCmp(double d)
27

{
28
if(fabs(d)<eps) return 0;
29
else return d>0?1:-1;
30
}
31
32
//线段AB的中点C
33
Point MidPoint(Point A,Point B)
34

{
35
Point C;
36
C.x=(A.x+B.x)/2;
37
C.y=(A.y+B.y)/2;
38
return C;
39
}
40
41
//点A到点B的距离
42
double Dist(Point A,Point B)
43

{
44
return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
45
}
46
47
//∠ACB的弧度值
48
double Angle(Point A,Point B,Point C)
49

{
50
double a,b,c;
51
a=Dist(B,C);
52
b=Dist(A,C);
53
c=Dist(A,B);
54
return acos((a*a+b*b-c*c)/(2*a*b));
55
}
56
57
//二维向量a=(x1,y1)与b=(x2,y2)的叉积的数值
58
double Det(double x1,double y1,double x2,double y2)
59

{
60
return x1*y2-x2*y1;
61
}
62
63
//二维向量的叉积AB*AC的数值
64
double Cross(Point A,Point B,Point C)
65

{
66
return Det(B.x-A.x,B.y-A.y,C.x-A.x,C.y-A.y);
67
}
68
69
//二维向量a=(x1,y1)与b=(x2,y2)的点积
70
double DotDet(double x1,double y1,double x2,double y2)
71

{
72
return x1*x2+y1*y2;
73
}
74
75
//二维向量的点积AB·AC
76
double Dot(Point A,Point B,Point C)
77

{
78
return DotDet(B.x-A.x,B.y-A.y,C.x-A.x,C.y-A.y);
79
}
80
81
//点A与B或C重合时为0,点A在BC内部时为-1,点A在BC外部时为1
82
int BetweenCmp(Point A,Point B,Point C)
83

{
84
return DblCmp(Dot(A,B,C));
85
}
86
87
//线段AB,CD规范相交则返回1,并求交点P;不规范相交则返回2;没有交点则返回0
88
int SegsCross(Point A,Point B,Point C,Point D,Point &P)
89

{
90
double s1,s2,s3,s4;
91
int d1,d2,d3,d4;
92
d1=DblCmp(s1=Cross(A,B,C));
93
d2=DblCmp(s2=Cross(A,B,D));
94
d3=DblCmp(s3=Cross(C,D,A));
95
d4=DblCmp(s4=Cross(C,D,B));
96
if(((d1^d2)==-2)&&((d3^d4)==-2))
97
{
98
P.x=(C.x*s2-D.x*s1)/(s2-s1);
99
P.y=(C.y*s2-D.y*s1)/(s2-s1);
100
return 1;
101
}
102
if(((d1==0)&&(BetweenCmp(C,A,B)<=0))||
103
((d2==0)&&(BetweenCmp(D,A,B)<=0))||
104
((d3==0)&&(BetweenCmp(A,C,D)<=0))||
105
((d4==0)&&(BetweenCmp(B,C,D)<=0)))
106
return 2;
107
else return 0;
108
}
109
110
//直线L1,L2相交则返回1,并求交点P;重合则返回2,平行则返回0;
111
int LinesCross(Line L1,Line L2,Point &P)
112

{
113
double d1=Det(L1.a,L1.b,L2.a,L2.b),d2=Det(L1.b,L1.c,L2.b,L2.c),d3=Det(L1.a,L1.c,L2.a,L2.c);
114
int x=DblCmp(d1),y=DblCmp(d2);
115
if(x==0&&y==0) return 2;
116
else if(x==0&&y!=0) return 0;
117
else
118
{
119
P.x=d2/d1;
120
P.y=-d3/d1;
121
return 1;
122
}
123
}
124
125
//两点式:AB构造直线L
126
Line LineFromSegs(Point A,Point B)
127

{
128
Line L;
129
L.a=B.y-A.y;
130
L.b=A.x-B.x;
131
L.c=B.x*A.y-A.x*B.y;
132
return L;
133
}
134
135
//点斜式:A及方位向量dir构造直线L
136
Line LineFromPointAndSlope(Point A,Point dir)
137

{
138
Line L;
139
if(dir.x==0)
140
{
141
L.a=1;
142
L.b=0;
143
L.c=-A.x;
144
}
145
else
146
{
147
double k=dir.y/dir.x;
148
L.a=k;
149
L.b=-1;
150
L.c=A.y-k*A.x;
151
}
152
return L;
153
}
154
155
//两点A,B构造垂直平分线L
156
Line PerbisecFromSegs(Point A,Point B)
157

{
158
Line AB=LineFromSegs(A,B),L;
159
Point C=MidPoint(A,B),dir;
160
dir.x=B.y-A.y;dir.y=A.x-B.x;
161
L=LineFromPointAndSlope(C,dir);
162
return L;
163
}
164
165
//三点A,B,C构造圆O
166
Circle CirFromPoints(Point A,Point B,Point C)
167

{
168
Circle O;
169
double c=Dist(A,B),ACB=Angle(A,B,C);
170
O.r=c/(2*sin(ACB));
171
Line DO=PerbisecFromSegs(A,B),EO=PerbisecFromSegs(B,C);
172
Point P;
173
if(LinesCross(DO,EO,P)==1) O.center=P;
174
return O;
175
}
posted on 2009-04-14 10:58
姚冰 阅读(456)
评论(0) 编辑 收藏 引用