File: selectpoints3d.R

package info (click to toggle)
rgl 1.3.36-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,968 kB
  • sloc: cpp: 23,234; ansic: 7,462; javascript: 5,668; sh: 3,555; makefile: 2
file content (69 lines) | stat: -rw-r--r-- 1,933 bytes parent folder | download | duplicates (2)
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
selectpoints3d <- function(objects = ids3d()$id, value = TRUE, closest = TRUE, 
                           multiple = FALSE, ...) {

  if (value) result <- cbind(x = numeric(0), y = numeric(0), z = numeric(0))
  else result <- cbind(id = integer(0), index = integer(0))

  first <- TRUE
  prevdist <- dist <- Inf
  
  while (first || is.function(multiple) || multiple) {
    f <- select3d(...)
    if (is.null(f)) break
    
    e <- environment(f)
    
    prev <- nrow(result) # Number to keep from previous selection
    
    for (id in objects) {
      verts <- expandVertices(id)
      hits <- f(verts)
      
      if (any(hits)) dist <- 0
      else if (closest && dist > 0 && nrow(verts)) {
        wincoords <- rgl.user2window(verts, projection = e$proj)
        wz <- wincoords[,3]
        keep <- (0 <= wz) & (wz <= 1)
        wincoords <- wincoords[keep,,drop=FALSE]
  
        if (!nrow(wincoords)) next 
  
        wx <- wincoords[,1]
        xdist <- ifelse(wx < e$llx, (wx-e$llx)^2, ifelse(wx < e$urx, 0, (wx-e$urx)^2))
   
        wy <- wincoords[,2]      
        ydist <- ifelse(wy < e$lly, (wy-e$lly)^2, ifelse(wy < e$ury, 0, (wy-e$ury)^2))  
  
        dists <- xdist + ydist
        hits <- (dists < dist) & (dists == min(dists))
        dist <- min(c(dist, dists))
      }
      
      if (!any(hits)) next
      
      if (prev && prevdist > dist) {
        result <- result[FALSE, , drop = FALSE]
        prev <- 0
      }
        
      if (value)
        result <- rbind(result, verts[hits,])
      else {
        indices <- getIndices(id)[which(hits)]
        result <- rbind(result, cbind(id, indices))
      }
      if (is.function(multiple) && nrow(result) > prev
          && !multiple(result[(prev+1):nrow(result),,drop=FALSE]))
        break  
        
      prevdist <- dist
      prev <- nrow(result)
      first <- FALSE
    }
    
    if (value)
      result <- unique(result)
  
  }
  result
}