I♥TLE

Java、オンラインジャッジなど

0010-Circumscribed Circle of a Triangle

実装の概要

三角形ABCの外接円の中心は、AB,BC,CAの交点にあります。もちろんこの中の2つの直線を選んで計算すれば十分です。
この実装では方程式そのものを表すクラスと連立方程式の計算を行うクラスを準備しています。
できれば既存のAPIを使いたかったのですが、Line2Dクラスのメソッドでは2直線が交わるかどうかは判断できますが具体的な交点までは返してくれないようです。
なお、問題の指示の通り、四捨五入に注意してください。

public class Main {
 
    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
        int n = Integer.parseInt(br.readLine());
 
        for(int i = 0;i < n ; i++){
            String[] tmpStr = br.readLine().split(" ");
 
            double[] input = new double[6];
            for(int j = 0; j < tmpStr.length ; j++){
                input[j] = Double.parseDouble(tmpStr[j]);
            }
 
            //点A,Bの中点
            Point2D.Double p1 = new Point2D.Double((input[0] + input[2])/2, (input[1] + input[3])/2);
            //点B,Cの中点
            Point2D.Double p2 = new Point2D.Double((input[2] + input[4])/2, (input[3] + input[5])/2);
            //線分ABおよびBCと垂直な傾きを計算
            double a1 = -1/((input[1]-input[3])/(input[0]-input[2]));
            double a2 = -1/((input[3]-input[5])/(input[2]-input[4]));
 
 
            Equation e1 = new Equation(a1, -1, (a1*p1.x - p1.y));
            if(input[1] == input[3]){
                e1 = new Equation(1, 0, p1.x);
            }
            Equation e2 = new Equation(a2, -1, (a2*p2.x - p2.y));
            if(input[3] == input[5]){
                e2 = new Equation(1, 0, p2.x);
            }
 
            Point2D.Double center = Calc.solveEquation(e1, e2);
 
            System.out.printf("%.3f %.3f %.3f\n",Calc.round(center.getX()), Calc.round(center.getY()), Calc.round(center.distance(input[0], input[1])));
        }
    }
 
}
 
class Equation {
    double a;
    double b;
    double c;
 
    public Equation(double a, double b, double c){
        this.a = a;
        this.b = b;
        this.c = c;
    }
}

class Calc {
 
    public static Point2D.Double solveEquation (Equation e1, Equation e2) {
        double[] input = new double[6];
        double[] reverse = new double[6];
 
        input[0] = reverse[3] = e1.a;
        input[1] = reverse[4] = e1.b;
        input[2] = reverse[5] = e1.c;
        input[3] = reverse[0] = e2.a;
        input[4] = reverse[1] = e2.b;
        input[5] = reverse[2] = e2.c;

        //a1 = 0の場合は2式を交換
        if(input[0] == 0){
            for(int i = 0; i < 6; i++){
                input[i] = reverse[i];
            }
        }

        double k = input[3]/input[0];
        input[3] = 0;
        input[4] -= input[1]*k;
        input[5] -= input[2]*k;
 
        double k2 = input[4];
        input[4] = 1;
        input[5] /= k2;
 
        double k3 = input[1];
        input[1] = 0;
        input[2] -= input[5]*k3;
 
        input[2] /= input[0];
        input[0] = 1;
 
        //System.out.printf("%.3f %.3f\n", input[2], input[5]);
        return new Point2D.Double(input[2], input[5]);
    }
 
    public static double round(double a){
        double result = (double)Math.round(a*1000)/1000;
        return result;
    }
}