|
Ответ: Как найти 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
Работает корректно, судя по рисунку
ЗЫ
Лучше юзать массивы, вместо типа, т.к. доступ к ним чуток быстрее, к тому же не надо задумываться об управлении памятью (хотя по хорошему выделять память для таких вычислений извращение, лучше вынести всю математику в длл)
|