Вы можете иметь угол между двумя направлениями v1,v2
(векторы), например:
ang = acos(dot(v1,v2)/(|v1|.|v2|))
, что переводит 3D в:
ang = acos( (x1*x2 + y1*y2 + z1*z1) / sqrt( (x1*x1 + y1*y1 + z1*z1)*(x2*x2+y2*y2+z2*z2) ) )
ОднакоВы не можете иметь угол между двумя точками, который просто не имеет смысла.Также остерегайтесь того, что 3D-угол - это не то, что вы думаете (его угол в стерадианах, и вы можете рассматривать его как объемное покрытие ... нормальный угол - это охват области), и да, это также скалярное значение.Итак, вы ищете направляющие косинусы или углы Эйлера (для которых вам нужно больше информации и порядок преобразований, чтобы не быть амбициозными) или матрицы преобразования .
Но поскольку я подозревал, что это проблема XY, и, основываясь на ваших комментариях, я был прав.
Итак, ваша реальная проблема (на основе комментариев) - найтиотраженный луч от (треугольной) грани.Использование углов (косинусов направления, углов Эйлера и матриц преобразования) - очень плохая идея, так как это было бы крайне медленно.Вместо этого используйте простую векторную математику. Я вижу это так:
Итак, вы получили направление луча dir
и хотите получить отраженную dir'
от лицапри нормальном nor
так:
dir' = 2 * ( nor*dot(-dir,nor) + dir ) - dir
dir' = 2 * ( -nor*dot(dir,nor) + dir ) - dir
dir' = -2*nor*dot(dir,nor) + 2*dir - dir
dir' = -2*nor*dot(dir,nor) + dir
dir' = dir-2*nor*dot(dir,nor)
так в 3D это:
dir=(dx,dy,dz)
nor=(nx,ny,nz)
t = 2*(dx*nx + dy*ny + dz*nz) // 2*dot(dir,nor)
dx' = dx-t*nx
dy' = dy-t*ny
dz' = dz-t*nz
, поскольку вы можете видеть, что гониометрия или углы не нужны вообще ..Также не имеет значения, если нормаль указывает на или вне лица / объекта, dot
обрабатывает знаки самостоятельно ...
В случае, если вам нужно, нормаль может быть вычислена путем перекрестного произведения двух ее сторон.поэтому, если треугольник определен v0,v1,v2
точками, то:
nor = cross( v1-v0 , v2-v1 )
Вот пример, где я использую эту технику для трассировщика лучей:
его шахта GLSL трассировщик лучей, поддерживающий отражения на гранях треугольника и не имеющий гониометрии в нем ... ищите комментарий // reflect
вФрагмент шейдера особенно ищут:
ray[rays].dir=ray[rays].dir-(2.0*t*ray[rays].nor);
его отражение где
t=dot(ray[i0].dir,ray[i0].nor);
, где dir
- направление луча, а nor
- нормальное лицо (выглядит знакомо?да это же уравнение) ...