@@ -354,6 +354,48 @@ def fit_circle(x, y):
354354 return x0, y0, radius, err
355355
356356
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+
357399@njit(cache=True, fastmath=True)
358400def shape_error(x, y, x0, y0, r):
359401 """
0 commit comments