Forum

Author Topic: Не получается определить ортогональное дополнение в E3  (Read 6966 times)

aldanstar

  • Full Member
  • ***
  • Posts: 137
    • View Profile
    • Александр Старовойтов
Здравствуйте, Алексей.
Все пишу скрипт выравнивания по камерам. "Нашел" плоскость камер. Пытаюсь построить базиз, чтобы трансформировать. Почему-то если выставляю собственный вектор (без плавающей запятой), то скалярное произведение по всем векторам равно 0. Если же нормаль плоскости или вектор с запятой, то 3-ий вектор не ортогональным получается.

Проекты и скрипт: ftp://gisserver.kpfu.ru/Public/Porjects/

Вот скрипт (в самом конце скрипта):

import PhotoScan
import math

doc = PhotoScan.app.document
chunk = doc.chunk
Cameras = chunk.cameras
T = chunk.transform.matrix

sCamera = Cameras[0]
correction = sCamera.key #нужен потому что иногда камера 0 становится большей непонятно почему
#cam_index = PhotoScan.app.getInt("Input camera index (starting from zero): ")
#save_path = PhotoScan.app.getSaveFileName("Specify output file:")
def realCoord(C): #Coordinates to real
    newCoord = PhotoScan.Vector( [T[0,0]*C[0]+T[0,1]*C[1]+T[0,2]*C[2]+T[0,3],T[1,0]*C[0]+T[1,1]*C[1]+T[1,2]*C[2]+T[1,3],T[2,0]*C[0]+T[2,1]*C[1]+T[2,2]*C[2]+T[2,3]] )
    return newCoord

def distBeatPoins(C1,C2): #Distance between points
    dist = math.sqrt((C1[0]-C2[0])*(C1[0]-C2[0])+(C1[1]-C2[1])*(C1[1]-C2[1])+(C1[2]-C2[2])*(C1[2]-C2[2]))
    return dist

def furtherCamera(C):#Mead and further camera in circle

    find=False
    index=C.key-correction
    D2=0

    while find == False:
        index +=1
        D1=distBeatPoins(C.center,Cameras[index].center)
        if D1 < D2:
            find=True
        else:
            D2=D1
            maxIndex=index

    find=False

    while find == False:
        D1=distBeatPoins(C.center,Cameras[index].center)
        if D1 > D2:
            find=True
        else:
            D2=D1
            minIndex = index
        index +=1
    print([Cameras[maxIndex],Cameras[minIndex]])
    return [Cameras[maxIndex],Cameras[minIndex]]

def planeBy3Cameras(C1,C2,C3):
    C1=C1.center
    C2=C2.center
    C3=C3.center
    return planeBy3Points(C1,C2,C3)


def planeBy3Points(C1,C2,C3):


    A = C1[1]*(C2[2] - C3[2]) + C2[1]*(C3[2] - C1[2]) + C3[1]*(C1[2] - C2[2])
    B = C1[2]*(C2[0] - C3[0]) + C2[2]*(C3[0] - C1[0]) + C3[2]*(C1[0] - C2[0])
    C = C1[0]*(C2[1] - C3[1]) + C2[0]*(C3[1] - C1[1]) + C3[0]*(C1[1] - C2[1])
    D =-( C1[0] * (C2[1] * C3[2] - C3[1] * C2[2]) + C2[0] * (C3[1] * C1[2] - C1[1] * C3[2]) + C3[0] * (C1[1] * C2[2] - C2[1] * C1[2]))

    return PhotoScan.Vector( [A, B, C, D] )

