2013-04-13 5 views
6

Obiettivo: Dato due punti, trovare le coordinate dell'arco che li collega e tracciarlo. Implementazione: Una funzione per trovare i punti dell'arco (circleFun) e un'altra per tracciarla (plottest). I colori mostrano la direzione del percorso, dal rosso al verde.Perché la funzione linee chiude il percorso in R?

circleFun <- function(x,y) 
{ 
    center <- c((x[1]+y[1])/2,(x[2]+y[2])/2) 
    diameter <- as.numeric(dist(rbind(x,y))) 

    r <- diameter/2 
    tt <- seq(0,2*pi,length.out=1000) 
    xx <- center[1] + r * cos(tt) 
    yy <- center[2] + r * sin(tt) 
    res <- data.frame(x = xx, y = yy) 

    if((x[1]<y[1] & x[2]>y[2]) | (x[1]>y[1] & x[2]<y[2])){ 
    res <- res[which(res$x>min(c(x[1],y[1])) & res$y>min(c(x[2],y[2]))),] 
    } else { 
    res <- res[which(res$x<max(c(x[1],y[1])) & res$y>min(c(x[2],y[2]))),] 
    } 
    return(res) 
} 

plottest <- function(x1,y1) 
{ 
    plot(c(x1[1],y1[1]),c(x1[2],y1[2]), 
     xlim=c(-2,2),ylim=c(-2,2),col=2:3,pch=20,cex=2,asp=1) 
    lines(circleFun(x1,y1)) 
} 

par(mfrow=c(2,2)) 
plottest(c(1,-1),c(-1, 1)) 
plottest(c(-1, 1),c(1,-1)) 
plottest(c(-1,-1),c(1, 1)) 
plottest(c(1, 1),c(-1,-1)) 

risultati:

enter image description here

Domanda: non riesco a capire perché lines funzione chiude il percorso nelle figure [1,1] e [1,2] mentre non per Figure [2,1] e [2,2]. Il risultato atteso dovrebbe essere tutte le cifre come quelle della seconda fila.

Grazie!

risposta

6

Come gli altri dicevano. Detto questo, ecco una versione molto più semplice della tua funzione, con l'output atteso.

circleFun <- function(x, y) { 

    center <- (x + y)/2 
    radius <- sqrt(sum((x - y)^2))/2 
    angle <- atan2((y - x)[2], (y - x)[1]) 
    direc <- ifelse(abs(angle) > pi/2, -1, 1) 
    tt <- seq(0, direc * pi, length.out = 1000) 

    return(data.frame(x = center[1] + radius * cos(angle + tt), 
        y = center[2] + radius * sin(angle + tt))) 
} 

dove la variabile direc è quello che decide se disegnare i in senso orario semi-cerchio o in senso antiorario.

open semi-circles

+1

+1: Questa funzione ha anche il vantaggio che trame da un punto di ingresso all'altro. Se riduci il numero di punti nel cerchio a (diciamo) 10, puoi vedere che la funzione dell'OP non includeva nessuno dei punti finali nella trama, mentre questa lo fa. – Simon

+1

codice stupendo, molto elegante – Emer

3

posso rispondere alla tua domanda sulla funzione lines, ma lascio a voi per capire come risolvere il vostro circleFun per produrre il comportamento previsto:

lines() collega punti nell'ordine in cui appaiono nel i dati. Inoltre, il percorso viene chiuso solo quando il primo punto viene nuovamente incluso alla fine dei dati. La seguente figura illustra questo comportamento.

par(mfrow=c(1, 2)) 

plot(x=c(-1, 0, 1), y=c(-1, 1, -1), xlim=c(-2, 2), ylim=c(-2, 2), 
    type="l", asp=1) 
points(x=c(-1, 1), y=c(-1, -1)) 

plot(x=c(-1, 0, 1, -1), y=c(-1, 1, -1, -1), xlim=c(-2, 2), ylim=c(-2, 2), 
    type="l", asp=1) 
points(x=c(-1, 1), y=c(-1, -1)) 

enter image description here