42
42
namespace cv
43
43
{
44
44
45
- // inner product
46
- static float innerProduct (Point2f &v1, Point2f &v2)
47
- {
48
- return v1.x * v2.y - v1.y * v2.x ;
49
- }
45
+ const float EPS = 1 .0e-4f ;
50
46
51
47
static void findCircle3pts (Point2f *pts, Point2f ¢er, float &radius)
52
48
{
53
49
// two edges of the triangle v1, v2
54
50
Point2f v1 = pts[1 ] - pts[0 ];
55
51
Point2f v2 = pts[2 ] - pts[0 ];
56
52
57
- if (innerProduct (v1, v2) == 0 .0f )
58
- {
59
- // v1, v2 colineation, can not determine a unique circle
60
- // find the longtest distance as diameter line
61
- float d1 = (float )norm (pts[0 ] - pts[1 ]);
62
- float d2 = (float )norm (pts[0 ] - pts[2 ]);
63
- float d3 = (float )norm (pts[1 ] - pts[2 ]);
64
- if (d1 >= d2 && d1 >= d3)
65
- {
66
- center = (pts[0 ] + pts[1 ]) / 2 .0f ;
67
- radius = (d1 / 2 .0f );
68
- }
69
- else if (d2 >= d1 && d2 >= d3)
70
- {
71
- center = (pts[0 ] + pts[2 ]) / 2 .0f ;
72
- radius = (d2 / 2 .0f );
73
- }
74
- else if (d3 >= d1 && d3 >= d2)
75
- {
76
- center = (pts[1 ] + pts[2 ]) / 2 .0f ;
77
- radius = (d3 / 2 .0f );
78
- }
79
- }
80
- else
81
- {
82
- // center is intersection of midperpendicular lines of the two edges v1, v2
83
- // a1*x + b1*y = c1 where a1 = v1.x, b1 = v1.y
84
- // a2*x + b2*y = c2 where a2 = v2.x, b2 = v2.y
85
- Point2f midPoint1 = (pts[0 ] + pts[1 ]) / 2 .0f ;
86
- float c1 = midPoint1.x * v1.x + midPoint1.y * v1.y ;
87
- Point2f midPoint2 = (pts[0 ] + pts[2 ]) / 2 .0f ;
88
- float c2 = midPoint2.x * v2.x + midPoint2.y * v2.y ;
89
- float det = v1.x * v2.y - v1.y * v2.x ;
90
- float cx = (c1 * v2.y - c2 * v1.y ) / det;
91
- float cy = (v1.x * c2 - v2.x * c1) / det;
92
- center.x = (float )cx;
93
- center.y = (float )cy;
94
- cx -= pts[0 ].x ;
95
- cy -= pts[0 ].y ;
96
- radius = (float )(std::sqrt (cx *cx + cy * cy));
97
- }
98
- }
99
-
100
- const float EPS = 1 .0e-4f ;
101
-
102
- static void findEnclosingCircle3pts_orLess_32f (Point2f *pts, int count, Point2f ¢er, float &radius)
103
- {
104
- switch (count)
105
- {
106
- case 1 :
107
- center = pts[0 ];
108
- radius = 0 .0f ;
109
- break ;
110
- case 2 :
111
- center.x = (pts[0 ].x + pts[1 ].x ) / 2 .0f ;
112
- center.y = (pts[0 ].y + pts[1 ].y ) / 2 .0f ;
113
- radius = (float )(norm (pts[0 ] - pts[1 ]) / 2.0 );
114
- break ;
115
- case 3 :
116
- findCircle3pts (pts, center, radius);
117
- break ;
118
- default :
119
- break ;
120
- }
121
-
122
- radius += EPS;
53
+ // center is intersection of midperpendicular lines of the two edges v1, v2
54
+ // a1*x + b1*y = c1 where a1 = v1.x, b1 = v1.y
55
+ // a2*x + b2*y = c2 where a2 = v2.x, b2 = v2.y
56
+ Point2f midPoint1 = (pts[0 ] + pts[1 ]) / 2 .0f ;
57
+ float c1 = midPoint1.x * v1.x + midPoint1.y * v1.y ;
58
+ Point2f midPoint2 = (pts[0 ] + pts[2 ]) / 2 .0f ;
59
+ float c2 = midPoint2.x * v2.x + midPoint2.y * v2.y ;
60
+ float det = v1.x * v2.y - v1.y * v2.x ;
61
+ float cx = (c1 * v2.y - c2 * v1.y ) / det;
62
+ float cy = (v1.x * c2 - v2.x * c1) / det;
63
+ center.x = (float )cx;
64
+ center.y = (float )cy;
65
+ cx -= pts[0 ].x ;
66
+ cy -= pts[0 ].y ;
67
+ radius = (float )(std::sqrt (cx *cx + cy * cy)) + EPS;
123
68
}
124
69
125
70
template <typename PT>
@@ -145,7 +90,7 @@ static void findThirdPoint(const PT *pts, int i, int j, Point2f ¢er, float &
145
90
ptsf[0 ] = (Point2f)pts[i];
146
91
ptsf[1 ] = (Point2f)pts[j];
147
92
ptsf[2 ] = (Point2f)pts[k];
148
- findEnclosingCircle3pts_orLess_32f (ptsf, 3 , center, radius);
93
+ findCircle3pts (ptsf, center, radius);
149
94
}
150
95
}
151
96
}
@@ -210,8 +155,6 @@ void cv::minEnclosingCircle( InputArray _points, Point2f& _center, float& _radiu
210
155
Mat points = _points.getMat ();
211
156
int count = points.checkVector (2 );
212
157
int depth = points.depth ();
213
- Point2f center;
214
- float radius = 0 .f ;
215
158
CV_Assert (count >= 0 && (depth == CV_32F || depth == CV_32S));
216
159
217
160
_center.x = _center.y = 0 .f ;
@@ -224,52 +167,62 @@ void cv::minEnclosingCircle( InputArray _points, Point2f& _center, float& _radiu
224
167
const Point* ptsi = points.ptr <Point>();
225
168
const Point2f* ptsf = points.ptr <Point2f>();
226
169
227
- // point count <= 3
228
- if (count <= 3 )
170
+ switch (count)
229
171
{
230
- Point2f ptsf3[3 ];
231
- for (int i = 0 ; i < count; ++i)
172
+ case 1 :
232
173
{
233
- ptsf3[i] = (is_float) ? ptsf[i] : Point2f ((float )ptsi[i].x , (float )ptsi[i].y );
174
+ _center = (is_float) ? ptsf[0 ] : Point2f ((float )ptsi[0 ].x , (float )ptsi[0 ].y );
175
+ _radius = EPS;
176
+ break ;
234
177
}
235
- findEnclosingCircle3pts_orLess_32f (ptsf3, count, center, radius);
236
- _center = center;
237
- _radius = radius;
238
- return ;
239
- }
240
-
241
- if (is_float)
242
- {
243
- findMinEnclosingCircle<Point2f>(ptsf, count, center, radius);
244
- #if 0
245
- for (size_t m = 0; m < count; ++m)
178
+ case 2 :
246
179
{
247
- float d = (float)norm(ptsf[m] - center);
248
- if (d > radius)
249
- {
250
- printf("error!\n");
251
- }
180
+ Point2f p1 = (is_float) ? ptsf[0 ] : Point2f ((float )ptsi[0 ].x , (float )ptsi[0 ].y );
181
+ Point2f p2 = (is_float) ? ptsf[1 ] : Point2f ((float )ptsi[1 ].x , (float )ptsi[1 ].y );
182
+ _center.x = (p1.x + p2.x ) / 2 .0f ;
183
+ _center.y = (p1.y + p2.y ) / 2 .0f ;
184
+ _radius = (float )(norm (p1 - p2) / 2.0 ) + EPS;
185
+ break ;
252
186
}
253
- #endif
254
- }
255
- else
256
- {
257
- findMinEnclosingCircle<Point>(ptsi, count, center, radius);
258
- #if 0
259
- for (size_t m = 0; m < count; ++m)
187
+ default :
260
188
{
261
- double dx = ptsi[m].x - center.x;
262
- double dy = ptsi[m].y - center.y;
263
- double d = std::sqrt(dx * dx + dy * dy);
264
- if (d > radius)
189
+ Point2f center;
190
+ float radius = 0 .f ;
191
+ if (is_float)
192
+ {
193
+ findMinEnclosingCircle<Point2f>(ptsf, count, center, radius);
194
+ #if 0
195
+ for (size_t m = 0; m < count; ++m)
196
+ {
197
+ float d = (float)norm(ptsf[m] - center);
198
+ if (d > radius)
199
+ {
200
+ printf("error!\n");
201
+ }
202
+ }
203
+ #endif
204
+ }
205
+ else
265
206
{
266
- printf("error!\n");
207
+ findMinEnclosingCircle<Point>(ptsi, count, center, radius);
208
+ #if 0
209
+ for (size_t m = 0; m < count; ++m)
210
+ {
211
+ double dx = ptsi[m].x - center.x;
212
+ double dy = ptsi[m].y - center.y;
213
+ double d = std::sqrt(dx * dx + dy * dy);
214
+ if (d > radius)
215
+ {
216
+ printf("error!\n");
217
+ }
218
+ }
219
+ #endif
267
220
}
221
+ _center = center;
222
+ _radius = radius;
223
+ break ;
268
224
}
269
- #endif
270
225
}
271
- _center = center;
272
- _radius = radius;
273
226
}
274
227
275
228
0 commit comments