How to generate a list of segments from a list of random self-intercepting lines (psp in R)?

StackOverflow https://stackoverflow.com/questions/14362127

  •  16-01-2022
  •  | 
  •  

Question

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 :

here is what 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.

and here is what I need

Was it helpful?

Solution 2

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.

OTHER TIPS

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))
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top