HDU 6206 Apple【计算几何+高精度Java】
Problem Description
Apple is Taotao's favourite fruit. In his backyard, there are three apple trees with coordinates (x1,y1) , (x2,y2) , and (x3,y3) . Now Taotao is planning to plant a new one, but he is not willing to take these trees too close. He believes that the new apple tree should be outside the circle which the three apple trees that already exist is on. Taotao picked a potential position (x,y) of the new tree. Could you tell him if it is outside the circle or not?
Input
The first line contains an integer T , indicating that there are T(T≤30) cases.
In the first line of each case, there are eight integers x1,y1,x2,y2,x3,y3,x,y , as described above.
The absolute values of integers in input are less than or equal to 1,000,000,000,000 .
It is guaranteed that, any three of the four positions do not lie on a straight line.
In the first line of each case, there are eight integers x1,y1,x2,y2,x3,y3,x,y , as described above.
The absolute values of integers in input are less than or equal to 1,000,000,000,000 .
It is guaranteed that, any three of the four positions do not lie on a straight line.
Output
For each case, output "Accepted" if the position is outside the circle, or "Rejected" if the position is on or inside the circle.
Sample Input
3
-2 0 0 -2 2 0 2 -2
-2 0 0 -2 2 0 0 2
-2 0 0 -2 2 0 1 1
Sample Output
Accepted
Rejected
Rejected
Source
【题意】:给出四个点,问你第四个点是否在前三个点构成的圆内,若在圆外输出"Accepted",否则输出"Rejected",题目保证前三个点不在一条直线上。
【分析】:就是求出三个点外接圆的圆心和半径判断下。精度问题需要用Java大数。已知三点坐标,求外接圆圆心坐标与半径。三点构圆的圆心和半径是能够推导出公式的圆弧方向判断方法和三点确定一个圆的计算方法 高精度问题也只用BigInteger解决即可。
【彩蛋】:
实际上有更简便的方法,直接能用更直接的公式算出圆心 (x0, y0) 和半径的平方 r^2
x0 = ((y2-y1)*(y3*y3-y1*y1+x3*x3-x1*x1)-(y3-y1)*(y2*y2-y1*y1+x2*x2-x1*x1))/(2.0*((x3-x1)*(y2-y1)-(x2-x1)*(y3-y1)));
y0 = ((x2-x1)*(x3*x3-x1*x1+y3*y3-y1*y1)-(x3-x1)*(x2*x2-x1*x1+y2*y2-y1*y1))/(2.0*((y3-y1)*(x2-x1)-(y2-y1)*(x3-x1)));
r^2= (x1-x0)*(x1-x0)+(y1-y0)*(y1-y0);
里面涉及除法,那就用BigDecimal就能解决了,参考http://blog.csdn.net/cillyb/article/details/78012069
import java.math.*; import java.util.*; import java.io.*; public class Main{ public static void main(String[] args){ Scanner cin=new Scanner(System.in); int t=cin.nextInt(); while(t-->0) { BigDecimal px1, px2, px3, py1, py2, py3, px, py; px1=cin.nextBigDecimal(); py1=cin.nextBigDecimal(); px2=cin.nextBigDecimal(); py2=cin.nextBigDecimal(); px3=cin.nextBigDecimal(); py3=cin.nextBigDecimal(); px=cin.nextBigDecimal(); py=cin.nextBigDecimal(); BigDecimal a, b, c, d, e, f, px0, py0, r,dis; a=px1.subtract(px2); b=py1.subtract(py2); c=px1.subtract(px3); d=py1.subtract(py3); e=px1.multiply(px1).subtract(px2.multiply(px2)).multiply(BigDecimal.valueOf(0.5)).subtract(py2.multiply(py2).subtract(py1.multiply(py1)).multiply(BigDecimal.valueOf(0.5))); f=px1.multiply(px1).subtract(px3.multiply(px3)).multiply(BigDecimal.valueOf(0.5)).subtract(py3.multiply(py3).subtract(py1.multiply(py1)).multiply(BigDecimal.valueOf(0.5))); px0=b.multiply(f).subtract(d.multiply(e)).divide(b.multiply(c).subtract(a.multiply(d)),30,BigDecimal.ROUND_HALF_UP); py0=c.multiply(e).subtract(a.multiply(f)).divide(b.multiply(c).subtract(a.multiply(d)),30,BigDecimal.ROUND_HALF_UP); r=px1.subtract(px0).multiply(px1.subtract(px0)).add(py1.subtract(py0).multiply(py1.subtract(py0))); dis=px.subtract(px0).multiply(px.subtract(px0)).add(py.subtract(py0).multiply(py.subtract(py0))); if(dis.compareTo(r)==1) System.out.println("Accepted"); else System.out.println("Rejected"); } } }
import java.math.BigDecimal; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); BigDecimal x1, y1, x2, y2, x3, y3, x4, y4; int _; _ = sc.nextInt(); while(_-- != 0) { x1 = sc.nextBigDecimal(); y1 = sc.nextBigDecimal(); x2 = sc.nextBigDecimal(); y2 = sc.nextBigDecimal(); x3 = sc.nextBigDecimal(); y3 = sc.nextBigDecimal(); x4 = sc.nextBigDecimal(); y4 = sc.nextBigDecimal(); BigDecimal t; if(y3.equals(y1)) { t = y2; y2 = y3; y3 = t; t = x2; x2 = x3; x3 = t; } BigDecimal t1 = (y3.subtract(y1)).multiply(y2.multiply(y2).subtract(y1.multiply(y1))); BigDecimal t2 = (y3.subtract(y1)).multiply(x2.multiply(x2).subtract(x1.multiply(x1))); BigDecimal t3 = (y1.subtract(y2)).multiply(y1.multiply(y1).subtract(y3.multiply(y3))); BigDecimal t4 = (y1.subtract(y2)).multiply(x1.multiply(x1).subtract(x3.multiply(x3))); BigDecimal t5 = BigDecimal.valueOf(2).multiply(y1.subtract(y2)).multiply(x3.subtract(x1)); BigDecimal t6 = BigDecimal.valueOf(2).multiply(y3.subtract(y1)).multiply(x1.subtract(x2)); BigDecimal x0 = (t1.add(t2).subtract(t3).subtract(t4)).divide(t5.subtract(t6)); BigDecimal v1 = y3.multiply(y3); BigDecimal v2 = y1.multiply(y1); BigDecimal v3 = BigDecimal.valueOf(2).multiply(x0).multiply(x3.subtract(x1)); BigDecimal v4 = x1.multiply(x1); BigDecimal v5 = x3.multiply(x3); BigDecimal v6 = BigDecimal.valueOf(2).multiply(y3.subtract(y1)); // System.out.println(v6); BigDecimal y0 = (v1.subtract(v2).subtract(v3).subtract(v4).add(v5)).divide(v6); BigDecimal z1 = (y0.subtract(y2)).multiply(y0.subtract(y2)); BigDecimal z2 = (x0.subtract(x2)).multiply(x0.subtract(x2)); BigDecimal r = z1.add(z2); BigDecimal tmp1 = (x4.subtract(x0)).multiply(x4.subtract(x0)); BigDecimal tmp2 = (y4.subtract(y0)).multiply(y4.subtract(y0)); BigDecimal dis = tmp1.add(tmp2); if(dis.compareTo(r) > 0) { System.out.println("Accepted"); } else { System.out.println("Rejected"); } } } }