Sar Kerson Ответов: 1

Как вычислить Нормаль вершин на сетке


Мой файл. obj не содержит vn (Нормаль вершин), поэтому я пытаюсь вычислить их сам. Мой здесь был мой код:
using namespace cv;
typedef struct vet_data 
{
	Vec3f vn;
	double total_angle;

} vet_data;
long v_num = mesh.vertices.size();
vet_data v_data[v_num];

for(int i = 0; i < v_num; ++i) {
	v_data[i].vn = Vec3f(0,0,0);
	v_data[i].total_angle = 0;
}
std::ofstream test_out("/home/sar/Desktop/test_out.txt");
for(auto&& v : mesh.tvi) {           //traverse all the triangles 
//here v is a triangle that contains 3 points
//so v[0], v[1], v[2] are the index of points of the triangle
	Vec3f v0 = Vec3f(mesh.vertices[v[0]][0], mesh.vertices[v[0]][1], mesh.vertices[v[0]][2]),
		  v1 = Vec3f(mesh.vertices[v[1]][0], mesh.vertices[v[1]][1], mesh.vertices[v[1]][2]),
		  v2 = Vec3f(mesh.vertices[v[2]][0], mesh.vertices[v[2]][1], mesh.vertices[v[2]][2]);

	Vec3f e1 = v1 - v0;
	Vec3f e2 = v2 - v1;
	Vec3f vn = normalize(e1.cross(e2));

	double angle[3] = { 0.0, 0.0, 0.0 };
	double t1, t2, t3;
	t1 = (v1 - v0).dot(v2 - v0) * CV_PI / 180.0;
	t2 = (v0 - v1).dot(v2 - v1) * CV_PI / 180.0;
	t3 = (v0 - v2).dot(v1 - v2) * CV_PI / 180.0;
	angle[0] = acos(t1);
	angle[1] = acos(t2);
	angle[2] = acos(t3);
	for(int i = 0; i < 3; ++i) {
		v_data[v[i]].vn += vn * angle[i];
		v_data[v[i]].total_angle += angle[i];
	}
}
obj_file << "--vn--" << std::endl;
for(int i = 0; i < v_num; ++i) {
	Vec3f vn = v_data[i].vn / v_data[i].total_angle;
	obj_file << "vn" << " " << vn[0] << " " << vn[1] << " " << vn[2] << std::endl;
}



Однако, некоторые ВНС являются :В. Н. НАНА НАНА НАНА
Я не могу понять, почему.

Что я уже пробовал:

и я попытался написать в файл, чтобы выяснить, что было не так. Но я все еще не знаю.
И даже если я написал неправильный vns в своем файле. obj, он все равно может отображаться. Почему?
Я был бы признателен, если бы кто-нибудь мог дать мне несколько советов.

0x01AA

"Тем не менее, некоторые ВНС являются :В. Н. НАНА НАНА НАНА": на какой вход? Вы проверили, что такое Е1, Е2 в данном случае? Может быть, они почти параллельны?

Sar Kerson

Да, это возможно.
Я сделаю предварительную обработку с вершинами.

[no name]

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

Sar Kerson

Спасибо. Но я нашел ту самую точку, где возникла проблема.
Это функция acos ().
T1, t2, t3 должны делиться на его mod.

1 Ответов

Рейтинг:
0

Jochen Arndt

Как уже упоминалось, это требует отладки вашего кода. Вы также можете использовать отладку бедняги, проверяя промежуточные значения с помощью isnan[^]. Таким образом, вы можете определить, где назначены NaN.

Но есть кандидат на генерацию NaN: acos функция. Может случиться так, что аргумент немного выше 1 из-за ошибок округления. Затем возвращается NAN, который влияет на все последующие вычисления.

Чтобы проверить и / или обработать это, вы можете вставить код, ограничивающий аргумент 1, Проверьте errno, или включить исключения с плавающей запятой.