Интерполяция треугольника
У меня есть единичный прямоугольный треугольник и значение в каждой из 3 вершин.
Мне нужно интерполировать, чтобы найти значение в точке внутри треугольника.
Часы поисков не нашли ничего, что на самом деле говорит мне, как это сделать.
Вот моя ближайшая попытка, которая на самом деле довольно близка, но не совсем верна -
result =
v1 * (1 - x) * (1 - y) +
v2 * x * (1 - y) +
v3 * x * y;
V1, v2 и v3-это значения в 3 вершинах треугольника.
(x, y) - это точка в треугольнике, значение которой вы пытаетесь найти.
Любой вид здесь мне поможет метод. Это не обязательно должен быть единичный / прямоугольный треугольник.
Обновленная информация:
У меня есть сетка равномерно расположенных точек и значение в каждой точке.
Я делаю треугольник из ближайших 3 точек на сетке.
Вот картинка, чтобы проиллюстрировать это -

Поэтому я должен интерполировать между 5, 3 и 7, чтобы найти значение x.
Точка также может находиться внутри другого треугольника, что означает, что вы будете интерполировать между 5, 7 и значением нижнего левого угла треугольника. площадь.
В коде, который я показал, v1 = 5, v2 = 3, v3 = 7.
x-дробное расстояние (диапазон [0-1]) в направлении" x", а y-дробное расстояние в направлении" y".
В Примере с рисунком x, вероятно, будет около 0,75, а y-около 0,2
Вот мои ближайшие попытки -
Создано с использованием -
if (x > y) //if x > y then the point is in the upper right triangle
return
v1 * (1 - x) * (1 - y) +
v2 * x * (1 - y) +
v3 * x * y;
else //bottom left triangle
return
v1 * (1 - x) * (1 - y) +
v4 * (1 - x) * y +
v3 * x * y;
И еще одна попытка -
Создано с использованием -
if (x > y)
return
(1 - x) * v1 + (x - y) * v2 + y * v3;
else
return
(1 - y) * v1 + (y - x) * v4 + x * v3;
Они оба близки к тому, что мне нужно, но очевидно, не совсем так.
5 ответов:
Следует использовать барицентрические координаты. Существует очень тщательная запись здесь, которая также обсуждает альтернативные решения и почему барицентрические координаты являются лучшими: CodePlea-интерполяция в треугольнике
В основном веса будут выглядеть следующим образом:
На самом деле самое простое и надежное решение основано на барицентрических координатах -
Http://answers.unity3d.com/questions/383804/calculate-uv-coordinates-of-3d-point-on-plane-of-m.html
Я задал этот вопрос 3 года назад и до сих пор работаю над тем, как это сделать. Я действительно считаю, что это невозможно, если не использовать равносторонний треугольник. Вот достойный способ сделать это, используя барицентрические координаты, а затем добавив технику, которая избавляет от большинства артефактов. v1, v2, v3-это значения в трех точках треугольника. x, y-это точка, для которой вы хотите найти значение.
if (x > y) { b1 = -(x - 1); b2 = (x - 1) - (y - 1); b3 = 1 - b1 - b2; } else { b1 = -(y - 1); b2 = -((x - 1) - (y - 1)); b3 = 1 - b1 - b2; } float abs = x - y; if (abs < 0) abs *= -1; if (abs < 0.25f) { abs = 0.25f - abs; abs *= abs; b1 -= abs; b3 -= abs; } b1 *= b1; b2 *= b2; b3 *= b3; float fd = 1 / (b1 + b2 + b3); b1 *= fd; b2 *= fd; b3 *= fd; return v1 * b1 + v2 * b2 + v3 * b3;
Хорошо, мы сделаем линейную интерполяцию, предполагая, что градиент постоянен относительно x и y.
d/dx = v2 - v1иd/dy = v3 - v2, иf(0,0) = v1. Мы имеем простое двумерное дифференциальное уравнение.d{f(x,y)} = (v2 - v1)*dx f(x,y) = (v2 - v1)*x + g(y) d{f(x,y)} = g'(y) = (v3 - v2)*dy g(y) = (v3 - v2)*y + C f(x,y) = (v2 - v1)*x + (v3 - v2)*y + C f(0,0) = v1 = (v2 - v1)*0 + (v3 - v2)*0 + C = C f(x,y) = (v2 - v1)*x + (v3 - v2)*y + v1Или в терминах v1 v2 и v3
f(x,y) = (1 - x)*v1 + (x - y)*v2 + y*v3Если вы хотите сделать это в квадрате для четырех вершин, как показано выше с v4 в левом нижнем углу при x=0 y=1, вот условия:
d/dx = (v2 - v1) (1 - y) + (v3 - v4) y,d/dy = (v3 - v2) x + (v4 - v1) (1 - x),f(0,0) = v1d/dx = (v2 - v1) (1 - y) + (v3 - v4) y f(x,y) = (v2 - v1) (1 - y) x + (v3 - v4) y x + g(y) d/dy = (v3 - v2) x + (v4 - v1) (1 - x) = -(v2 - v1) x + (v3 - v4) x + g'(y) v3 - v2 + (v4 - v1) / x + v4 - v1 = -v2 + v1 + v3 - v4 + g'(y) / x (v4 - v1) / x + 2*(v4 - v1) = g'(y) / x g'(y) = (v4 - v1) + 2 x (v4 - v1) g(y) = (v4 - v1) (1 + 2 x) y + C f(x,y) = (v2 - v1) (1 - y) x + (v3 - v4) y x + (v4 - v1) (1 + 2 x) y + C f(0,0) = (v2 - v1) (1 - 0) 0 + (v3 - v4) 0 0 + (v4 - v1) (1 + 2 0) 0 + C = v1 f(x,y) = (v2 - v1) (1 - y) x + (v3 - v4) y x + (v4 - v1) (1 + 2 x) y + v1
Вот некоторый псевдокод для ближайшего соседа:
if( dist( p, p1 ) <= dist( p, p2 ) && dist( p, p1 ) <= dist( p, p3 ) ) return val( p1 ) if( dist( p, p2 ) <= dist( p, p3 ) && dist( p, p2 ) <= dist( p, p1 ) ) return val( p2 ) if( dist( p, p3 ) <= dist( p, p1 ) && dist( p, p3 ) <= dist( p, p2 ) ) return val( p3 )Я думаю, что это также порождает диаграмму Вороного

Comments