Skip to content

Commit

Permalink
[feature] add affine transform
Browse files Browse the repository at this point in the history
  • Loading branch information
olivierdalang committed Mar 7, 2015
1 parent 4f00016 commit 4ab0179
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 10 deletions.
64 changes: 60 additions & 4 deletions ui_main.ui
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,20 @@
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>4</number>
<number>3</number>
</property>
<widget class="QWidget" name="page_0">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
Expand All @@ -202,7 +211,16 @@
</widget>
<widget class="QWidget" name="page_1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
Expand All @@ -222,7 +240,16 @@
</widget>
<widget class="QWidget" name="page_2">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
Expand All @@ -240,6 +267,35 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="page_4">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_10">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Affine - exactly 3 pairs</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="leftMargin">
Expand Down
18 changes: 12 additions & 6 deletions vectorbender.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ def determineTransformationType(self):
0 if no pairs Found
1 if one pair found => translation
2 if two pairs found => linear
3 if three or more pairs found => bending
4 if bending but unmet dependencies"""
3 if two pairs found => linear
4 if three or more pairs found => bending
5 if bending but unmet dependencies"""

pairsLayer = self.dlg.pairsLayer()

Expand All @@ -117,11 +118,13 @@ def determineTransformationType(self):
return 1
elif featuresCount == 2:
return 2
elif featuresCount >= 3:
elif featuresCount == 3:
return 3
elif featuresCount >= 4:
if dependenciesStatus != 2:
return 4
return 5
else:
return 3
return 4

return 0

Expand All @@ -136,10 +139,13 @@ def run(self):

# Loading the delaunay
restrictToSelection = self.dlg.restrictBox_pairsLayer.isChecked()
if transType==3:
if transType==4:
self.dlg.displayMsg( "Loading delaunay mesh (%i points) ..." % len(self.ptsA) )
QCoreApplication.processEvents()
self.transformer = BendTransformer( pairsLayer, restrictToSelection, self.dlg.bufferValue() )
elif transType==3:
self.dlg.displayMsg( "Loading affine transformation vectors..." )
self.transformer = AffineTransformer( pairsLayer, restrictToSelection )
elif transType==2:
self.dlg.displayMsg( "Loading linear transformation vectors..." )
self.transformer = LinearTransformer( pairsLayer, restrictToSelection )
Expand Down
82 changes: 82 additions & 0 deletions vectorbendertransformers.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,88 @@ def fromTriangularToCartesian(self, l,t1,t2,t3):
y = l[0]*t1.y()+l[1]*t2.y()+l[2]*t3.y()
return QgsPoint(x,y)

class AffineTransformer(Transformer):
def __init__(self, pairsLayer, restrictToSelection):
Transformer.__init__(self, pairsLayer, restrictToSelection)

# Make sure data is valid
assert len(self.pointsA)==3
assert len(self.pointsA)==len(self.pointsB)

self.a1 = self.pointsA[0]
self.a2 = self.pointsA[1]
self.a3 = self.pointsA[2]
self.b1 = self.pointsB[0]
self.b2 = self.pointsB[1]
self.b3 = self.pointsB[2]


"""
MATRIX
[a,b,c]
M = [d,e,f]
[0,0,1]
[x11] [x12]
1] M * [y11] = [y12]
[ 1 ] [ 1 ]
[x21] [x22]
2] M * [y21] = [y22]
[ 1 ] [ 1 ]
[x31] [x32]
3] M * [y31] = [y32]
[ 1 ] [ 1 ]
Equations to solve
[
a*x11+b*y11+c = x12,
d*x11+e*y11+f = y12,
a*x21+b*y21+c = x22,
d*x21+e*y21+f = y22,
a*x31+b*y31+c = x32,
d*x31+e*y31+f = y32]
For variables
[a,b,c,d,e,f]
Result using http://www.numberempire.com/equationsolver.php
a = (x12*(y31-y21)-x22*y31+x32*y21+(x22-x32)*y11)/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
b = (x11*(x32-x22)-x21*x32+x22*x31+x12*(x21-x31))/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
c = -(x11*(x32*y21-x22*y31)+x12*(x21*y31-x31*y21)+(x22*x31-x21*x32)*y11)/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
d = (y21*y32+y11*(y22-y32)+y12*(y31-y21)-y22*y31)/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
e = -(x21*y32+x11*(y22-y32)-x31*y22+(x31-x21)*y12)/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
f = (x11*(y22*y31-y21*y32)+y11*(x21*y32-x31*y22)+y12*(x31*y21-x21*y31))/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
"""

x11 = self.a1.x()
y11 = self.a1.y()
x21 = self.a2.x()
y21 = self.a2.y()
x31 = self.a3.x()
y31 = self.a3.y()
x12 = self.b1.x()
y12 = self.b1.y()
x22 = self.b2.x()
y22 = self.b2.y()
x32 = self.b3.x()
y32 = self.b3.y()

self.a = (x12*(y31-y21)-x22*y31+x32*y21+(x22-x32)*y11)/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
self.b = (x11*(x32-x22)-x21*x32+x22*x31+x12*(x21-x31))/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
self.c = -(x11*(x32*y21-x22*y31)+x12*(x21*y31-x31*y21)+(x22*x31-x21*x32)*y11)/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
self.d = (y21*y32+y11*(y22-y32)+y12*(y31-y21)-y22*y31)/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
self.e = -(x21*y32+x11*(y22-y32)-x31*y22+(x31-x21)*y12)/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)
self.f = (x11*(y22*y31-y21*y32)+y11*(x21*y32-x31*y22)+y12*(x31*y21-x21*y31))/(x11*(y31-y21)-x21*y31+x31*y21+(x21-x31)*y11)


def map(self, p):

return QgsPoint( self.a*p.x()+self.b*p.y()+self.c, self.d*p.x()+self.e*p.y()+self.f )

class LinearTransformer(Transformer):
def __init__(self, pairsLayer, restrictToSelection):
Expand Down

0 comments on commit 4ab0179

Please sign in to comment.