|
5 | 5 | base <- data[indices[-j],,drop=FALSE] |
6 | 6 |
|
7 | 7 | # Calculate the null space, generalization of normal vector for an arbitrary dimension |
8 | | - # e.g. for a plain triangle in 3D, a null space will be a 2D hyper plane orthogonal to the base |
9 | | - N <- MASS::Null(t( |
10 | | - # Remove first row from all other rows to move from points to vectors, i.e. |
11 | | - # from [em1, em2, em3, ...] we switch to [(em2-em1), (em3-em1), ...] |
12 | | - sweep(base, 2L, base[1,], check.margin=FALSE)[-1,,drop = FALSE] |
13 | | - )) |
14 | | - |
15 | | - # Handle a special case, e.g. length(indices) == 2 |
16 | | - if (ncol(N) == 0) { |
17 | | - N <- diag(1, nrow = ncol(data), ncol = ncol(data)) |
| 8 | + # e.g. for a plain triangle in 3D, a null space is a 2D hyper plane orthogonal to the base |
| 9 | + |
| 10 | + # Remove first row from all other rows to move from points to vectors, i.e. |
| 11 | + # from [em1, em2, em3, ...] we switch to [(em2-em1), (em3-em1), ...] |
| 12 | + Ut <- sweep(base, 2L, base[1,], check.margin=FALSE)[-1,,drop = FALSE] |
| 13 | + if (nrow(Ut) == 0) { |
| 14 | + # Handle a special case, e.g. length(indices) == 2 |
| 15 | + P <- diag(ncol(data)) |
| 16 | + } else { |
| 17 | + P <- diag(ncol(data)) - t(Ut) %*% solve(tcrossprod(Ut), Ut) |
18 | 18 | } |
19 | 19 |
|
20 | 20 | # Project points onto the null space and remove base offset of the base |
|
24 | 24 | # Alternatively, it is possible to do apply same shift before the projection, |
25 | 25 | # i.e. `sweep(data[...], 2L, base[1,]) %*% N` but we chose to do it after the projection |
26 | 26 | # because the projected data has smaller dimension. |
27 | | - base_offset <- as.vector(base[1,] %*% N) |
28 | | - proj <- data[new_indices, ] %*% N |
| 27 | + base_offset <- as.vector(base[1,] %*% P) |
| 28 | + proj <- data[new_indices, ] %*% P |
29 | 29 | proj <- sweep(proj, 2L, base_offset) |
30 | 30 |
|
31 | 31 | # Calculate height ratios |
|
34 | 34 | if (indices[j] %in% new_indices) { |
35 | 35 | height_current <- heights[new_indices == indices[j]] |
36 | 36 | } else { |
37 | | - height_current <- (data[indices[j],] %*% N) - base_offset |
| 37 | + height_current <- (data[indices[j],] %*% P) - base_offset |
38 | 38 | height_current <- sqrt(sum(height_current*height_current)) |
39 | 39 | } |
40 | 40 |
|
|
0 commit comments