Как исправить инвертированные нормали облака точек?

== сравнивает ссылки на объекты.

.equals() сравнивает значения String.

Иногда == дает иллюзии сравнения значений String, как в следующих случаях:

String a="Test";
String b="Test";
if(a==b) ===> true

Это связано с тем, что при создании любого строкового литерала JVM сначала ищет этот литерал в пуле строк, и если он найдет совпадение, эта же ссылка будет передана новой String. Из-за этого получаем:

(a == b) ===> true

                       String Pool
     b -----------------> "test" <-----------------a

Однако == не выполняется в следующем случае:

String a="test";
String b=new String("test");
if (a==b) ===> false

В этом случае для new String("test") оператор new String будет создан в куче, и эта ссылка будет указана на b, поэтому b будет дана ссылка на кучу, а не на String pool.

Теперь a указывает на String в пуле String, а b указывает на String в куче. Из-за этого мы получаем:

, если (a == b) ===> false.

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

Пока .equals() всегда сравнивает значение String, поэтому дает true в обоих случаях:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

Таким образом, использование .equals() всегда лучше.

0
задан Joey Chia 17 January 2019 в 10:12
поделиться

2 ответа

Учитывая треугольник, определенный его тремя вершинами ABC, вектор, перпендикулярный («нормальный») этому треугольнику, легко получить с помощью перекрестного произведения двух векторов, например ABxAC. Но также ABxBC.

Дело в том, что перекрестное произведение НЕ коммутативно. Итак, ABxAC - это не то же самое, что ACxAB. Именно это ABxAC = - ACxAB, это тот же вектор, но в противоположном направлении .

Нормальное направление движения по передней поверхности должно быть рассчитано в соответствии с порядком намотки или треугольником. Тот же порядок, в котором вы устанавливаете вершины треугольника в буфере, - это порядок выбора векторов для перекрестного произведения.

Вы должны знать, как GL делает порядок намотки в зависимости от типа треугольного примитива

ПРИМЕР
Допустим, вы используете glDrawArrays (GL_TRIANGLES, ... ) и ваш буфер вершин выглядит как v1, v2, v3, v1, v3, v4, v1, v4, v5 и т. д. (vi = vix, viy, viz), где все порядки намотки расположены против часовой стрелки. Тогда:

Vector AB = v2 - v1
Vector AC = v3 - v1
Vector perp = cross(AB, AC)
Vector norm = normalize(perp) //divide each component by lenght of perp


Теперь у вас есть нормаль к граням, нормали в точках немного хитры.
Простейшим способом является вычисление среднего значения нормалей к треугольникам, разделяющим вершину. Когда каждый фрагмент треугольника заштрихован, нормаль в этой точке может быть интерполирована из нормалей в вершинах. В результате вы получаете «мягкий» переход от треугольника к треугольнику.

Если вы хотите сохранить края (жесткий переход), то вы должны предоставить разные нормали для разных треугольников. Таким образом, каждая вершина, если смотреть на шейдер, получает свою собственную нормаль. Повторите вершину для другого треугольника, затем установите другую нормаль даже для той же вершины.

0
ответ дан Ripi2 17 January 2019 в 10:12
поделиться

Поскольку вопрос помечен тегом point-cloud-library, я представляю решение с использованием PCL .

Отразить нормаль к точке обзора

PCL имеет функцию flipNormalTowardsViewpoint , в которой вы указываете точку, соответствующую нормаль и точку обзора, к которой нужно перевернуться.

Точка обзора обычно является положением камеры в глобальных координатах, но если у вас есть только снимок сцены, то точка обзора становится (0,0,0) .

0
ответ дан kanstar 17 January 2019 в 10:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: