@@ -63,16 +63,22 @@ export default {
63
63
/**
64
64
* compute node positions during rotation
65
65
* given x-y coordinates of the root and the child, compute the
66
- * intermediate position after step 1 or step 2
66
+ * intermediate position after step 1, step 2, ...
67
67
* coords represented as record with fields rX, rY, cX, cY (root X&Y,
68
68
* child X&Y)
69
+ * Steps 1&2:
69
70
* We keep the edge the same length and rotate it around the point 40%
70
71
* along the edge from the root. If initially the y coordinate of the
71
72
* root is 1 and the child is zero, after step 1 the root is at 2/3
72
73
* and the child is at 1/2 and after step 2 the root is at 1/3 and the
73
74
* child is at 1. The x coordinates are computed so as to keep the length
74
75
* of the edge same (magic numbers derived from maths).
75
76
* returns record with new coordinates
77
+ * Further steps:
78
+ * Not coded here but in the next steps the (new) root is moved
79
+ * more towards the center and the (new) child (and it's child?)
80
+ * is moved down.
81
+ *
76
82
*/
77
83
function rotateStep ( pos0 , step ) {
78
84
@@ -82,14 +88,16 @@ export default {
82
88
// edge length = sqrt(deltaX**2 + deltaY**2)
83
89
let deltaX1 ; // deltaX for new position
84
90
let pos1 = { rX :0 , rY :0 , cX :0 , cY :0 } ;
85
- if ( step == 1 ) {
91
+ if ( step === 1 ) {
86
92
pos1 . rY = ( 2 * rY + cY ) / 3 ;
87
93
pos1 . cY = ( rY + cY ) / 2 ;
88
94
deltaX1 = Math . sqrt ( ( 35 / 36 ) * deltaY ** 2 + deltaX ** 2 ) ;
89
- } else { // assume step == 2
95
+ } else if ( step === 2 ) {
90
96
pos1 . rY = ( rY + 2 * cY ) / 3 ;
91
97
pos1 . cY = rY ;
92
98
deltaX1 = Math . sqrt ( ( 5 / 9 ) * deltaY ** 2 + deltaX ** 2 ) ;
99
+ } else {
100
+ console . log ( 'Invalid rotateStep step ' , step ) ;
93
101
}
94
102
if ( rX > cX ) // reverse direction of deltaX
95
103
deltaX1 = - deltaX1 ;
@@ -100,13 +108,16 @@ export default {
100
108
101
109
// We apply the following char notations in our rotation code.
102
110
// It helps code reusability and readability.
111
+ // XXX might be good to change some of these (RR+RL added
112
+ // later); note that P is not necessarilty the *global* root, R
113
+ // can stand for root and right.
103
114
// tNum / charNotation
104
115
//
105
116
// P/G (Global root /Parent) P/G
106
117
// | |
107
118
// 6/R 2/R
108
119
// / \ Right Rotation / \
109
- // 2/A 7 - - - - - - - > 1 6/A
120
+ // 2/A 7/RR - - - - - - - > 1/RL 6/A
110
121
// / \ < - - - - - - - / \
111
122
// 1 4/D Left Rotation 4/D 7
112
123
@@ -176,8 +187,6 @@ export default {
176
187
}
177
188
178
189
// -- following code is for visualising the rotation step by step --
179
- let rootNode = vis . graph . findNode ( tt2 ) ;
180
- let leafNode = vis . graph . findNode ( tt2 ) ;
181
190
// freeze the layout to avoid the nodes moving automatically
182
191
vis . graph . setPauseLayout ( true ) ;
183
192
let pos0 = vis . graph . getRotPos ( ) ; // original position
@@ -192,7 +201,6 @@ export default {
192
201
// let t2's right child point to t6
193
202
chunker . add ( 't2.right = t6' ,
194
203
( vis , t6 , t2 , t4 , p , rotate ) => {
195
- // highlight the edge between t2 and t6
196
204
if ( rotate ) vis . graph . visit ( t2 , p ) ;
197
205
198
206
vis . graph . removeEdge ( t6 , t2 ) ;
@@ -206,24 +214,42 @@ export default {
206
214
vis . graph . addEdge ( t2 , t6 ) ;
207
215
208
216
if ( t4 !== null ) vis . graph . removeEdge ( t6 , t4 ) ;
217
+ // set the new position of the node(s)
218
+ // - just move (new) root node towards center more.
219
+ // New child and grandchild moved in next chunk -
220
+ // could do them here also but less confusing as is?
221
+ let pos0 = vis . graph . getRotPos ( ) ; // original position
222
+ let pos2 = rotateStep ( pos0 , 2 ) ; // previous position
223
+ vis . graph . setNodePosition ( t2 , ( pos0 . rX + 3 * pos0 . cX ) / 4 , pos2 . cY ) ;
209
224
} ,
210
225
[ R . key , A . key , D ? D . key : null , parentNode ? parentNode . key : null , rotateVis ] ,
211
226
depth
212
227
) ;
213
228
229
+ let RR = ( R . right ? R . right . key : null ) ;
214
230
// if t4 is not null, let t6's left child point to t4
215
231
// if (D) { // we now animate this step even if t4 is null
216
- chunker . add ( 't6.left = t4' ,
217
- ( vis , r , d ) => {
218
- if ( d !== null ) vis . graph . addEdge ( r , d ) ;
219
- } ,
220
- [ R . key , D ? D . key : null ] ,
221
- depth
222
- )
223
- // }
232
+ chunker . add ( 't6.left = t4' ,
233
+ ( vis , t6 , t6r , t2 , t4 , p , rotate ) => {
234
+ // vis.graph.setMoveRatio(9/10);
235
+ if ( t4 !== null ) vis . graph . addEdge ( t6 , t4 ) ;
236
+ // set the new position of the nodes
237
+ // - just move (new) child node down more
238
+ // plus it's child also (if it has one)
239
+ let pos0 = vis . graph . getRotPos ( ) ; // original position
240
+ let pos2 = rotateStep ( pos0 , 2 ) ; // position after step 2
241
+ let deltaY = ( pos2 . rY - pos0 . rY ) / 3 ;
242
+ vis . graph . setNodePosition ( t6 , pos2 . rX , pos2 . rY + deltaY ) ;
243
+ if ( t6r !== null ) {
244
+ vis . graph . moveNodePosition ( t6r , 0 , deltaY ) ;
245
+ }
246
+ } ,
247
+ [ R . key , RR , A . key , D ? D . key : null , parentNode ? parentNode . key : null , rotateVis ] ,
248
+ depth
249
+ )
224
250
225
251
// perform the rotation in our objects
226
- const temp = root . left ;
252
+ const temp = root . left ; // XXX temp = A ???
227
253
root . left = temp . right ;
228
254
temp . right = root ;
229
255
updateHeight ( root ) ;
@@ -252,15 +278,20 @@ export default {
252
278
253
279
// finalise the rotation
254
280
chunker . add ( 'return t2' ,
255
- ( vis , p , t2 , t6 ) => {
281
+ ( vis , g , p , t2 , t6 ) => {
256
282
// vis.graph.clearTID();
283
+ console . log ( g , p , t2 , t6 ) ;
257
284
vis . graph . updateTID ( t2 , 't2' ) ;
258
285
if ( p !== null ) {
259
286
vis . graph . removeEdge ( p , t6 ) ;
260
287
vis . graph . addEdge ( p , t2 ) ;
261
288
}
289
+ vis . graph . setMoveRatio ( 3 / 6 ) ;
290
+ vis . graph . setPauseLayout ( false ) ;
291
+ vis . graph . layoutAVL ( g , true , false ) ;
292
+ vis . graph . rectangle_size ( ) ;
262
293
} ,
263
- [ parentNode ? parentNode . key : null , A . key , R . key ] ,
294
+ [ parentNode ? globalRoot . key : temp . key , parentNode ? parentNode . key : null , A . key , R . key ] ,
264
295
depth
265
296
) ;
266
297
@@ -360,20 +391,38 @@ export default {
360
391
vis . graph . addEdge ( t6 , t2 ) ;
361
392
// remove edge after layout to perform the middle step
362
393
if ( t4 !== null ) vis . graph . removeEdge ( t2 , t4 ) ;
394
+ // set the new position of the nodes
395
+ // - just move (new) root node towards center more.
396
+ // New child and grandchild moved in next chunk -
397
+ // could do them here also but less confusing as is?
398
+ let pos0 = vis . graph . getRotPos ( ) ; // original position
399
+ let pos2 = rotateStep ( pos0 , 2 ) ; // previous position
400
+ vis . graph . setNodePosition ( t6 , ( pos0 . rX + 3 * pos0 . cX ) / 4 , pos2 . cY ) ;
363
401
} ,
364
402
[ R . key , A . key , D ? D . key : null , parentNode ? parentNode . key : null , rotateVis ] ,
365
403
depth
366
404
) ;
367
405
406
+ let RL = ( R . left ? R . left . key : null ) ;
368
407
// if t4 is not null, let t2's right child point to t4
369
408
// if (D) { // we now animate this step even if t4 is null
370
- chunker . add ( 't2.right = t4' ,
371
- // reconnect the edge between t2 and t4
372
- ( vis , r , d ) => {
373
- if ( d !== null ) vis . graph . addEdge ( r , d ) ;
374
- } ,
375
- [ R . key , D ? D . key : null ] ,
376
- depth
409
+ chunker . add ( 't2.right = t4' ,
410
+ // reconnect the edge between t2 and t4
411
+ ( vis , t2 , t2l , t6 , t4 , p , rotate ) => {
412
+ if ( t4 !== null ) vis . graph . addEdge ( t2 , t4 ) ;
413
+ // set the new position of the nodes
414
+ // - just move (new) child node down more
415
+ // plus it's child also (if it has one)
416
+ let pos0 = vis . graph . getRotPos ( ) ; // original position
417
+ let pos2 = rotateStep ( pos0 , 2 ) ; // position after step 2
418
+ let deltaY = ( pos2 . rY - pos0 . rY ) / 3 ;
419
+ vis . graph . setNodePosition ( t2 , pos2 . rX , pos2 . rY + deltaY ) ;
420
+ if ( t2l !== null ) {
421
+ vis . graph . moveNodePosition ( t2l , 0 , deltaY ) ;
422
+ }
423
+ } ,
424
+ [ R . key , RL , A . key , D ? D . key : null , parentNode ? parentNode . key : null , rotateVis ] ,
425
+ depth
377
426
)
378
427
// }
379
428
@@ -407,15 +456,19 @@ export default {
407
456
408
457
// finalise the rotation
409
458
chunker . add ( 'return t6' ,
410
- ( vis , p , t6 , t2 ) => {
459
+ ( vis , g , p , t6 , t2 ) => {
411
460
// vis.graph.clearTID();
412
461
vis . graph . updateTID ( t6 , 't6' ) ;
413
462
if ( p !== null ) {
414
463
vis . graph . removeEdge ( p , t2 ) ;
415
464
vis . graph . addEdge ( p , t6 ) ;
416
465
}
466
+ vis . graph . setMoveRatio ( 3 / 6 ) ;
467
+ vis . graph . setPauseLayout ( false ) ;
468
+ vis . graph . layoutAVL ( g , true , false ) ;
469
+ vis . graph . rectangle_size ( ) ;
417
470
} ,
418
- [ parentNode ? parentNode . key : null , A . key , R . key ] ,
471
+ [ parentNode ? globalRoot . key : temp . key , parentNode ? parentNode . key : null , A . key , R . key ] ,
419
472
depth
420
473
) ;
421
474
return temp ; // new root node after the rotation
@@ -442,6 +495,7 @@ export default {
442
495
vis . graph . updateHeight ( r . key , r . height ) ;
443
496
vis . graph . setPauseLayout ( false ) ;
444
497
vis . graph . layoutAVL ( g , true , false ) ;
498
+ vis . graph . rectangle_size ( ) ;
445
499
} , [ ( parentNode !== null ) ? globalRoot . key : root . key , root . left ] , depth ) ;
446
500
447
501
// chunker.add('return right rotation on t', (vis) => { }, [], depth);
@@ -471,9 +525,9 @@ export default {
471
525
vis . graph . updateHeight ( r . key , r . height ) ;
472
526
vis . graph . setPauseLayout ( false ) ;
473
527
vis . graph . layoutAVL ( g , true , false ) ;
528
+ vis . graph . rectangle_size ( ) ;
474
529
} , [ ( parentNode !== null ) ? globalRoot . key : root . key , root . right ] , depth ) ;
475
530
476
- // chunker.add('return left rotation on t', (vis) => { }, [], depth);
477
531
478
532
// perform left rotation on the root node
479
533
return RRCR ( root , parentNode , depth , true ) ;
@@ -548,7 +602,7 @@ export default {
548
602
);
549
603
*/
550
604
551
- // update the chilld of the parent node
605
+ // update the child of the parent node
552
606
if ( parentNode !== null ) {
553
607
if ( key < parentNode . key ) {
554
608
parentNode . left = root ;
@@ -664,6 +718,7 @@ export default {
664
718
// clear the function information after the rotation
665
719
// and tidy up the nodes' position
666
720
chunker . add ( 'return rightRotate(t)' , ( vis , g , r ) => {
721
+ vis . graph . setMoveRatio ( 1 ) ;
667
722
vis . graph . updateHeight ( r . key , r . height ) ;
668
723
vis . graph . setFunctionNode ( null ) ;
669
724
vis . graph . clearSelect_Circle_Count ( ) ;
@@ -700,6 +755,7 @@ export default {
700
755
// clear the function information after the rotation
701
756
// and tidy up the nodes' position
702
757
chunker . add ( 'return leftRotate(t)' , ( vis , g , r ) => {
758
+ vis . graph . setMoveRatio ( 1 ) ;
703
759
vis . graph . updateHeight ( r . key , r . height ) ;
704
760
// vis.graph.clearTID();
705
761
vis . graph . setFunctionNode ( null ) ;
@@ -736,6 +792,7 @@ export default {
736
792
// clear the function information after the rotation
737
793
chunker . add ( 'return rightRotate(t) after leftRotate' ,
738
794
( vis , g , r ) => {
795
+ vis . graph . setMoveRatio ( 1 ) ;
739
796
vis . graph . updateHeight ( r . key , r . height ) ;
740
797
// vis.graph.clearTID();
741
798
vis . graph . setFunctionNode ( null ) ;
@@ -775,6 +832,7 @@ export default {
775
832
// clear the function information after the rotation
776
833
chunker . add ( 'return leftRotate(t) after rightRotate' ,
777
834
( vis , g , r ) => {
835
+ vis . graph . setMoveRatio ( 1 ) ;
778
836
vis . graph . updateHeight ( r . key , r . height ) ;
779
837
// vis.graph.clearTID();
780
838
vis . graph . setFunctionNode ( null ) ;
@@ -804,6 +862,8 @@ export default {
804
862
vis . graph . isWeighted = true ;
805
863
vis . graph . setFunctionName ( 'Tree is Empty' ) ;
806
864
vis . graph . setFunctionInsertText ( `` ) ;
865
+ vis . graph . setPauseLayout ( false ) ;
866
+ vis . graph . setMoveRatio ( 1 ) ;
807
867
vis . array . patch ( 0 ) ;
808
868
// make a bit more room for tree
809
869
vis . graph . setSize ( 2.5 ) ;
0 commit comments