I'm using X=rpoisline(4)
to generate lines and plot them with plot(X)
.
With X$ends
I have their coordinates and their intersection points with selfcrossing.psp(X)
(In R with spatstat : library(spatstat)
).
I need to get a list of segments and their coordinates and be able to manipulate them (change their orientation, position, intersection...). Those segments have to be defined by the intersection of a line with an other line and with the window.
So, am I missing a simple way to convert a psp of few intersecting lines in a psp of non intersecting segments (I hope it's clear) ?
If you have a non-simple way, I'm interested to !
Thanks for your time !
edit :
Here are the lines I have :
And here are the kind of random stuff I think I can produce if I manage to handle each segments (one by one). So I need to get a list of segments from my list of random lines.
The spatstat
function selfcut.psp
is designed for exactly this purpose.
Y <- selfcut.psp(X)
For further information about manipulating line segment patterns, see section 4.4 in the spatstat book.
Ok, several coffeebreaks later, here's some buggy code that does what you want. The cleanup I'll leave to you.
ranpoly <- function(numsegs=10,plotit=TRUE) {
require(spatstat)
# temp fix: put the first seg into segset. Later make it a constrained random.
segset<-psp(c(0,1,1,0,.25),c(0,0,1,1,0),c(1,1,0,0,1),c(0,1,1,0,.75),owin(c(0,1),c(0,1)) ) #frame the frame
for (jj in 1: numsegs) {
# randomly select a segment to start from, a point on the seg, the slope,and direction
# later... watch for slopes that immediately exit the frame
endx <-sample(c(-0.2,1.2),1) #force 'x1' outside the frame
# watch that sample() gotcha
if(segset$n<=5) sampset <- c(5,5) else sampset<-5:segset$n
startseg<-sample(sampset,1) #don't select a frame segment
# this is slope of segment to be constructed
slope <- tan(runif(1)*2*pi-pi) # range +/- Inf
# get length of selected segment
seglen<-lengths.psp(segset)[startseg]
startcut <- runif(1)
# grab the coords of starting point (similar triangles)
startx<- segset$ends$x0[startseg] + (segset$ends$x1[startseg]-segset$ends$x0[startseg])*startcut #seglen
starty<- segset$ends$y0[startseg] + (segset$ends$y1[startseg]-segset$ends$y0[startseg])*startcut #seglen
# make a psp object with that startpoint and slope; will adjust it after finding intersections
endy <- starty + slope*(endx-startx)
newpsp<-psp(startx,starty,endx,endy,segset$window,check=FALSE)
# don't calc crossing for current element of segset
hits <- crossing.psp(segset[-startseg],newpsp)
segdist <- dist(cbind(c(startx,hits$x),c(starty,hits$y)))
# dig back to get the crosspoint desired -- have to get matrixlike object out of class "dist" object
# And, as.matrix puts a zero in location 1,1 kill that row.
cutx <- hits$x[ which.min( as.matrix(segdist)[-1,1] )]
cuty <- hits$y[which.min(as.matrix(segdist)[-1,1] )]
segset <- superimpose(segset,psp(startx,starty,cutx,cuty,segset$window))
} #end jj loop
if(plotit) plot(segset,col=rainbow(numsegs))
return(invisible(segset))
}