def meanPlaneBeatCameras(sCamera,fCamera):
    pList = []

    for i in range(sCamera.key-correction, fCamera.key-correction):
        C1 = Cameras
        if int(i+fCamera.key-correction/3)> fCamera.key-correction:
            C2 = Cameras[int(i+fCamera.key-correction/3)-fCamera.key-correction+(sCamera.key-correction-1)]
        else:
            C2 = Cameras[int(i+fCamera.key-correction/3)]

        if int(i+2*fCamera.key-correction/3)> fCamera.key-correction:
            C3 = Cameras[int(i+2*fCamera.key-correction/3)-fCamera.key-correction+(sCamera.key-correction-1)]
        else:
            C3 = Cameras[int(i+2*fCamera.key-correction/3)]

        P = planeBy3Cameras(C1, C2, C3)
        pList.append([i, int(i+fCamera.key-correction/3), int(i+2*fCamera.key-correction/3), P])

    return pList

def meanPlane(pList):
    summA =0
    summB =0
    summC =0
    summD =0
    for i in range(0,len(pList)):
        summA += pList[3][0]
        summB += pList[3][1]
        summC += pList[3][2]
        summD += pList[3][3]
    return PhotoScan.Vector( [summA/len(pList), summB/len(pList), summC/len(pList), summD/len(pList)] )

def cameraToPlaneDist(Plane, Camera):
    Point = Camera.center
    return pointToPlaneDist(Plane, Point)

def pointToPlaneDist(Plane, Point):
    return (Plane[0]*Point[0]+Plane[1]*Point[1]+Plane[2]*Point[2]+Plane[3])/math.sqrt(Plane[0]*Plane[0]+Plane[1]*Plane[1]+Plane[2]*Plane[2])

def maxDistToPlane(Plane, sCamera, eCamera):
    maxDist=0
    distList = []
    distListWithMax = []
    for i in range(sCamera.key-correction,eCamera.key-correction+1):
        disPoint = math.fabs(round(cameraToPlaneDist(meanP, Cameras),2))
        distList.append(disPoint)
        if disPoint>maxDist:
            maxDist=disPoint
    distListWithMax.append(distList)
    distListWithMax.append(maxDist)
    return distListWithMax

def degbeatPlane(plane1, plane2):
    return math.acos(math.fabs(plane1[0]*plane2[0]+plane1[1]*plane2[1]+plane1[2]*plane2[2])/math.sqrt((plane1[0]*plane1[0]+plane1[1]*plane1[1]+plane1[2]*plane1[2])*(plane2[0]*plane2[0]+plane2[1]*plane2[1]+plane2[2]*plane2[2])))


fCamera = furtherCamera(sCamera)[0]
pList = meanPlaneBeatCameras(sCamera,fCamera)
meanP = meanPlane(pList)
#print(pList)
#print(meanP)


def intersectVector(P1,P2):
    return PhotoScan.Vector( [ (P1[1]*P2[2]-P1[2]*P2[1]),(P1[0]*P2[2]-P1[2]*P2[0]),(P1[0]*P2[1]-P1[1]*P2[0]) ] )

def scalar(vec1,vec2):
    return vec1[0]*vec2[0]+vec1[1]*vec2[1]+vec1[2]*vec2[2]

def degrBVect(vec1, vec2):
    scalar = scalar(vec1,vec2)
    veclen = math.sqrt((vec1[0]*vec1[0]+vec1[1]*vec1[1]+vec1[2]*vec1[2])*(vec2[0]*vec2[0]+vec2[1]*vec2[1]+vec2[2]*vec2[2]))
    return math.acos(scalar/veclen)

