0

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

  • Can you provide an example, i.e. some commands that generate the output you have? That would give people something to experiment with and thus increase chances of a useful answer. – MvG Jan 16 '13 at 16:45
  • So is the problem that you have a bunch of ordered pairs representing intersection points, but these data are not mapped (e.g. by their position in an array of data) to the data defining the lines which are involved in said intersections? – Carl Witthoft Jan 16 '13 at 18:08
  • Here is what I type to R library(spatstat) lignes=rpoisline(4) plot(lignes) lignes$ends interP=selfcrossing.psp(lignes) plot(interP,add=T,col="red") @CarlWitthoft : that's my problem ! – Yollanda Beetroot Jan 17 '13 at 08:43
  • Sorry I didn't manage to format that comment ... – Yollanda Beetroot Jan 17 '13 at 09:12
  • Please post the plot you're producing AND a sketch of the plot you would like to produce. I fear the language barrier is confusing the issue. – Carl Witthoft Jan 17 '13 at 12:25
  • Looking at your second pic, I think you should NOT start with the first picture (or the lines behind it). Looks more like: draw any one line, then pick a random point either on your picture boundary(frame) or on the line, and draw a random segment from that point until you intersect an existing line or boundary. Repeat as often as desired. – Carl Witthoft Jan 17 '13 at 15:35

2 Answers2

2

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))
}
Carl Witthoft
  • 20,573
  • 9
  • 43
  • 73
  • This is awesome ! I'll try to deal with it for my subject and I'll may come back to you with problems !^^ Thank you very much for your time ! – Yollanda Beetroot Jan 24 '13 at 08:06
1

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.

Adrian Baddeley
  • 1,956
  • 1
  • 8
  • 7
  • Oh, great -- provide a nice clean easy solution 3 yrs later and steal my points. :-) . No, seriously, I'm happy that you posted this vs. my kludge code. – Carl Witthoft Jun 27 '16 at 19:54