DarianFlorianVoda / BioShapes

Bachelor Thesis R Package
0 stars 0 forks source link

[Arrows] Tail: Squarewave #70

Closed discoleo closed 2 years ago

discoleo commented 2 years ago

Arrow with Tail a SquareWave

Also an example how to implement different types of arrow-tails.

Helper Functions

### Split Line
#' @export
split.line = function(x, y, n) {
    if(n == 1) {
        lst = list(x=x, y=y);
        return(lst);
    }
    if(n <= 0) stop("Wrong number of fragments!");
    # Split
    t  = seq(n - 1) / n;
    rt = rev(t);
    xs = x[1]*rt + x[2]*t;
    ys = y[1]*rt + y[2]*t;
    xs = c(x[1], xs, x[2]);
    ys = c(y[1], ys, y[2]);
    lst = list(x=xs, y=ys);
    return(lst);
}

Arrow Function

### Arrow: Tail = Square Wave
#' @export
arrowSquareWave = function(x, y, n, d=-0.5, dV=c(-1,1), d.head=c(-d,d),
        col=1, lwd=1, h.lwd=lwd, scale=1, join=0) {
  if(join > 2) stop("Unsupported value for join!");
  slope = compute_slope(x, y);
  ### Head
  ahead = list(arrowHeadSimple(x[2], y[2], slope=slope, d=d, dV=d.head, scale=scale),
    lwd = h.lwd);
  ### ArrowTail
  l = shiftLine(x, y, d=dV, slope=slope, scale=scale);
  # Split lines:
  p1 = c(x[1], y[1]);
  p2 = c(x[2], y[2]);
  # l0 = split.line(p1, p2, n+1);
  l1 = l[l$id == 1, c("x", "y")];
  l1 = split.line(l1[,1], l1[,2], n+1);
  l2 = l[l$id == 2, c("x", "y")];
  l2 = split.line(l2[,1], l2[,2], n+1);
  # Join lines:
  join.lines = function(l, l1, l2) {
    pos = length(l1) - 1; # before last
    mid = (l1[pos] + l2[pos]) / 2;
    if(n %% 2 == 1) {
        l1 = head(l1, -1);
        l2 = c(tail(head(l2, -2), -1), mid, mid);
    } else {
        l1 = head(l1, -2);
        l2 = c(tail(head(l2, -1), -1));
    }
    l1 = matrix(l1, nrow=2);
    l2 = matrix(l2, nrow=2);
    lt = rbind(l1, l2);
    lt = c(as.vector(lt));
    if(n %% 2 == 0) lt = c(lt, mid);
    lt = c(l[1], lt, l[2]);
  }
  x = join.lines(x, l1$x, l2$x);
  y = join.lines(y, l1$y, l2$y);
  arrow = list(list(x=x, y=y), lwd=lwd);
  ### Full Arrow
  lst = list(Arrow=arrow, Head=ahead);
  class(lst) = c("arrow", "list");
  # Plot lines:
  lines(lst, col=col);
  invisible(lst);
}

Tests for Arrows

Square-Wave Arrow

x = c(1,5); y = c(1,7); plot.base() arrowSquareWave(x, y, n=5) arrowSquareWave(x + c(0, 4), y - c(0, 3), n=6, col="red")

No. of Teeth: Variations

x = c(-1, 8); y = c(0, 0); dy = 2.5; plot.base() arrowSquareWave(x, y, n=5) arrowSquareWave(x, y + 1dy, n=6) arrowSquareWave(x, y + 2dy, n=7) arrowSquareWave(x, y + 3*dy, n=8)

DarianFlorianVoda commented 2 years ago

Added.