graph layout
This commit is contained in:
parent
94d65af760
commit
a4bee26e4e
|
@ -47,7 +47,6 @@ class CVConnection(QtGui.QGraphicsItem):
|
|||
self.nodeFrom = nodeFrom
|
||||
self.nodeTo = nodeTo
|
||||
self.beziercurve = None
|
||||
self.paintRect = None
|
||||
self.setZValue(1)
|
||||
|
||||
self.determinePath()
|
||||
|
|
|
@ -95,7 +95,29 @@ class DecompositionView(QtGui.QDialog):
|
|||
n = len(c.variables)
|
||||
layers[n].append(c)
|
||||
# sort clusters in layers
|
||||
# ??
|
||||
# start from layer N (largest clusters)
|
||||
# clusters are initially ordered according to the order in which sub-clusters appear in the previous (n+1) layer
|
||||
for n in reversed(range(1,N)):
|
||||
print "ordering layers",n
|
||||
# find subiable pseudo-ordering in previous layers
|
||||
subordervalue = {}
|
||||
clusterindex = 0
|
||||
for cluster in layers[n+1]:
|
||||
clusterindex = clusterindex+1
|
||||
for sub in cluster.subs:
|
||||
# order by first appearence in cluster from left to right
|
||||
if sub not in subordervalue:
|
||||
subordervalue[sub] = clusterindex
|
||||
# determine pseudo-order clusters in this layers: sum subordervalues per cluster
|
||||
clusterordervalue = {}
|
||||
for cluster in layers[n]:
|
||||
clusterordervalue[cluster] = 0
|
||||
for sub in cluster.subs:
|
||||
if sub in subordervalue:
|
||||
clusterordervalue[cluster] += subordervalue[sub]
|
||||
# sort clusters in layers
|
||||
layers[n].sort(lambda x,y:clusterordervalue[x]<clusterordervalue[y])
|
||||
|
||||
# map GeometricDecompositions to CVClusters
|
||||
for n in range(0,N+1):
|
||||
layer = layers[n]
|
||||
|
@ -112,10 +134,10 @@ class DecompositionView(QtGui.QDialog):
|
|||
for child in c.subs:
|
||||
self.ui.graphicsScene.addItem(CVConnection(self, self.map[c], self.map[child]))
|
||||
# iteratively improve graph layout
|
||||
# self.optimiseGraphLayout()
|
||||
self.optimiseGraphLayout()
|
||||
|
||||
def optimiseGraphLayout(self):
|
||||
|
||||
print "optimising graph layout..."
|
||||
# create a graph of clusters and connections
|
||||
graph = geosolver.graph.Graph()
|
||||
if self.ui.graphicsScene != None:
|
||||
|
@ -140,10 +162,10 @@ class DecompositionView(QtGui.QDialog):
|
|||
for j in range(i+1,n):
|
||||
c1 = l[i]
|
||||
c2 = l[j]
|
||||
box1 = c1.paintRect.translated(c1.position)
|
||||
box1 = c1.boundingRect().translated(c1.position)
|
||||
box1.setWidth(2*box1.width())
|
||||
box1.setHeight(2*box1.height())
|
||||
box2 = c2.paintRect.translated(c2.position)
|
||||
box2 = c2.boundingRect().translated(c2.position)
|
||||
box2.setWidth(2*box2.width())
|
||||
box2.setHeight(2*box2.height())
|
||||
#print "box 1", box1
|
||||
|
@ -166,20 +188,48 @@ class DecompositionView(QtGui.QDialog):
|
|||
for e in graph.edges():
|
||||
c1 = e[0]
|
||||
c2 = e[1]
|
||||
box1 = c1.paintRect.translated(c1.position)
|
||||
box2 = c2.paintRect.translated(c2.position)
|
||||
box1 = c1.boundingRect().translated(c1.position)
|
||||
box2 = c2.boundingRect().translated(c2.position)
|
||||
centerdiff = box2.center()-box1.center()
|
||||
direction = numpy.array([centerdiff.x(),centerdiff.y()])
|
||||
norm = numpy.linalg.norm(direction)
|
||||
if norm != 0:
|
||||
direction = direction / numpy.linalg.norm(direction)
|
||||
goal = box1.height() + box2.height() + box1.width() + box2.width()
|
||||
force = (norm - goal) / 20.0
|
||||
#goal = max(box1.width(),box2.width())
|
||||
goal = 5 * box1.height()
|
||||
force = (norm - goal) / 50.0
|
||||
#direction[1] = 0.0
|
||||
c1.force += +force*direction;
|
||||
c2.force += -force*direction;
|
||||
#print "force ", force
|
||||
|
||||
# determine forces due to clusters overlapping connections
|
||||
n = len(l)
|
||||
for c in graph.vertices():
|
||||
for e in graph.edges():
|
||||
box1 = c.boundingRect().translated(c.position)
|
||||
box1.setWidth(2*box1.width())
|
||||
box1.setHeight(2*box1.height())
|
||||
con = graph.get(e[0],e[1])
|
||||
box2 = con.boundingRect()
|
||||
box2.setWidth(2*box2.width())
|
||||
box2.setHeight(2*box2.height())
|
||||
#print "box 1", box1
|
||||
#print "box 2", box2
|
||||
if box1.intersects(box2):
|
||||
#print "intersects"
|
||||
force = box1.intersected(box2).width() + box1.intersected(box2).height()
|
||||
centerdiff = box2.center()-box1.center()
|
||||
direction = numpy.array([centerdiff.x(),centerdiff.y()])
|
||||
norm = numpy.linalg.norm(direction)
|
||||
if norm != 0:
|
||||
direction = direction / numpy.linalg.norm(direction)
|
||||
#direction[1] = 0.0
|
||||
c.force += -force*direction / 50.0;
|
||||
#print "force 1", c1.force
|
||||
#print "force 2", c2.force
|
||||
|
||||
|
||||
# apply forces
|
||||
for c in l:
|
||||
move = QtCore.QPointF(c.force[0],c.force[1])
|
||||
|
@ -191,6 +241,7 @@ class DecompositionView(QtGui.QDialog):
|
|||
for e in graph.edges():
|
||||
connector = graph.get(e[0],e[1])
|
||||
connector.determinePath()
|
||||
print "done"
|
||||
|
||||
def updateViewports(self):
|
||||
self.viewportManager.updateViewports()
|
||||
|
|
14
workbench/examples/rick/tetrahedron.gcs
Normal file
14
workbench/examples/rick/tetrahedron.gcs
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE Geometric Constraints>
|
||||
<Objects>
|
||||
<Point posX="-101.660079249" posY="0.0" key="p1" posZ="-89.9399" name="p1"/>
|
||||
<Point posX="116.978718304" posY="0.0" key="p4" posZ="-91.3343" name="p4"/>
|
||||
<DistanceConstraint pBeginKey="p1" key="d5" distance="218.643244" pEndKey="p4" name="d5" fixed="False"/>
|
||||
<Point posX="-1.39260383038" posY="0.0" key="p8" posZ="66.2348" name="p8"/>
|
||||
<DistanceConstraint pBeginKey="p4" key="d9" distance="197.078134705" pEndKey="p8" name="d9" fixed="False"/>
|
||||
<DistanceConstraint pBeginKey="p8" key="d12" distance="185.59122702" pEndKey="p1" name="d12" fixed="False"/>
|
||||
<Point posX="0.0" posY="94.8203361356" key="p15" posZ="-27.1911" name="p15"/>
|
||||
<DistanceConstraint pBeginKey="p1" key="d16" distance="152.522391009" pEndKey="p15" name="d16" fixed="False"/>
|
||||
<DistanceConstraint pBeginKey="p15" key="d19" distance="163.674270388" pEndKey="p4" name="d19" fixed="False"/>
|
||||
<DistanceConstraint pBeginKey="p15" key="d24" distance="133.121126352" pEndKey="p8" name="d24" fixed="False"/>
|
||||
<Prototypes numberOfImports="0" number="27"/>
|
||||
</Objects>
|
Loading…
Reference in New Issue
Block a user