1
2
3
4
5
6
7
8
9 package org.lcsim.fit.threepointcircle;
10
11 import static java.lang.Math.pow;
12 import static java.lang.Math.sqrt;
13
14
15
16
17 public class ThreePointCircleFitter
18 {
19 private CircleFit _fit;
20 private static double[][] a = {{0, 0, 0},{0, 0, 0},{0, 0, 0}};
21 private static double[][] m = {{0, 0, 0},{0, 0, 0},{0, 0, 0}};
22
23
24 public ThreePointCircleFitter()
25 {
26 }
27
28
29
30
31
32
33
34
35 public boolean fit(double[] p1, double[] p2, double[] p3)
36 {
37 int i;
38 double r, m11, m12, m13, m14;
39
40 double[][] P = {p1, p2, p3};
41
42 for (i = 0; i < 3; i++)
43 {
44 a[i][0] = P[i][0];
45 a[i][1] = P[i][1];
46 a[i][2] = 1;
47 }
48 m11 = determinant( a, 3 );
49 if(m11==0)
50 {
51 _fit = null;
52 return false;
53 }
54
55 for (i = 0; i < 3; i++)
56 {
57 a[i][0] = P[i][0]*P[i][0] + P[i][1]*P[i][1];
58 a[i][1] = P[i][1];
59 a[i][2] = 1;
60 }
61 m12 = determinant( a, 3 );
62
63 for (i = 0; i < 3; i++)
64 {
65 a[i][0] = P[i][0]*P[i][0] + P[i][1]*P[i][1];
66 a[i][1] = P[i][0];
67 a[i][2] = 1;
68 }
69 m13 = determinant( a, 3 );
70
71 for (i = 0; i < 3; i++)
72 {
73 a[i][0] = P[i][0]*P[i][0] + P[i][1]*P[i][1];
74 a[i][1] = P[i][0];
75 a[i][2] = P[i][1];
76 }
77 m14 = determinant( a, 3 );
78
79 double x0 = 0.5 * m12 / m11;
80 double y0 = -0.5 * m13 / m11;
81 r = sqrt( x0*x0 + y0*y0 + m14/m11 );
82
83 _fit = new CircleFit(x0, y0, r);
84
85 return true;
86 }
87
88
89
90
91
92 public CircleFit getFit()
93 {
94 return _fit;
95 }
96
97
98 private double determinant(double[][] a, int n)
99 {
100 int i, j, j1, j2;
101 double d = 0.;
102
103 if (n == 2)
104 {
105 d = a[0][0]*a[1][1] - a[1][0]*a[0][1];
106 }
107 else
108 {
109 d = 0;
110 for (j1 = 0; j1 < n; ++j1 )
111 {
112 for (i = 1; i < n; ++i)
113 {
114 j2 = 0;
115 for (j = 0; j < n; ++j)
116 {
117 if (j == j1) continue;
118 m[i-1][j2] = a[i][j];
119 j2++;
120 }
121 }
122
123 d += pow(-1.0, j1)*a[0][j1]*determinant( m, n-1 );
124 }
125 }
126 return d;
127 }
128 }