Как только я получу координаты трехмерной точки, какой алгоритм мне использовать, чтобы подобрать оптимальный цилиндр и получить вектор направления и радиус центральной оси?

Моя предыдущая идея заключалась в том, чтобы разделить цилиндр на слои, и по мере увеличения количества слоев фигура, образованная точками, приближалась к цилиндру, но в этом случае я не мог получить точный радиус цилиндра. (Центральная ось получается путем подгонки центра круга через каждый слой)
Пожалуйста, уточните вашу конкретную проблему или предоставьте дополнительную информацию, чтобы выделить именно то, что вам нужно. Поскольку сейчас написано, трудно точно сказать, о чем вы спрашиваете.
Ваша выставка представляет собой оптическую иллюзию.






Вот ось MCVE для регрессии, определяемая p0 и p1 (векторами) и радиусом R (скаляром).
Сначала мы создаем фиктивный набор данных:
import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
from scipy.spatial.transform import Rotation
def cylinder(n=60, m=20, r=2, h=5):
t = np.linspace(0, m * 2 * np.pi, m * n)
z = np.linspace(0, h, m * n)
x = r * np.cos(t)
y = r * np.sin(t)
return np.stack([x, y, z]).T
X = cylinder()
rot = Rotation.from_rotvec(np.array([-1, 2, 0.5]))
x0 = np.array([1., 2., 0.])
X = rot.apply(X)
X = X + x0
Это создает общий вариант использования, включая сдвиг происхождения.
Теперь достаточно записать геометрическое уравнение (см. уравнение 10) в виде остатков и минимизировать его по методу наименьших квадратов.
def residuals(p, xyz):
return np.power(np.linalg.norm(np.cross((xyz - p[0:3]), (xyz - p[3:6])), axis=1) / np.linalg.norm((p[3:6] - p[0:3])), 2) - p[6] ** 2
p, res = optimize.leastsq(residuals, x0=[0., 0., 0., 1., 1., 1., 0.], args=(X,), full_output=False)
Что в данном случае возвращает:
# array([ -1.8283916 , -1.65918186, 3.29901757, # p0
# 20.31455462, 26.98786514, -22.52837088, # p1
# 2. ]) # R
Графически это приводит к:
Добро пожаловать в SO, не могли бы вы предоставить набор данных в виде ссылки (без снимка экрана).