@@ -655,232 +655,22 @@ wilkinson_bin_from_center = function(x, width) {
655655
656656# weave swarm -------------------------------------------------------------
657657
658- # ' Find the last value in `values` less than or equal to `target`
659- # ' @param values <[numeric]> sorted vector
660- # ' @param target <[numeric]> value to compare to
661- # ' @returns <[numeric]> last value in x less than or equal to val, or -Inf if none
662- # ' @noRd
663- last_lte = function (values , target ) {
664- i = findInterval(target , values )
665- if (i == 0 ) - Inf else values [[i ]]
666- }
667-
668- # ' Find the first value in `values` greater than `target`
669- # ' @param values <[numeric]> sorted vector
670- # ' @param target <[numeric]> value to compare to
671- # ' @returns <[numeric]> first value in x greater than val
672- # ' @noRd
673- first_gt = function (values , target ) {
674- i = findInterval(target , values ) + 1
675- if (i > length(values )) Inf else values [[i ]]
676- }
677-
678- # ' Can we place candidate at this position given the last placed dot and
679- # ' the previous rows of dots placed so far?
680- # ' @param candidate <scalar [numeric]> candidate x position
681- # ' @param last_placed <scalar [numeric]> last placed x position in this row
682- # ' @param last_rows <[list] of [numeric]> list of previous rows of placed dots
683- # ' @param y_grid <scalar [integer]> number of previous rows in the y grid that
684- # ' could overlap with this candidate
685- # ' @param xsize <scalar [numeric]> horizontal spacing between dots
686- # ' @param reverse <scalar [logical]> are we placing dots in reverse order?
687- # ' @returns <scalar [logical]> can we place candidate here?
688- # ' @noRd
689- can_place_candidate_old = function (candidate , last_placed , last_rows , y_grid , xsize , reverse ) {
690- if (reverse ) {
691- if (candidate > last_placed - xsize ) return (FALSE )
692- } else {
693- if (candidate < last_placed + xsize ) return (FALSE )
694- }
695- for (i in seq_len(y_grid - 1 )) {
696- last_row_i = last_rows [[i ]]
697- if (length(last_row_i ) == 0 ) next
698-
699- y_offset = i / y_grid
700- min_x_dist = sqrt(1 - y_offset ^ 2 ) * xsize
701- last_val_lte_candidate_idx = findInterval(candidate , last_row_i )
702- if (last_val_lte_candidate_idx > 0 ) {
703- last_val_lte_candidate = last_row_i [[last_val_lte_candidate_idx ]]
704- if (candidate < last_val_lte_candidate + min_x_dist ) return (FALSE )
705- }
706- if (last_val_lte_candidate_idx < length(last_row_i )) {
707- first_val_gt_candidate = last_row_i [[last_val_lte_candidate_idx + 1 ]]
708- if (candidate > first_val_gt_candidate - min_x_dist ) return (FALSE )
709- }
710- }
711- TRUE
712- }
713-
714658# ' Weave/swarm hybrid
715659# '
716- # ' @param x sorted x values
717- # ' @param y y values (must be constant)
718- # ' @noRd
719- weave_swarm_old = function (x , y , xsize , ysize = xsize , side = 1 ) {
720- y_grid = 4
721-
722- both = side == 0
723- remaining = x
724- rows = list ()
725- if (both ) rows_bottom = list ()
726-
727- place_row = function (reverse = FALSE , both = side == 0 ) {
728- if (length(remaining ) == 0 ) return ()
729-
730- kth_last_row = function (k , rows ) {
731- i = length(rows ) + 1 - k
732- if (i < = 0 ) numeric () else rows [[i ]]
733- }
734- last_rows = lapply(seq_len(y_grid ), kth_last_row , rows )
735- if (both ) last_rows_bottom = lapply(seq_len(y_grid ), kth_last_row , rows_bottom )
736- candidates = remaining
737- if (reverse ) candidates = rev(candidates )
738-
739- row = numeric ()
740- if (both ) row_bottom = numeric ()
741- next_remaining = numeric ()
742- last_placed = if (reverse ) Inf else - Inf
743- if (both ) last_placed_bottom = last_placed
744-
745- for (candidate in candidates ) {
746- if (can_place_candidate_old(candidate , last_placed , last_rows , y_grid , xsize , reverse )) {
747- row = c(row , candidate )
748- last_placed = candidate
749- } else if (both && can_place_candidate_old(candidate , last_placed_bottom , last_rows_bottom , y_grid , xsize , reverse )) {
750- row_bottom = c(row_bottom , candidate )
751- last_placed_bottom = candidate
752- } else {
753- next_remaining = c(next_remaining , candidate )
754- }
755- }
756-
757- if (reverse ) {
758- row = rev(row )
759- if (both ) row_bottom = rev(row_bottom )
760- next_remaining = rev(next_remaining )
761- }
762- rows <<- c(rows , list (row ))
763- if (both ) rows_bottom <<- c(rows_bottom , list (row_bottom ))
764- remaining <<- next_remaining
765- }
766-
767- # first row is special when both == TRUE: it is a "middle" row that is
768- # treated as the first row (for placement purposes) on both the top and bottom sides
769- place_row(both = FALSE )
770- if (both ) rows_bottom = rows
771-
772- while (length(remaining ) > 0 ) {
773- for (i in seq_len(y_grid - 1 )) place_row()
774- for (i in seq_len(y_grid )) place_row(reverse = TRUE )
775- place_row()
776- }
777-
778- row_y = function (rows , side ) (seq_along(rows ) - 1 ) / y_grid * ysize * side
779- df = data.frame (
780- x = unlist(rows ),
781- y = rep(row_y(rows , side = if (both ) 1 else side ), lengths(rows ))
782- )
783- if (both ) {
784- df = rbind(
785- df ,
786- data.frame (
787- x = unlist(rows_bottom [- 1 ]),
788- y = rep(row_y(rows_bottom , side = - 1 )[- 1 ], lengths(rows_bottom [- 1 ]))
789- )
790- )
791- }
792- df = df [order(df $ x ), ]
793- df $ y = df $ y + y
794- df
795- }
796-
797- # ' Weave/swarm hybrid
798- # '
799- # ' @param x sorted x values
800- # ' @param y y values (must be constant)
660+ # ' @param x <[numeric]> sorted x values
661+ # ' @param x <[numeric]> y values (should be constant)
662+ # ' @param xsize <scalar [numeric]> horizontal spacing between dots
663+ # ' @param ysize <scalar [numeric]> vertical spacing between dots
664+ # ' @param side <scalar [integer]> which side to place dots on: 0 = both, 1 = above, -1 = below
665+ # ' @returns <[data.frame]> data frame with columns x and y giving the new positions
801666# ' @noRd
802- weave_swarm_new = function (x , y , xsize , ysize = xsize , side = 1 ) {
803- y_grid = 4
804-
805- both = side == 0
806- remaining = x
807- rows = list ()
808- if (both ) rows_bottom = list ()
809-
810- place_row = function (reverse = FALSE , both = side == 0 ) {
811- if (length(remaining ) == 0 ) return ()
812-
813- candidates = remaining
814- if (reverse ) candidates = rev(candidates )
815-
816- row = numeric ()
817- if (both ) row_bottom = numeric ()
818- next_remaining = numeric ()
819- last_placed = if (reverse ) Inf else - Inf
820- if (both ) last_placed_bottom = last_placed
821-
822- n_rows_back = min(y_grid , length(rows ))
823- for (candidate in candidates ) {
824- if (can_place_candidate_(candidate , last_placed , rows , n_rows_back , y_grid , xsize , reverse )) {
825- row = c(row , candidate )
826- last_placed = candidate
827- } else if (both && can_place_candidate_(candidate , last_placed_bottom , rows_bottom , n_rows_back , y_grid , xsize , reverse )) {
828- row_bottom = c(row_bottom , candidate )
829- last_placed_bottom = candidate
830- } else {
831- next_remaining = c(next_remaining , candidate )
832- }
833- }
834-
835- if (reverse ) {
836- row = rev(row )
837- if (both ) row_bottom = rev(row_bottom )
838- next_remaining = rev(next_remaining )
839- }
840- rows <<- c(rows , list (row ))
841- if (both ) rows_bottom <<- c(rows_bottom , list (row_bottom ))
842- remaining <<- next_remaining
843- }
844-
845- # first row is special when both == TRUE: it is a "middle" row that is
846- # treated as the first row (for placement purposes) on both the top and bottom sides
847- place_row(both = FALSE )
848- if (both ) rows_bottom = rows
849-
850- while (length(remaining ) > 0 ) {
851- for (i in seq_len(y_grid - 1 )) place_row()
852- for (i in seq_len(y_grid )) place_row(reverse = TRUE )
853- place_row()
854- }
855-
856- row_y = function (rows , side ) (seq_along(rows ) - 1 ) / y_grid * ysize * side
857- print(seq_along(rows ) - 1 )
858- df = data.frame (
859- x = unlist(rows ),
860- y = rep(row_y(rows , side = if (both ) 1 else side ), lengths(rows ))
861- )
862- if (both ) {
863- df = rbind(
864- df ,
865- data.frame (
866- x = unlist(rows_bottom [- 1 ]),
867- y = rep(row_y(rows_bottom , side = - 1 )[- 1 ], lengths(rows_bottom [- 1 ]))
868- )
869- )
870- }
871- df = df [order(df $ x ), ]
872- df $ y = df $ y + y
873- df
874- }
875-
876- weave_swarm_new2 = function (x , y , xsize , ysize = xsize , side = 1 ) {
877- df = weave_swarm_new_(x , xsize , ysize , side )
667+ weave_swarm = function (x , y , xsize , ysize = xsize , side = 1 ) {
668+ df = weave_swarm_(x , xsize , ysize , side )
878669 df = df [order(df $ x ), ]
879670 df $ y = df $ y + y
880671 df
881672}
882673
883- weave_swarm = weave_swarm_new2
884674
885675# bin nudging for overlaps ------------------------------------------------
886676
0 commit comments