def alignByVector(V):
    V=PhotoScan.Vector([0,1,2])


    V1 = PhotoScan.Vector([V[0],V[1],V[2]])
    V2 = PhotoScan.Vector([1,1,-(V1[0]+V1[1])/V1[2]])
    V3 = PhotoScan.Vector([V1[1]*V2[2]-V1[2]*V2[1],V1[2]*V2[0]-V1[0]*V2[2],V1[0]*V2[1]-V1[1]*V2[0]])

    print(T)
    print(V1)
    print(V2)
    print(V3)
    print(scalar(V1,V2))
    print(scalar(V1,V3))
    print(scalar(V2,V3))

    """rotation = PhotoScan.Matrix([[V1[0],V1[1],V1[2]],[V2[0],V2[1],V2[2]],[V3[0],V3[1],V3[2]]])

    R = rotation
    C = chunk.region.center

    if chunk.transform:
       T = chunk.transform.matrix
       s = math.sqrt(T[0,0]*T[0,0] + T[0,1]*T[0,1] + T[0,2]*T[0,2])
       S = PhotoScan.Matrix( [[s, 0, 0, 0], [0, s, 0, 0], [0, 0, s, 0], [0, 0, 0, 1]] )
    else:
       S = PhotoScan.Matrix( [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] )


    T = PhotoScan.Matrix( [[-R[2,0],-R[2,1],-R[2,2],C[2]], [R[1,0],R[1,1],R[1,2],C[1]],[R[0,0],R[0,1],R[0,2], C[0]], [0,0,0,1]])

    chunk.transform.matrix = S * T.inv()"""

alignByVector(meanP)



P.S. есть еще один вопрос. Пытаюсь прикрутить библиотеки http://vpython.org/. Возможно ли это. Нужно просто после выравнивания сгенерировать цилиндр без шапок с цилиндрической UV для запекания в xNormals. Закидываю DLL и Libs от x64 пишет не совместим за данной версией Python, если 2.7 или 3.2 то не является Win32.

Я вижу так же, что Вы используете PyQt. Может можно через него сгенерировать.
По крайней мере, выполнял то ошибок не возникло, только вот как его добавить с цилиндрической UV и без шапок:

import PhotoScan
import math
import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtOpenGL import *

class MyWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setFixedSize(200, 120)

        self.quit = QtGui.QPushButton("Quit", self)
        self.quit.setGeometry(62, 40, 75, 30)
        self.quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold))

        self.connect(self.quit, QtCore.SIGNAL("clicked()"),
                     QtGui.qApp, QtCore.SLOT("quit()"))


widget = MyWidget()
widget.show()


Соответственно я разобрался как создавать свои окна

Заранее спасибо,
С уважением,
Александр






« Last Edit: April 16, 2015, 03:22:35 PM by aldanstar »
С уважением,
Александр Старовойтов
Казанский (Приволжский) Федеральный Университет

aldanstar

  • Full Member
  • ***
  • Posts: 137
    • View Profile
    • Александр Старовойтов
Переписал на
    C = chunk.region.center
    print(T)
    T = PhotoScan.Matrix( [[T[0,0],T[0,1],T[0,2], T[0,3]],[T[1,0],T[1,1],T[1,2],T[1,3]],[T[2,0],T[2,1],T[2,2],T[2,3]], [0,0,0,1]])
    M = PhotoScan.Matrix([[V1[0],V1[1],V1[2],T[0,3]],[V2[0],V2[1],V2[2],T[1,3]],[V3[0],V3[1],V3[2],T[2,3]],[0,0,0,1]])
    R = M * T.inv()
    chunk.transform.matrix = R*T

Модель вроде выравнивается но искажается
С уважением,
Александр Старовойтов
Казанский (Приволжский) Федеральный Университет

aldanstar

  • Full Member
  • ***
  • Posts: 137
    • View Profile
    • Александр Старовойтов
Написал так:

    T = chunk.transform.matrix
    C = chunk.region.center
    M = PhotoScan.Matrix([[V1[0],V1[1],V1[2],C[0]],[V2[0],V2[1],V2[2],C[1]],[V3[0],V3[1],V3[2],C[2]],[0,0,0,1]])

    if chunk.transform:
       s = math.sqrt(T[0,0]*T[0,0] + T[0,1]*T[0,1] + T[0,2]*T[0,2])
       S = PhotoScan.Matrix( [[s, 0, 0, 0], [0, s, 0, 0], [0, 0, s, 0], [0, 0, 0, 1]] )
    else:
       S = PhotoScan.Matrix( [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] )

    R = M * T.inv()
    T = PhotoScan.Matrix( [[R[0,0],R[0,1],R[0,2], C[0]],[R[1,0],R[1,1],R[1,2],C[1]],[R[2,0],R[2,1],R[2,2],C[2]], [0,0,0,1]])

    chunk.transform.matrix = S * T.inv()

