@@ -354,6 +354,48 @@ def fit_circle(x, y):
354
354
return x0 , y0 , radius , err
355
355
356
356
357
+ @njit (cache = True )
358
+ def fit_circle_ (x , y ):
359
+ """
360
+ From a polygon, function will fit a circle.
361
+
362
+ Must be call with local coordinates (in m, to get a radius in m).
363
+
364
+ .. math:: (x_i - x_0)^2 + (y_i - y_0)^2 = r^2
365
+ .. math:: x_i^2 - 2 x_i x_0 + x_0^2 + y_i^2 - 2 y_i y_0 + y_0^2 = r^2
366
+ .. math:: 2 x_0 x_i + 2 y_0 y_i + r^2 - x_0^2 - y_0^2 = x_i^2 + y_i^2
367
+
368
+ we get this linear equation
369
+
370
+ .. math:: a X + b Y + c = Z
371
+
372
+ where :
373
+
374
+ .. math:: a = 2 x_0 , b = 2 y_0 , c = r^2 - x_0^2 - y_0^2
375
+ .. math:: X = x_i , Y = y_i , Z = x_i^2 + y_i^2
376
+
377
+ Solutions:
378
+
379
+ .. math:: x_0 = a / 2 , y_0 = b / 2 , r = \\ sqrt{c + x_0^2 + y_0^2}
380
+
381
+
382
+ :param array x: x of polygon
383
+ :param array y: y of polygon
384
+ :return: x0, y0, radius, shape_error
385
+ :rtype: (float,float,float,float)
386
+ """
387
+ datas = ones ((x .shape [0 ] - 1 , 3 ))
388
+ # we skip first position which are the same than the last
389
+ datas [:, 0 ] = x [1 :]
390
+ datas [:, 1 ] = y [1 :]
391
+ # Linear regression
392
+ (a , b , c ), _ , _ , _ = lstsq (datas , x [1 :] ** 2 + y [1 :] ** 2 )
393
+ x0 , y0 = a / 2.0 , b / 2.0
394
+ radius = (c + x0 ** 2 + y0 ** 2 ) ** 0.5
395
+ err = shape_error (x , y , x0 , y0 , radius )
396
+ return x0 , y0 , radius , err
397
+
398
+
357
399
@njit (cache = True , fastmath = True )
358
400
def shape_error (x , y , x0 , y0 , r ):
359
401
"""
0 commit comments