Показать сообщение отдельно
Старый 12.12.2010, 10:42   #10
Venom2
 
Сообщений: n/a
Ответ: Как найти UV координаты новой точки на триангле.

Сообщение от CRASHER Посмотреть сообщение
Если кто то понял как код работает, пжалст объясните как мне найти эти векторы ? Я так понял Vector3 это Nx,Ny,Nz, а Vector2 это UV верно?
; вычитание векторов
Function Sub3(Dst#[3], Src1#[3], Src2#[3])
	Dst[0] = Src1[0] - Src2[0]
	Dst[1] = Src1[1] - Src2[1]
	Dst[2] = Src1[2] - Src2[2]
End Function

; векторное произведение векторов
; по сути получается перпендикуляр к плоскости образующейся исходными двумя векторами
Function Cross3(Dst#[3], Src1#[3], Src2#[3])
	Dst[0] = Src1[1] * Src2[2] - Src1[2] * Src2[1]
	Dst[1] = Src1[2] * Src2[0] - Src1[0] * Src2[2]
	Dst[2] = Src1[0] * Src2[1] - Src1[1] * Src2[0]
End Function

; скалярное произведение векторов
; в результате получается косинус угла между исходными векторами
Function Dot3#(Src1#[3], Src2#[3])
	Return Src1[0] * Src2[0] + Src1[1] * Src2[1] + Src1[2] * Src2[2]
End Function

; нормализация вектора, приведение его к единичной длине
; просто делим элементы вектора на длину
Function Normalize3(Dst#[3], Src#[3])
	Local Dot# = Dot3(Src, Src)
	If Dot > 0.001 Then
		Dot = 1.0 / Sqr(Dot)
		Dst[0] = Src[0] * Dot
		Dst[1] = Src[1] * Dot
		Dst[2] = Src[2] * Dot
	Else
		Dst[0] = 0
		Dst[1] = 0
		Dst[2] = 0
	End If
End Function

; инициализация
Function Vector3(Dst#[3], x#, y#, z#)
	Dst[0] = x
	Dst[1] = y
	Dst[2] = z
End Function

; инициализация
Function Vector2(Dst#[2], x#, y#)
	Dst[0] = x
	Dst[1] = y
End Function

Function ComputeUV(A#[3], Auv#[2], B#[3], Buv#[2], C#[3], Cuv#[2], D#[3], Duv#[2])

	Local T1#[3], T2#[3], T3#[3], N#[3]
	Local r1#, r2#, r3#

	; получаем два ребра AB и AC
	Sub3(T1, B, A)
	Sub3(T2, C, A)

	; берем перпендикуляр к плоскости треугольника, образованого его ребрами
	Cross3(N, T1, T2)

	; нормализуем чтобы получить вектор нормали
	Normalize3(N, N)

	; получаем ребра DB, DC
	Sub3(T1, B, D)
	Sub3(T2, C, D)

	; перпендикуляр к образуемой плоскости
	Cross3(T3, T1, T2)

	; косинус угла между ним и нормалью
	r1 = Dot3(N, T3)

	; получаем ребра DC, DA
	Sub3(T1, C, D)
	Sub3(T2, A, D)
	
	; перпендикуляр к образуемой плоскости
	Cross3(T3, T1, T2)

	; косинус угла между ним и нормалью
	r2 = Dot3(N, T3)

	; косинус третьего угла (сумма всех косинусов углов равна единице)
	r3 = 1.0 - AreaPBC - AreaPCA

	; используем косинусы для определения долей от каждой вершины
	Duv[0] = Auv[0] * r1 + Buv[0] * r2 + Cuv[0] * r3
	Duv[1] = Auv[1] * r1 + Buv[1] * r2 + Cuv[1] * r3

End Function

Local A#[3], Auv#[2]
Local B#[3], Buv#[2]
Local C#[3], Cuv#[2]
Local D#[3], Duv#[2]


Vector3(A, -1,  0,  0)
Vector2(Auv,  0.0,  0.0)

Vector3(B,  0,  1,  0)
Vector2(Buv,  1.0,  0.0)

Vector3(C,  1,  0,  0)
Vector2(Cuv,  1.0,  1.0)

Vector3(D, 0, 0.5, 0)

ComputeUV(A, Auv, B, Buv, C, Cuv, D, Duv)

Print(Str(Duv[0]))
Print(Str(Duv[1]))

WaitKey()


End
Работает корректно, судя по рисунку

ЗЫ
Лучше юзать массивы, вместо типа, т.к. доступ к ним чуток быстрее, к тому же не надо задумываться об управлении памятью (хотя по хорошему выделять память для таких вычислений извращение, лучше вынести всю математику в длл)
Миниатюры
Нажмите на изображение для увеличения
Название: tri.PNG
Просмотров: 1249
Размер:	6.5 Кб
ID:	12097  
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
CRASHER (12.12.2010)