Тоже не правильно. Не выравнивает.

Заранее спасибо
« Last Edit: April 17, 2015, 05:09:30 PM by aldanstar »
С уважением,
Александр Старовойтов
Казанский (Приволжский) Федеральный Университет

aldanstar

  • Full Member
  • ***
  • Posts: 137
    • View Profile
    • Александр Старовойтов
Написал так:

    T = chunk.transform.matrix
    C = chunk.region.center
    M = PhotoScan.Matrix([[V1[0],V1[1],V1[2],C[0]],[V2[0],V2[1],V2[2],C[1]],[V3[0],V3[1],V3[2],C[2]],[0,0,0,1]])

    if chunk.transform:
       s = math.sqrt(T[0,0]*T[0,0] + T[0,1]*T[0,1] + T[0,2]*T[0,2])
       S = PhotoScan.Matrix( [[s, 0, 0, 0], [0, s, 0, 0], [0, 0, s, 0], [0, 0, 0, 1]] )
    else:
       S = PhotoScan.Matrix( [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] )

    R = M * T.inv()
    T = PhotoScan.Matrix( [[R[0,0],R[0,1],R[0,2], C[0]],[R[1,0],R[1,1],R[1,2],C[1]],[R[2,0],R[2,1],R[2,2],C[2]], [0,0,0,1]])

    chunk.transform.matrix = S * T.inv()

Тоже не правильно. Не выравнивает.

Заранее спасибо
С уважением,
Александр Старовойтов
Казанский (Приволжский) Федеральный Университет

aldanstar

  • Full Member
  • ***
  • Posts: 137
    • View Profile
    • Александр Старовойтов
Здравствуйте,
Написал следующее. Вроде получилось.

def alignByVector(V):
    #V=PhotoScan.Vector([1.2,1,2])
    T = chunk.transform.matrix
    T1=PhotoScan.Vector([T[0,0],T[0,1],T[0,2]])
    T2=PhotoScan.Vector([T[1,0],T[1,1],T[1,2]])
    T3=PhotoScan.Vector([T[2,0],T[2,1],T[2,2]])

    length=math.sqrt(V[0]*V[0]+V[1]*V[1]+V[2]*V[2])
    V1 = PhotoScan.Vector([V[0],V[1],V[2]])/length
    V2 = firstOrthoVeactor(V1)
    V3 = secondOrthoVeactor(V1, V2)


    D1=degrBVect(T1, V1)
    D2=degrBVect(T2, V2)
    D3=degrBVect(T3, V3)
    print(V1)
    print(V2)
    print(V3)
    print(scalar(V1,V2))
    print(scalar(V1,V3))
    print(scalar(V2,V3))

    T = chunk.transform.matrix
    C = chunk.region.center
    M = PhotoScan.Matrix([[V1[0],V1[1],V1[2],C[0]],[V2[0],V2[1],V2[2],C[1]],[V3[0],V3[1],V3[2],C[2]],[0,0,0,1]])

    if chunk.transform:
       s = math.sqrt(T[0,0]*T[0,0] + T[0,1]*T[0,1] + T[0,2]*T[0,2])
       S = PhotoScan.Matrix( [[s, 0, 0, 0], [0, s, 0, 0], [0, 0, s, 0], [0, 0, 0, 1]] )
    else:
       S = PhotoScan.Matrix( [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] )

    R = M * T.inv()

    chunk.transform.matrix = R* T* S

alignByVector(meanP)


С уважением,
Александр.
С уважением,
Александр Старовойтов
Казанский (Приволжский) Федеральный Университет