2012-12-11 8 views
6

Mam dwuwymiarową siatkę jednostek i kilka segmentów linii, które rozpoczynają się i kończą na dowolnej liczbie wymiernej. Potrzebuję skutecznego sposobu obliczania, które komórki siatki przechodzi przez linię. Na przykład linia:Efektywny sposób obliczania kwadrantów kwadratu, linia przechodzi przez

Od (2.1, 3.9) do (3.8, 4.8) przechodzi przez komórki siatki z dolnymi lewymi punktami (2, 3), (2, 4) i (3, 4).

Czy istnieje szybki i skuteczny sposób obliczenia tych kwadrantów z punktów końcowych linii?

Będę pracował w R, ale zadziała również odpowiedź w Pythonie lub pseudokod. Dzięki!

+4

Prawdopodobnie znaczy siatki * komórek * zamiast * ćwiartki *. – lhf

+0

Dzięki tak, możesz nazwać je komórkami. Jakieś sugestie? –

+0

Możliwe duplikaty http://stackoverflow.com/questions/11694886/traverse-a-2-5d-grid (zignoruj ​​część z). – lhf

Odpowiedz

7

Ludzie, którzy pracują z danymi przestrzennymi, przez cały czas zajmują się tego rodzaju pytaniami, więc może warto wspierać ich wysiłki. Oto rozwiązanie, które wykorzystuje rastrowych pakiet R (oraz funkcji z sp pakietu, od której zależy):

library(raster) 

## Create a SpatialLines object 
a <- c(2.1, 3.9) 
b <- c(3.8, 4.8) 
## Method #1 -- Uses functions from the sp package. 
SL <- SpatialLines(list(Lines(list(Line(rbind(a,b))), "ab"))) 
## Method #2 -- Uses readWKT() from the rgeos package. Easier to read. 
# library(rgeos) 
# string <- paste0("LINESTRING(", paste(a, b, collapse=", "), ")") 
# SL <- readWKT(string) 

## Create a raster object 
m <- 10 
n <- 10 
mat <- matrix(seq_len(m*n), nrow = m, ncol = n) 
r <- raster(mat, xmn = 0, xmx = n, ymn = 0, ymx = m) 

## Find which cells are intersected & get coordinates of their lower-left corners 
ii <- extract(r, SL, cellnumbers=TRUE)[[1]][, "cell"] 
floor(xyFromCell(r, ii)) 
#  x y 
# [1,] 2 4 
# [2,] 3 4 
# [3,] 2 3 

## Confirm that this is correct with a plot 
image(r) 
plot(as(rasterize(SL, r), "SpatialPolygons"), 
    border = "darkgrey", lwd = 2, add = TRUE) 
lines(SL) 

enter image description here

+0

Dzięki Josh działa dobrze! –

+0

Miło, nie wiedziałem, że ekstrakt może to zrobić, wybiera wszystkie komórki pod liniami i wydaje się również obsługiwać linie o zerowej długości. – mdsumner

+0

@mdsumner - Dobrze o tym wiedzieć, ale nie jestem zaskoczony: ** raster ** to fenomenalnie dobrze skonstruowany pakiet, ennit? –

0

Proponuję jakiś wariant Bresenham's line algorithm (lub powiązany z nim Wu's algorithm). Kody te są szeroko stosowane w grafice komputerowej do rysowania linii i powinny być dostosowane do twoich potrzeb (takich jak niecałkowite punkty końcowe).

+0

Algorytm Bresenhama nie znajduje wszystkich komórek przekraczających segment. – lhf

+0

Cześć, dziękuję jednak, o ile mogę powiedzieć, że Bresenham nie otrzymuje wszystkich komórek, przez które przechodzi linia, a Wu ma więcej komórek niż te bezpośrednio przez niego przechodzące. –

+0

Myślę, że łatwo jest zmodyfikować jedną lub obie z nich do pracy. Na przykład w Brasenham's możesz zaznaczyć oba piksele za każdym razem, gdy zwiększasz y (chyba że linia przechodzi dokładnie przez róg między czterema komórkami). Spróbuję opracować implementację w Pythonie. – Blckknght

Powiązane problemy