неискаженные координаты текстуры - PullRequest
3 голосов
/ 18 марта 2011

Как рассчитать координаты UV для точек на плоскости?

У меня есть многоугольник - 3 или 4 или более точек - то есть на плоскости, то есть все точки находятся насамолет.Но это может быть под любым углом в пространстве.

Одна сторона этого многоугольника - две точки - должны быть сопоставлены с двумя соответствующими 2D точками в текстуре - я знаю эти две точки заранее.Я также знаю масштаб текстуры по осям x и y, и что ни одна точка не выходит за пределы экстента текстуры или других «краевых случаев».

Вот изображение, где искаженный самый верхний квадратик искажен:

enter image description here

Я выделил плохой квадратик желтым цветом.Представьте себе, что я знаю координаты UV этих двух самых нижних углов в этом квадре и хочу вычислить правильные координаты UV двух других точек ...

Как рассчитатькоординаты UV всех других точек на плоскости относительно этих двух точек?

Представьте, что моя текстура - это кусок бумаги в реальной жизни, и я хочу текстурировать вашу (плоскую)двери автомобиля.Я помещаю две точки на мою бумагу, которые я выстраиваю в линию с двумя точками на двери вашей машины.Как рассчитать, где находятся другие места на дверце машины под бумагой?

Можно ли использовать трилатерацию?Как будет выглядеть псевдокод для двух известных точек в 2D-пространстве?


Успешно с использованием кода brainjam:

def set_texture(self,texture,a_ofs,a,b):
    self.texture = texture
    self.colour = (1,1,1)
    self.texture_coords = tx = []
    A, B = self.m[a_ofs:a_ofs+2]
    for P in self.m:
        if P == A:
            tx.append(a)
        elif P == B:
            tx.append(b)
        else:
            scale = P.distance(A)/B.distance(A)
            theta = (P-A).dot((B-A)/(P.distance(A)*B.distance(A)))
            theta = math.acos(theta)
            x, y = b[0]-a[0], b[1]-a[1]
            x, y = x*math.cos(theta) - y*math.sin(theta), \
                x*math.sin(theta) + y*math.cos(theta)
            x, y = a[0]+ x*scale, a[1]+ y*scale
            tx.append((x,y))

enter image description here

Ответы [ 3 ]

2 голосов
/ 18 марта 2011

Вы должны выразить остальные точки в виде двух выбранных векторов и источника.

Я бы сделал что-то вроде этого:

Выберите 3 3D-точки с соответствующими точками УФ:

  • A (x, y, z, u, v)
  • B (x, y, z, u, v)
  • C (x, y, z, u, v)

Затем, используя координаты x, y, z, мы хотим выразить данную трехмерную точку D как:

D = A + альфа (B - A) + бета (C - A) + гамма (B - A) X (C - A)

У нас есть 3 уравнения для x, y, z, X - перекрестное произведение, и альфа, бета, гамма - этонеизвестно.Мы хотим, чтобы это создало линейную связь между uv и xyz.

Вычислите W = (B - A) X (C - A), нам нужно решить:

Dx - Ax = alpha. (Bx-Axe) + бета. (Cx-Axe) + гамма.Wx

Dy - Ay = альфа. (By-Ay) + бета. (Cy-Ay) + гамма.Wy

Dz - Az = альфа. (Bz-Az) + бета. (Cz-Az) + гамма.Wz

Вычислить обратную матрицу матрицы M с помощью , этот метод :

       | (Bx-Ax) , Cx-Ax , Wx | 
   M = | (By-Ay) , Cy-Ay , Wy | 
       | (Bz-Az) , Cz-Az , Wz | 

Мы называем матрицу результатов N, обратите внимание, что она не зависит от D.

Затем вычисляем альфа, бета, гамму для D:

(альфа, бета), гамма) = N. (DA)

Затем вычислите u, v для D:

Du = Au + альфа (Bu - Au) + бета (Cu - Au)

Dv = Av + ​​альфа (Bv - Av) + бета (Cv - Av)

гамма не используется, так как это расстояние между D и плоскостью (A, B, C) 3D.

1 голос
/ 20 марта 2011

Пометьте вершины вашего трехмерного многоугольника против часовой стрелки, начиная с двух вершин, координаты UV которых известны. Назовите эти метки A , B , C , D . Метки соответствующих вершин в УФ-пространстве: a , b , c , d , где a и b известны.

Вы задали проблему для точки P в исходном многоугольнике, чтобы определить соответствующую UV-координату p . (Я полагаю, что вам нужно только рассчитать координаты УФ c и d для точек C и D , но общее решение для P то же самое.)

Сначала вычислите угол & theta; между P-A и B-A . Это легко сделать, используя скалярное произведение нормализованных векторов и acos.

& альфа; = ( P-A ) & sdot; ( B-A ) / (| P-A || B-A |)

* * & Тысяче пятьдесят-шесть тета; = acos (& alpha;)

Также рассчитаем соотношение длин:

& Sigma; = | P-A | / | B-A |

Теперь, чтобы вычислить p в ультрафиолетовом пространстве, мы просто поворачиваем вектор b-a на угол & theta; (сохраняя a фиксированной) и масштабировать по & sigma;.

Пусть R , матрица для поворота на угол & theta; , будет

| + cos (& theta;) -син (& theta;) |
| + грех (& theta;) + cos (& theta;) |

Тогда p = a + & sigma; R ( b-a ).

И все готово.

0 голосов
/ 18 марта 2011

U и V - это числа от 0 до 1.

Итак, скажем, в вашей ситуации размер большего ребра равен 10, а меньшего ребра равен 5, каждый «разрыв» равен 2,5.Затем это нормализуется, чтобы дать вам нужную цифру.

, поэтому некоторые примеры псевдокода:

bottomLeftVector(0,0,0)
bottomLeftTexture(0,0)
topLeftVector(2.5, 5, 0)
topLeftTexture(0.25, 0)
topRightVector(7.5, 5, 0)
topRightTexture(0, 0.75)
bottomRightVector(10, 0, 0)
bottomRightTexture(1,1)

Надеюсь, это поможет!

...