воскресенье, 21 июня 2009 г.

UV координаты вершины принадлежащей треугольнику

При сложном разбиении mesh’а (дополнительная генерация геометрии), треугольники дробятся таким образом, что текстурные координаты новых вершин бывает не так просто вычислить. Потому, что новая вершина может по разным причинам быть различно удаленной от вершин треугольника. Вспомнил, что как то приводил свой вывод расчета в форуме xnadev.ru, но как понадобилось самому, долго искал, где именно.

Делаю для себя заначку, чтоб добру не пропадать:



using System;
using Microsoft.Xna.Framework;

namespace Test
{
public class TestMath2
{
public TestMath2()
{
// вершины треугольника
Vector3 A = new Vector3(1f, -1f, 0f);
Vector3 B = new Vector3(3f, -4f, 0f);
Vector3 C = new Vector3(5f, -1f, 0f);
// текстурные координаты вершин
Vector2 tA = new Vector2(1f, 1f);
Vector2 tB = new Vector2(3f, 4f);
Vector2 tC = new Vector2(5f, 1f);
// точка в плоскости треугольника ограниченная его гранями
Vector3 D = new Vector3(3f, -2f, 0f);
// B
// .
// / \
// / \
// / \
// / .D \
// / \
// .-----------.
// A C
// расчет
Vector2 tD = CalculationDuvFromABC( A, tA,
B, tB,
C, tC,
D);
}
///
/// Нахождение текстурных координат точки D
///
/// Позиция точки A
/// Текстурные координаты точки A
/// Позиция точки B
/// Текстурные координаты точки B
/// Позиция точки C
/// Текстурные координаты точки C
/// Позиция точки D
/// Текстурные координаты точки D
private Vector2 CalculationDuvFromABC( Vector3 A, Vector2 tA,
Vector3 B, Vector2 tB,
Vector3 C, Vector2 tC,
Vector3 D)
{
Vector3 E = PointOfLinesCrossing(A, B, C, D);
float kAEC = (E - A).Length() / (C - A).Length();
Vector2 tE = tA + (tC - tA) * kAEC;
float kBDE = (D - B).Length() / (E - B).Length();
return (Vector2)(tB + (tE - tB) * kBDE);
}
///
/// Нахождение позиции точки пересечения двух прямых,
/// проходящих через точки AC и BD
///
/// Позиция точки A
/// Позиция точки B
/// Позиция точки C
/// Позиция точки D
/// Позиция точки E, полученной пересечением двух прямых AC и BD
private Vector3 PointOfLinesCrossing(Vector3 A, Vector3 B, Vector3 C, Vector3 D)
{
Vector3 vecAC = C - A;
Vector3 vecBD = D - B;
float Tac = Math.Abs( Matrix2x2Determinant( vecBD.X, A.X - B.X,
vecBD.Y, A.Y - B.Y)
/
Matrix2x2Determinant( vecBD.X, vecAC.X,
vecBD.Y, vecAC.Y));
return Vector3.Add(A, Vector3.Multiply(vecAC, Tac));
}
///
/// Определитель матрицы 2х2
///
/// a00
/// a01
/// a10
/// a11
/// Определитель
private float Matrix2x2Determinant( float a00, float a01,
float a10, float a11)
{
return (float)(a00 * a11 - a10 * a01);
}
}
}

Комментариев нет:

Отправить комментарий