-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvis_rep_finder.hpp
2555 lines (2289 loc) · 92 KB
/
vis_rep_finder.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef _WAILEA_UNDIRECTED_VIS_REP_FINDER_HPP_
#define _WAILEA_UNDIRECTED_VIS_REP_FINDER_HPP_
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <exception>
#include "undirected/base.hpp"
#include "undirected/planar_dual_graph_maker.hpp"
#include "undirected/embedded_bctree.hpp"
#include "undirected/planarizable_graph.hpp"
#ifdef UNIT_TESTS
#include "gtest/gtest_prod.h"
#endif
namespace Wailea {
namespace Undirected {
/**
* @file undirected/vis_rep_finder.hpp
*
* @brief finds a visibility representation for a planar VRRectLabelGraph.
*
* @remark
*
* This file handles visibility representation for connected graphs.
* not just for biconnected graphs.
* Visibility representation can be considered the closest representation
* to an actual drawing.
* Visibility representation was originally developed to express a drawing of
* a biconnectd graph on a 2 dimensioal plane with a designated
* the outer face, the top node, and the ordering of the incident edges around
* each vertex fixed out of two orientations (clockwise /counter-clockwise).
* Most of the algorithms to generate a visiblity representation take a
* biconnected component with its combinatorial embedding as their inputs, and
* most of the algorithms to find a planar embedding take a biconnected graph.
* as their inputs.
* On the other hand, any combinatorial embedding of a tree always gives a
* planar embedding, and there is no need to find a planar embedding by an
* algorithm. The embedding of a tree is usually given externaly to represent
* some semantics of the data structure that uses the tree.
*
* The class VisRepVinder and its accompanying classes are an attempt to expand
* the visibility representation to connected graphs.
* A connected graph can be decomposed into block-cut-tree, or BC-tree.
* Each node of a BC-tree is either a cut vertex or a block.
* As stated above, a combinatorial embedding is usually found by some
* planarity test algorithm for bi-connected components.
* On the other hand, a combinatorial embedding of a tree is assumed to be
* given in the ordering of incident edges lists. They are considered to be
* given externally, rather than to be found by some algorithms.
* Here we assume the combinatorial embedding of the connected graph is
* represented by EmbeddedBCTree that has an internal embedding for each block,
* and a data structure called FaceUnificationGroup for cut vertices.
* Moreover, the outer/inner classification has been already done in
* EmbedddBCTree. Please see embedded_bctree.hpp for details.
*
* =========================================================================
* An existing standard algorithm to find a visibility representation for a
* biconnected component [TT86]
* =========================================================================
*
* We first explain the visibility representation algorithm for biconnected
* component. Our algorithm is based on it.
*
* Finding a visibility representation of a biconnected graph is usually done
* in the following steps [TT86].
* Input: Embedding with its dual graph, top node, and the outer face.
* 1. Let s be the top node.
* 2. Let t be the node incident to s and the outer face s* where s is the
* destination node, and t is the source node of the half edge of {s,t}
* according to the s*.
* Please note that around each inner face, the incident half edges cycle
* around it counter-clockwise as follows.
*
* We denote the face opposite to the outer face across {s,t} by 'right face'
* t*.
* We also denote the outer face by 's*', and the right face by 't*'.
*
* Ex.1) biconnected graph not k2.
*
* (top node) s ==================================
* /| /| /|
* | |eCCW |
* {s,t}| eCW |/ |
* | === v1 |/ outer face
* (s*)--+---> t* /| === s*
* outer face | right face |/ /|
* | === v2 .
* | . .
* | . .
* | . |
* |/ |/ |/
*(bottom node)t ===================================
*
*
* Ex.2) k2 (minimum biconnected component)
*
* (top node) s ===
* /|
* outer face | outer face
* |
* s* --+---> t* = s* (self loop)
* |
* |
* |/
* (bottom node)t ===
*
* 3. Find (s,t)-ordering.
* For the reason described later, we find (t,s)-ordering with the 't'
* at the rank 0 upward to 's', which has the highest rank.
* Magically, (t,s)-ordering does not violate the constraints
* in the planar embedding in the following sense;
*
* Lemma 1 [TT86]: Each face of the embeding consists of two directed paths
* induced by the (s,t)-ordering
* Lemma 2 [TT86]: All outgoing (ingoing) arcs of any vertex v of the
* embedding appear consecutively around v.
*
* 4. Orient each edge of the embedding according to the (t,s)-ordering.
*
* 5. Orient each dual edge such that its corresponding graph edge
* cuts across upward if we place the source and the destination nodes
* of the dual edge left and right respectively.
*
* edge
* /|\
* |
* ----+---> Dual edge
* |
* |
*
* 7. Use a scheduling algorithm (PERT critical path, DFS-based, network
* simplex etc.) that takes both node and edge costs to assign ranks to the
* vertices. In a standard algorithm, only the edge costs are used. The
* value is fixed to 1 or 2.
*
* 8. Remove {s*,t*} from the dual graph.
*
* 9. Use a scheduling algorithm that takes both node and edge cost to assign
* ranks to the faces on the dual graph.
*
* 10. For each edge e, let x(e) be a value between the ranks of two incident
* face.
*
* 11. For each vertex v, let LeftX(v) be min{y(e)} and RightX(v) be max
* among incident edges.
*
* Eventually, t has the least y value , s has the greatest y value among
* the nodes. In the same way, t* has the least x value and s* has the
* greatest x value among the faces.
*
* =======================================================
* Making a visibility representation of a connected graph
* from an EmbeddedBCTree
* =======================================================
* In our approach, a visibility representation is made by assembling
* visibility representations of the blocks utilizing the algorithm
* for biconnected components described above.
* The algorithm takes a top node and an outer face as part of its input.
* Hence we have to first determine the outer face and the top node for
* each block in the bc-tree.
* Also, the blocks incident to the same cutvertex must be joined at the
* cut vertex in the embedding. A set of blocks to be joined at a cut vertex
* is defined by 'face unification group', in which each participating block
* nominates an incident face to be unified with others. Please note that a cut
* vertex can have multiple face unification groups.
* When determining an outer face of each block, we have to take the following
* constraint into consideration: at each face unification group, at most
* one face can be inner face, and the rest must be outer.
* This relationship among the blocks at each face unification block is
* called absorbor/absorbees relationship into 'sorted face unification
* group'.
* This is done in EmbeddedBCTree::findGeometricEmbedding(), which gives a
* rooted directed tree EmbeddedBCTree::ExplorationTree.
* EmbeddedBCTree::ExplorationTree takes ExplorationNode and ExplorationEdge
* as its nodes and edges. The former represents one block, but the latter
* does not represent any edge in EmbeddedBCTree but to represent a parent-
* child relationship between two blocks.
* each ExplorationNode has FaceUnificationGroups. The parent-child
* relationships represent absorber-absorbee relationship among the blocks,
* and FaceUnificationGroups represent how the faces of the absorbee blocks
* are unified to the absorbers'.
*
* Generation of visibility representation for
* EmbeddedBCTRee::findGeometricEmbedding() is done by VisRepFinder defined in
* this file in two tree traversals on ExplorationTree: One in bottom-up and
* the other top-down.
* In the bottom-up phase, at each block node, visibility representation for
* the block is found based on the standard visibility representaton algorithm
* for biconnected components, but some extensions to utilize the node and
* edge costs.
* The block may have some child blocks with absorbee faces into the block.
* We accommodate those child blocks in the absorber faces at the cut vertices.
* In order to do that, we first allocate enough space for those blocks.
* How to allocate those spaces will be described below.
* We also have to accommodate enough space for vertex and edge labels.
* This will be described later.
*
* In the top-down phase, we assign the global coordinates to all the
* descendant visibility representations from the root.
*
* ==========================================================
* How to accommodate absorbee visibility representations at
* each cut vertex for a sorted unification group.
* ==========================================================
* Here we denote the relevant edges by cw and ccw, which
* mean clockwise and counter-clockwise respectively.
* Those are relative to the face unification group, not
* to the ordering among the half edges of the embedding of the block.
*
* 1. Absorber is inner face/top node
*
* Cut vertex
* ======+=========+=============+=====
* | | | | |
* | +-+-+ +----+----+ +-+-+ |
* | |VR1| | | ... |VRy| |
* | +---+ | VR2 | | | |
* | cw ccw | | +---+ |
* | +---------+ cw ccw|
* | cw ccw |
* CCW CW
*
*
* 2. Absorber is outer face/top node
*
* Cut vertex
* ===========+=========+=============+==
* | | | | |
* | | +-+-+ +----+----+ +-+-+
* | | |VR1| | | ... |VRy|
* | | +---+ | VR2 | | |
* | | cw ccw | | +---+
* | | +---------+ cw ccw
* | | cw ccw
* CW CCW
*
* 3. Absorber is inner face/bottom node
*
* CW CCW
* | ccw cw |
* | ccw cw +---------+ |
* | +---+ | |ccw cw |
* | | | | VR2 | +---+ |
* | |VRy| ... | | |VR1| |
* | +-+-+ +----+----+ +-+-+ |
* | | | | |
* ======+============+========+======
* Cut vertex
*
* 4. Absorber is outer face/bottom node
*
* CCW CW
* | |
* | |
* | Cut vertex |
* ===+=========+=============+===
* | | |
* +-+-+ +----+----+ +-+-+
* |VR1| | | ... |VRy|
* +---+ | VR2 | | |
* cw ccw | | +---+
* +---------+ cw ccw
* cw ccw
*
* 5. Absorber is outer or inner face/left node
*
* CW ccw cw
* | +---------+ ccw cw
* | | | +-------+
* | | VRUx | ... | VRU1 |
* | | | | |
* | +----+----+ +---+---+
* | | |
* CV =========++===============++====
* | | |
* | +--+--+ +---+---+
* | | VRL1| .... | VRLx |
* | | | +-------+
* | +-----+ cw ccw
* CCW cw ccw
*
*
* 6. Absorber is outer or inner face/right node
* ccw cw CCW
* +---------+ ccw cw |
* | | +-------+ |
* | VRU1 | ... | VRUx | |
* | | | | |
* +---------+ +-------+ |
* | | |
* =============================== CV
* | | |
* +--+--+ +---+---+ |
* |VRL2 | .... | VRL1 | |
* | | +-------+ |
* +-----+ cw ccw |
* cw ccw CW
*
*
*
* ==========================================================
* NOTES on the coordinate systems and the orientations used
* ==========================================================
*
* 1. Circular orientations of the incident half edges around each face in an
* embedding of a block.
*
* The incident half edges of each inner face is asssumed to be in counter-
* clockwise as follows.
*
* v3 v2
* *------------* ---------> v1 e3
* | <------- | /|\*--------* | * e4\ | /e2
* | | inner /|\| | |v2 v3| | /|\| | \|/
* | | face | | | | | |face | | | e5---V---e1
* |\|/ | | | |v1 v4| | | | | /|\
* | -------> | | *--------*\|/ | |\|/ e6/ | \e8
* *------------* <--------- * e7
* v4 v1 v2
*
* Inner face Outer face K2 counter-clockwise
* ordering of
* incident edges
*
* 2. Circular orientations of the incident edges around each cut vertex
* in the sorted unification group.
* A sorted unification group unifies the faces in the differrent block
* at the same cut vertex.
* A sorted unification group has one absorber and the rest are absorbees.
*
* The ordering of the unification faces in the absorbee list is in the
* counter-clockwise ordering.
*
* =======================...========================= CV
* | | f1 | | fN | |
* | absorbee1 absorbee1 absorbeeN absorbeeN |
* | edge CW edge CCW edge CW edge CCW |
* | ------------------------------------------> |
* | Absorbees arranged in counter-clockwise |
* | around the CW. |
* | |
* absorber absorber face absorber
* edge CCW edge CW
*
* Please note UnificationFace::edgeCWInEG() and edgeCCWInEG() are
* the edges on the clockwise and counter-clockwise side respectively
* around the cut vertex in the unification group, which may not be
* necessarily aligned with the embedding of the block.
*
* Ex1.) An absorbee block joining in the ordinary (unflipped)
embedding at CV.
*
* CV ....=============....
* /| | | |
* | | | | (outer) face
* | | | | to be unified
* | | | |
* | | | |/
* edgeCWInEG() edgeCCWInEG()
*
*
* Ex2.) An absorbee block joining in the reversed (flipped)
* embedding at CV.
*
* CV ....=============....
* | | | |\
* | | | | (outer) face
* | | | | to be unified
* | | | |
* \| | | |
* edgeCWInEG() edgeCCWInEG()
*
* Embedding of the block is flipped.
*
* 3. Ordering of the nodes in the embedding of each block and the induced
* orientation of the edges.
*
* top node S (+) Highest value
*
* /|\
* |
* | edge orientation is upward.
* |
* |
* |
*
* bottom node T (-) Lowest value
*
* 4. Ordering of the faces in the dual graph of each block and the induced
* orientation of the dual edges.
*
* The embedding of the block is normal (unflipped) in the sense that
* the half edges around each inner face is in counter-clockwise order.
*
* N2
* /|\
* |
* | | |\ half edge
* | | |
* --+-+-+-> Right-ward orientation of the dual
* | | | edge in the normal (unflipped) embedding.
* half \| | |
* edge |
* |
* N1
* Upward orientation
* of the edge
*
*
* 5. Geometric coordinate system used to describe the node and edge label
* placement and dimensions.
*
* The labels are specified as rectangles with widths and heights.
* The widths and heights in real numbers.
*
* The placement of the edge labels are specified in one of three positions:
* center, couter-clockwise, and clockwise. This is decided as follows.
* If you look at N2 from N1, the right hand side is clockwise.
*
* N2
* /|\
* couneter- |
* clockwise | clockwise
* |
* N1
*
* 6. Local geometric coordinate system for each block to place the nodes and
* the edges and to allocate necessary spaces for child blocks.
*
* The orientation of X and Y axes are aligned with the
* normal (unflipped) embedding of the block
*
* higher positive
* /|\ .(+100.0, +100.0)
* |
* (left) | (right)
* negative | positive
* X-axis ------+------>
* (0.0,0.0)|
* |
* |
* .(-100.0, -100.0)
* lower negative
*
*
* 7. Global geometric coordinate system in which the resultant visibility
* representation is given.
*
* The orientation of X and Y axes are aligned with the
* normal (unflipped) embedding of the root block.
* The embeddings of the descendent blocks may be rotated
* , vertically flipped, or horizontally flipped.
*
* higher positive
* /|\ .(+100.0, +100.0)/|\
* |
* (left) | (right)
* negative | positive
* X-axis ------+------>
* (0.0,0.0)|
* |
* |
* .(-100.0, -100.0)
* lower negative
*
* =======================================
* How to allocate space for child blocks
* =======================================
* We augument the basic algorithm above to include handling of the child
* visibility representations at the cut vertices in the UF groups.
* Assume an absorber face fx for a cut vertex of the current block is
* incident to two half edges he1, and he2.
* And the edges denoted by CW and CCW mean the edge clockwise side, and
* counter-clockwise side respectively with respect to the circular ordering
* around the cut vertex in the unification group, which does not necessary
* mean the circular ordering of the incident edges around the face fx.
* In the following discussion we assume the orientation of the absorber block
* is fixed as its top cut vertex node positioned at the top (higher y), and
* each inner face is oriented counter-clockwise.
*
* Finding an optimum arrangement in terms of the aspect ratio and/or area
* is a combinatorial optimization problem, which probably belongs to
* NP-complete (TSP or 3-SAT). Here we simply give up optimality, but try to
* find a good enough arrangement in terms of the aspect ratio and the area
*
* Each inner face is split into two horizontal halves: Left pane and the right
* pane. The left pane is incident to the left path of edges from the top node
* to the bottom. The right pane is to the right path in the same way. Each
* pane is vertically split into sub-panes at the incident nodes. Each
* sub-pane is incident to an edge.
*
* Each sub-pane consists of several areas.
*
* NOTE: Here the inner face is oriented such that the edges of the graph are
* oriented upward according to the ts-numbering, and the face oriented
* counte-clockwise in the embedding.
*
* Ex. Inner face, Top node.
*
* Left Pane of F2
* Right Pane of F1 <----------------> Right Pane of F2
* <---------------------> <--------------->
* <---------------> W7
* <------->W8
* <-------> W9
* <-----> W10
* <------> W11
* <-------> W12
* <-----> W13
* <-------> W14
* ...----------> W15
* <----------> W16
* <--> HG <--> HG <--> HG
* <-----> W17
* <---------> W18
* <--------> W19
* <---------------------> W20
* <----------------> W21
* <---------------------------------------> W22
*
* X1 X31 X2
* | || | H23 H24 H28
* Y4 -------------+-----------------+--+---------------+---------- + + +
* N2 | E1 | | E2 | |H27| H30
* Y3 -------------|--+-------++-----+--|---------------|--+----++- + | + | +
* | | | || | | | | | || | | | |
* | | || | | | | || | | | |
* | | | ++-----+ | | | | || | | | |
* | | || | | | | || | | | |
* |----------+ | +--++--+ | | | | | || | | + |
* | | || | | | | | || | | |
* D1|=============|====|==||==|=====|=======| | | || | | VG |
* | | || | | +---------------+ | || + | + |
* F1 | | || | | F2 | || | | |
* | +--++--+ | +-----+ | || + | + |
* | +--------+ | || | | | | | || | | + |
* | | +-------++ | | | | || | | | |
* | | | | || | | | | | || | | | |
* Y6 |--------|--+-------++-----+--|-----| | || + | + | +
* | | | N1 E1 | | | | || | | |
* Y7 +--------+---++----+--+-------+-+---+ | || + + +
* | || | | | | | ||H25 H26 H29
* || | | | D2 ==========|====||=
* || | | |
* E3 | +---------+
*
*
* D1: Dual of E1
* D2: Dual of E2
* HG: Horizontal gap between two features.
* HG :=VRRectLabelGraph::horizontalGap()
* VG: Vertical gap between two features.
* HG :=VRRectLabelGraph::verticalGap()
* X1: center of the left face F1 X1 := DGFaceAux::mEarlyStart
* DGFaceAux::mX
* X2: center of the right face F2 X2 := DGFaceAux::mEarlyStart
* DGFaceAux::mX
* Y3: lower edge of the node N2 DGNodeAux::mEarlyStart
* In this case, N1 is the top node of the block.
* Y4: upper edge of the node N2 EGNodeAux::mEarlyStart +
* EGNodeAux::mCost
* DGNodeAux::mCost := VRRectLabelNode::mHeight
*
* Y5: lower edge of the node N1 EGNodeAux::mEarlyStart
* In this case, N1 is the top node of the block.
*
* Y6: upper edge of the node N1 EGNodeAux::mEarlyStart +
* EGNodeAux::mCost
* DGNodeAux::mCost := VRRectLabelNode::mHeight
*
* W7: Width required to accommodate the absorbee VRs under N2
* between E1 and E2. The width is calculated as follows.
*
* <----------- W7 ----------->
* |W_vr1|HG|W_vr2|HG|...|HG|W_vrN|
*
* HG: horizontal gap. G :=VRRectLabelGraph::horizontalGap()
* W_vri: Width of the absorbee VRi.
*
* W7 = SUM{W_vri} + (N-1)*G
*
* W8: F2's Left pane's share of W7. It's w7/2.0.
* W8 := DGEdgeAux::mChildrenWidthUpperRight for D1.
* W9: F2's Right pane's share of W7. It's w7/2.0.
* W9 := DGEdgeAux::mChildrenWidthUpperLeft for D2.
* W10: Width of the label edge of E1 on the N2 side.
* W10 := VRRectLabelEdge::widthNode2()
* It is assumed that the label is placed on F2 side.
* i.e., VRRectLabelEdge::typeNode2() == POS_CLOCKWISE.
*
* W11: Width of the label edge of E1 in the middle of the edge.
* It is assumed that the label is placed on the center of E1.
* i.e., VRRectLabelEdge::typeNode2() == POS_CENTER.
* W11 := VRRectLabelEdge::widthMiddle()
*
* W12: Width of the label edge of E1 on the N1 side.
* W12 := VRRectLabelEdge::widthNode1()
* It is assumed that the label is placed on F1 side.
* i.e., VRRectLabelEdge::typeNode1() == POS_COUNTER_CLOCKWISE.
*
* W13: Horizontal extent of the label edges of E1 on the right hand side,
* i.e., F2 side.
* W13 := DGEdgeAux::mLabelWidthRight for D1
* := max {DGEdgeAux::mLabelWidthUpperRight,
* DGEdgeAux::mLabelWidthMiddleRight,
* DGEdgeAux::mLabelWidthLowerRight }
*
* W14: Horizontal extent of the label edges of D1 on the right hand side,
* i.e., F1 side.
* W14 := DGEdgeAux::mLabelWidthLeft
* := max {DGEdgeAux::mLabelWidthUpperLeft,
* DGEdgeAux::mLabelWidthMiddleLeft,
* DGEdgeAux::mLabelWidthLowerLeft }
*
* W15: Width required to accommodate the absorbee VRs under N2
* between E1 and the edge to the left of it. It is calculated
* in the same way as W7.
*
* W16: F1's Right pane's share of W15. It's w15/2.0.
* W9 := DGEdgeAux::mChildrenWidthUpperLeft for D1.
*
* W17: Width required to accommodate the absorbee VRs at N1 whose absorber
* face is F2, and incident edges are E1 and E3 and HG/2.
* This is one of two halves of absorbee VRs that goes over N1 and to the
* right of E1. The extra HG/2 is required to keep this area and the
* others on the other side of the face apart at least by HG.
*
* W17 := DGEdgeAux::mChildrenWidthLowerRight for D1.
*
* W18: Width required to accommodate the absorbee VRs at N1 whose absorber
* face is F2, and incident edges are E1 and E3 and HG/2 This is one of
* two halves of absorbee VRs that goes under N1 and to the right of E3.
*
* W19: Width required to accommodate the absorbee VRs at N1 whose absorber
* face is F1. This is one of two halves of the absorbee VRs that goes
* over N1 and to the left of E1.
*
* W20: Extent from the center (X1) of F1 to the right along D1 to accommodate
* all the features on the left hand side of D1.
* W20 := DGEdgeAux::mLeftInset
* := max{DGEdgeAux::mChildrenWidthUpperLeft,
* DGEdgeAux::mChildrenWidthLowerLeft }
* + HG + mLabelWidthLeft
*
* W21: Extent from the center (X2) of F2 to the left along D1 to accommodate
* all the features on the right hand side of D1.
* W21 := DGEdgeAux::mRightInset
* := max{DGEdgeAux::mChildrenWidthUpperRight,
* DGEdgeAux::mChildrenWidthLowerRight }
* + HG + mLabelWidthRight
*
* W22: Total cost for D1 to accommodate all the features horizontally between
* F1 and F2.
* W22 := max {
* W20 + W21,
* DGEdgeAux::mWidthLabelShareUpper,
* DGEdgeAux::mWidthLabelShareLower
* }
* := DGEdgeAux::mCost
*
*
* H23: Height of the node label of N2.
* H23 := EGNodeAux::mCost
* := VRRectLabelGraph::height()
*
* H24: Height required to accommodate the absorbee VRs under N2
* between E1 and E2. The Height is calculated as follows.
*
* H24 := max{H_vri} where H_vri is the height of the absorbee VRi.
* := EGEdgeAux::mChildrenHeightUpperRight
*
* H25: Height of the node label of N1.
* H25 := EGNodeAux::mHeight
* := VRRectLabelGraph::height()
*
* H26: Height required to accommodate the absorbee VRs over N1
* between E1 and E3.
* This is one of two halves of absorbee VRs that goes over N1 and to the
* right of E1. The height is calculated as follows.
*
* H26 := max{H_vri} where H_vri is the height of the absorbee VRi.
* := EGEdgeAux::mChildrenHeightLowerRight
*
* H27: Height required to accommodate the edge labels of E1.
* H27 := EGEdgeAux::mLabelHeight
*
* H28: Height required to accommodate the absorbee VRs under N2
* between E1 and the one to the left of it.
* The Height is calculated as follows.
*
* H28 := max{H_vri} where H_vri is the height of the absorbee VRi.
* := EGEdgeAux::mChildrenHeightUpperLeft
*
* H29: Height required to accommodate the absorbee VRs over N1
* between E1 and E3.
* This is one of two halves of absorbee VRs that goes over N1 and to the
* left of E1. The height is calculated as follows.
*
* H26 := max{H_vri} where H_vri is the height of the absorbee VRi.
* := EGEdgeAux::mChildrenHeightLoweLeft
*
* H30: Total cost for E1 to accommodate all the features vertically along E1.
* H30 := max{
* EGEdgeAux::mLabelHeight,
*
* max{
* EGEdgeAux::mChildrenHeightUpperRight
* EGEdgeAux::mChildrenHeightUpperLeft
* } + VG +
* max{
* EGEdgeAux::mChildrenHeightLowerRight
* EGEdgeAux::mChildrenHeightLowerLeft
* }
* }
* := EGEdgeAux::mCost
*
*
* X31: Horizontal coordiate assigned to E1.
*
* X3 := (X2 - W21) + (X1 + W20) / 2
* := EGEdgeAux::mX
* Note the value (X2 - W21) - (X1 + W20) is a slack on D1 after X1 and X2
* are determined.
*
* Ex. Outer face, bottom node.
*
*
* X1 X2
* | |
* H12
* +-----------------------------------+ + +
* | S | | |
* Y9 +---++-----+-------------------------------++ + |
* | || | | || | |
* | ||E1 | T* .. S* |
* | || | | .. . | |
* | || | F1 . .. . |
* D1 ...==|===||=====|====| | | || | | |
* | || | |E2|| | D2 |
* | || | | |==|==||=|======| |
* | || | | || | |
* | || | | | | || | | |
* +---++-+---+-----------------------++--++-+ + + |
* | |T | | | | |
* Y8 +--+---------------------------+----+ | + |
* | | |H11 |
* | | | |
* +---------------------------+ + +
* H10 H13
* W3 <--> W4 <->
* W5 <--------------------------->
* <------------------------------------------------> W6
*
* <------------------------------------------------> W7
*
*
* S: The top node of the absorber block with the highest rank.
* T: The bottom node to which the absorbee blocks are unified.
*
* S*: The outer face of the block.
* T*: The right face. The other face of S* across {S,T}.
*
* E1: Edge {S,T} that runs through the left side of the block
* D1: Dual Edge {S*,T*}. The lest-most dual edge.
* E2: Edge incident to S* and T.
* D2: Dual Edge of E2.
*
* X1: X-position of Edge E1. X1 := EGEdgeAux::mX
* X2: X-position of Edge E2. X2 := EGEdgeAux::mX
*
* W3: Horizontal extent of the label edges of E1 on the left hand side.
* W3 := DGEdgeAux::mLabelWidthLeft
*
* W4: Horizontal extent of the label edges of E2 on the right hand side.
* W4 := DGEdgeAux::mLabelWidthRight
*
* W5: Width required to accommodate the absorbee VRs under T
* between E1 and E2 in S*.
* W5 := ETNodeAux::mExtraWidthBottom
*
* W6: Width required to accommodate all the other features execpt for the
* absorbee VRs for the outer face/bottom node.
* W6 := DGFaceAux::mEarlyStart for S* - X1 + W3.
*
* W7: Width required for this block.
* W7 := max{ W6, W7 }
* := ETNodeAux::mWidth
*
* Y8: lower edge of the node T EGNodeAux::mEarlyStart
*
* Y9: lower edge of the node S EGNodeAux::mEarlyStart
*
* H10: Height required to accommodate the absorbee VRs under T.
* H10: ETNodeAux::mExtraHeightBottom + EGNodeAux::mLabelHeight
*
* H11: Height of the node label of T.
* H11 := EGNodeAux::mLabelHeight
* := VRRectLabelGraph::height()
*
* H12: Height of the node label of S.
* H12 := EGNodeAux::mLabelHeight
* := VRRectLabelGraph::height()
*
* H13: Height required for this block.
* H13 := Y9 - Y8 + H12 + H10 - H11
* := ETNodeAux::mHeight
*
* ===================================================
* Allocating spaces for vertex label and edge labels
* ===================================================
*
* The height of the node label is dealt with by the costs of the nodes.
* The width is distributed evenly among duals of the incident edges.
*
* EGNodeAux::mLabelHeight for N := VRRectLabelNode::height() for N.
*
* eu1 eu2 eu3 eu4 euN
* | | | | |
* | | | | |
* | | | | |
* | | | | |
* +---------------------------+
* | |
* fL | N | fR
* | |
* +---------------------------+
* | | | | |
* | | | | |
* | | | | |
* | | | | |
* el1 el2 el3 el4 elM
*
* EGEdgeAux::
* Assume there are N edge from above, and M edges from below.
* The width of node label width(label) is evenly distributed among them.
*
* DGEdgeAux::mWidthLabelShareUpper for upper node
* := VRRectLabelNode::width()/N
* DGEdgeAux::mWidthLabelShareUpper for lower node
* := VRRectLabelNode::width()/M
*
* There are 3 edge labels along the edge: one closer to node 1, one in the
* middle, and one closer to node 2. Each edge is places any of three
* hozirontal positions. in the right face, in the center of the edge, and
* in the left face.
*
* N2 ========+=======
* +-------+------+
* | |+----+|
* | || L2 || Closer to N1, positioned in the right face
* | |+----+|
* | | |
* |+-----+| |
* || || |
* || Lm || | In the middle, positioned in the left face
* || || |
* |+-----+|E1 |
* fL | | | fR
* | +-+ |
* | |L1 | Closer to N2, positioned in the center
* | | | |
* | +-+ |
* +-------+------+
* N1 ========+========
*
* The height of those three labels are dealt with in the cost of the edge E1.
* EGEdgeAux::mLabelHeight := VRRectLabelEdge::heightNode1() +
* VRRectLabelGraph::verticalGap() +
* VRRectLabelEdge::heightMiddle() +
* VRRectLabelGraph::verticalGap() +
* VRRectLabelEdge::heightNode2()
*
* The widths of those three labels are dealt with in the cost of the dual of
* E1
*
* 1. Assuming all the three labels exist and are positioned in the right face
* then we have to accommodate the space for them.
*
* DGEdgeAux::mLabelWidthLeft := 0.0
*
* DGEdgeAux::mLabelWidthRight := max { VRRectLabelEdge::widthNode1(),
* VRRectLabelEdge::widthMiddle(),
* VRRectLabelEdge::heightNode2() }
*
* 2. Assuming all the three labels exist and are positioned in the center.
*
* DGEdgeAux::mLabelWidthLeft := max { VRRectLabelEdge::widthNode1()/2.0,
* VRRectLabelEdge::widthMiddle()/2.0,
* VRRectLabelEdge::heightNode2()/2.0 }
*
* DGEdgeAux::mLabelWidthRight := max { VRRectLabelEdge::widthNode1()/2.0,
* VRRectLabelEdge::widthMiddle()/2.0,
* VRRectLabelEdge::heightNode2()/2.0 }
*
* 3. Assuming all the three labels exist and are positioned in the left face
* then we have to accommodate the space for them.
*
* DGEdgeAux::mLabelWidthLeft := max { VRRectLabelEdge::widthNode1(),
* VRRectLabelEdge::widthMiddle(),
* VRRectLabelEdge::heightNode2() }
*
* DGEdgeAux::mLabelWidthRight := 0.0
*
* ====================
* Input data structure
* ====================
* First, the input connected graph must be planar.
* It must be represented by VRRectLabelGraph[Node,Edge], which provides
* means to handle rectangular label dimensions in integer.
*
* The graph then must be decomposed into BCTree, and then an embedding
* must be given in EmbeddedBCTree.
* EmbeddedBCTree generates ExplorationTree as a result of generating
* a geometric embedding of the connected graph.
* EmbeddedBCTree::ExplorationTree is the input to VisRepFinder.
*
* The overall flow of preparation is drawn as follows.
*
* VRRectLabelGraph[Node,Edge] : Original input the user must create.
*
* || biconnected
* \||/ decomposition
*
* BCTree
*
* || embedding of each
* || block and the
* || face unification
* || groups at each
* \||/ cut vertex
*
* EmbeddedBCTree
*
* || top node and outer face of
* || each block, absorber-absorbee
* || relationships at each face
* \||/ unification group.
*
* EmbeddedBCTree::ExplorationTree
*
* - VRRectLabel{Node,Edge} and Block{Node,Edge} in BCTreeNode.block()
* must be cross-linked.
*
* - Block{Node,Edge} in BCTreeNode.block() and Embedded{Node,Edge} in
* EmbeddedBCTreeNode.embeddedGraph() must be cross-linked.
*
* - BCTree{Node,Edge} in BCTree and EmbeddedBCTree{Node,Edge}
* must be cross-linked.
*
* - ExplorationNode in ExplorationTree and EmbeddedBCTreeNode
* must be cross-linked.
*
*
*
* =====================
* Output data structure
* =====================
* VisRepFinder::find() does the following.
*
* EmbeddedBCTree::ExplorationTree
*
* || x- and y-coordinates of each
* || node and the edges. A node is
* || representation by a horizontal
* || line segment, and an edge is
* || by a vertical one. A node label
* || can be placed at the center of
* || the line segment. Edge label
* || can be placed along the vertical
* \||/ line segment at an appropriate location.
*
* VRRectLabelGraph[Node,Edge]
*
*
* ============
* Classes List
* ============
* - VisRepFinder : The main class the user uses.
*
*
* - VRRectLabelGraph : The input graph the user specifies with the
* geometric information.
* - VRRectLabelGraphNode : The input graph node with the rectangular label
* dimensions.
* - VRRectLabelGraphEdge : The input graph edge with the rectangular label
* dimensions.
*
* Following 5 classes are used internally in VisRepFinder
*
* - EGNodeAux : Internal data structure used to augument EmbeddedNode
* in the embedding of the blocks in the BCTree.
*