2015-03-30 6 views
2

Я пытаюсь установить плоскость в набор точек в трехмерном пространстве. Сначала я попробовал исчерпывающие наименьшие квадраты, но это оказалось слишком медленным. Я читал, что наиболее эффективным решением будет выполнение сингулярного декомпозирования.Установка плоскости на множество точек с использованием сингулярного значения Разложение

Математика для этого вне меня, но я нашел массу ресурсов, чтобы попытаться заставить это работать.

В соответствии с ответом в this post, мне нужно вычислить центроид точек, вычесть центроид из всех точек, поместить их в матрицу 3xN и выполнить SVD. Затем я беру левый сингулярный вектор как нормаль для плоскости.

Пока все хорошо.

Я нашел библиотеку математики C# под названием alglib, которая имеет функцию SVD. Определение алгоритма можно найти here. Здесь возникают проблемы, так как в дополнение к матрице точек данных требуется еще две матрицы, и я не совсем понимаю, что вкладывать в них. Я побежал этот код независимо:

Vector3 centroid = getCentroid(planeVerts); 
    double[,] dataMat = substractCentroid(planeVerts, centroid); 
    double[] w = new double[3]; 
    double[,] u = new double[1,1]; 
    double[,] t = new double[1, 1]; 

    bool a = alglib.svd.rmatrixsvd(dataMat, 3, planeVerts.Length, 0, 0, 2, ref w, ref u, ref t); 

    Vector3 planeNorm = new Vector3((float) w[0], (float) w[1], (float) w[2]); 

Таким образом, в теории, я думал, что «вес» будет содержать мой самолет нормально, но, к сожалению, это не (я представил его в Unity3D, и это было под неправильным углом). Матрицы «u» и «t» - это те, которые меня пугают, и я действительно не знаю, к чему я должен их устанавливать.

Подробный API для функции rmatrixsvd можно найти here.

Есть ли какие-либо математики или ветераны алгоритмов, которые могли бы поделиться своими знаниями по этому вопросу? Мне нужно использовать C#, поскольку мой проект находится в Unity3D. Я буду рад предоставить дополнительную информацию в случае необходимости.

ответ

2

Оглядываясь на документацию, это выглядит так: w будет содержать ваши сингулярные значения, U будет содержать левые особые векторы, а V будет содержать особые сингулярные векторы. Поскольку dataMat равен 3xN, U должен быть 3x3, а V должен быть NxN. И, как вы говорите, вам нужен левый сингулярный вектор, установите UNeeded = 1 и просто возьмите первый столбец U. Поскольку вам не нужны прямые сингулярные векторы, вы также можете установить VNeeded = 0.

+0

Просто примечание; OP также необходимо установить параметр UNeeded для вывода левых сингулярных векторов –

+0

Спасибо! Обновленный ответ, чтобы включить эти предложения. – vrume21

+0

Спасибо за ответ. Это может показаться действительно глупым вопросом, но какие значения я вкладываю в матрицы U и V? Спасибо! –

 Смежные вопросы

  • Нет связанных вопросов^_^