题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6206
判断给定一点是否在三角形外接圆内。
给定三角形三个顶点的坐标,如何求三角形的外心的坐标呢?
知乎链接:https://www.zhihu.com/question/40422123/answer/86514178
例如 :给定a(x1,y1) b(x2,y2) c(x3,y3)求外接圆心坐标O(x,y)
1. 首先,外接圆的圆心是三角形三条边的垂直平分线的交点,我们根据圆心到顶点的距离相等,可以列出以下方程:
(x1-x)*(x1-x)+(y1-y)*(y1-y)=(x2-x)*(x2-x)+(y2-y)*(y2-y);
(x2-x)*(x2-x)+(y2-y)*(y2-y)=(x3-x)*(x3-x)+(y3-y)*(y3-y);
2.化简得到:
2*(x2-x1)*x+2*(y2-y1)y=x2^2+y2^2-x1^2-y1^2;
2*(x3-x2)*x+2*(y3-y2)y=x3^2+y3^2-x2^2-y2^2;
令:A1=2*(x2-x1);
B1=2*(y2-y1);
C1=x2^2+y2^2-x1^2-y1^2;
A2=2*(x3-x2);
B2=2*(y3-y2);
C2=x3^2+y3^2-x2^2-y2^2;
即:A1*x+B1y=C1;
A2*x+B2y=C2;
3.最后根据克拉默法则:
x=((C1*B2)-(C2*B1))/((A1*B2)-(A2*B1));
y=((A1*C2)-(A2*C1))/((A1*B2)-(A2*B1));
所以x,y为圆心坐标。
然后最后r^2 = (x1-x)*(x1-x)+(y1-y)*(y1-y)就好了。
C++卡double,换成Java写,用BigDecimal写。
1 import java.io.*;
2 import java.math.BigDecimal;
3 import java.math.BigInteger;
4 import java.util.*;
5
6
7 public class Main {
8
9 final static BigInteger HUNDRED = BigInteger.valueOf(100);
10
11 //叉乘求面积
12 /* private static BigDecimal TriangleArea(POINT pi,POINT pj,POINT pk)
13 {
14 BigDecimal num1 = (pj.x.subtract(pi.x)).multiply(pk.y.subtract(pi.y));
15 BigDecimal num2 = (pk.x.subtract(pi.x)).multiply(pj.y.subtract(pi.y));
16 BigDecimal num3 = (num1.subtract(num2)).abs();
17 BigDecimal two = new BigDecimal("2.0");
18 return num3.divide(two);
19 }*/
20 //平方
21 private static BigDecimal pinfang(BigDecimal x)
22 {
23 return x.multiply(x);
24 }
25
26 //求长度
27 private static BigDecimal Dis(POINT a,POINT b)
28 {
29 return pinfang(a.x.subtract(b.x)).add(pinfang(a.y.subtract(b.y)));
30 }
31
32 public static void main(String[] args) {
33 // TODO 自动生成的方法存根
34 Scanner cin=new Scanner(System.in);
35 int T = cin.nextInt();
36 for(int i=1;i<=T;i++)
37 {
38 POINT A = new POINT();
39 POINT B = new POINT();
40 POINT C = new POINT();
41 POINT D = new POINT();
42
43 A.x = cin.nextBigDecimal();
44 A.y = cin.nextBigDecimal();
45 B.x = cin.nextBigDecimal();
46 B.y = cin.nextBigDecimal();
47 C.x = cin.nextBigDecimal();
48 C.y = cin.nextBigDecimal();
49 D.x = cin.nextBigDecimal();
50 D.y = cin.nextBigDecimal();
51
52 BigDecimal two = new BigDecimal("2.0");
53 BigDecimal four = new BigDecimal("4.0");
54
55 //求圆心
56 BigDecimal c1 = ((pinfang(A.x).add(pinfang(A.y))).subtract(pinfang(B.x).add(pinfang(B.y)))).divide(two);
57 BigDecimal c2 = ((pinfang(A.x).add(pinfang(A.y))).subtract(pinfang(C.x).add(pinfang(C.y)))).divide(two);
58
59 POINT center = new POINT();
60 center.x = (c1.multiply((A.y.subtract(C.y)))).subtract(c2.multiply(A.y.subtract(B.y)));
61 BigDecimal tmp = ((A.x.subtract(B.x)).multiply(A.y.subtract(C.y))).subtract((A.x.subtract(C.x)).
62 multiply(A.y.subtract(B.y)));
63 center.x = center.x.divide(tmp);
64 center.y = (c1.multiply((A.x.subtract(C.x)))).subtract(c2.multiply(A.x.subtract(B.x)));
65 tmp = ((A.y.subtract(B.y)).multiply(A.x.subtract(C.x))).subtract((A.y.subtract(C.y)).
66 multiply(A.x.subtract(B.x)));
67 center.y = center.y.divide(tmp);
68 //求半径
69 BigDecimal r2 = pinfang(A.x.subtract(center.x)).add(pinfang(A.y.subtract(center.y)));
70 //圆心到D点距离
71 BigDecimal tempr = pinfang(D.x.subtract(center.x)).add(pinfang(D.y.subtract(center.y)));
72
73 if(tempr.compareTo(r2)<=0)
74 {
75 System.out.println ("Rejected");
76 }
77 else
78 {
79 System.out.println ("Accepted");
80 }
81 }
82 }
83 }
84
85
86
87 class POINT
88 {
89
90 BigDecimal x;
91 BigDecimal y;
92 }
93
94 /*
95 41
96 0 0 1 1 2 0 2 0
97 -2 0 0 -2 2 0 2 -2
98 -2 0 0 -2 2 0 0 2
99 -2 0 0 -2 2 0 1 1
100 */