Hi everyone, I wanted to generate random lines between two spatial points (random points in polygons). The lines should consist of segments (9 segments), after following suggestions I received to my previous post, I ended up using trajectories. My aim now is to restrict these random trajectories (see points in the attachment as an example) to the extent of a polygon (shown in the attachment in yellow). So the trajectories should lie within the polygon. Please find the code I used below: I first generated a data frame with my start and end point and used it to generate a trajectory (straight line in attachment). I then generated a random trajectory and shifted it so that the start and endpoints were equal to my first trajectory. I transformed the matrices to a Spatial Data frame to be able to plot it. Does anyone know how I can restrict the extent of the trajectory that I randomly generate?
#coordinates of start and end point and time steps x<-c(1649786,-1636500) y<-c(-2902593,738500) times<-c(0,9) start_end_points<-as.data.frame(cbind(x,y,times)) # generate a trajectory between start and endpoint trj<-TrajFromCoords(point_trj,xCol=1,yCol=2,timeCol=3, spatialUnits="m", timeUnits="d") # generate a random trajectory with 9 segments track<-TrajGenerate(n=9, random=T, stepLength=TrajLength(trj)/9) # To be able to use StartEndTranslate transform trajectories into matrices ma1<-as.matrix(trj) ma2<-as.matrix(track) # Translate, rotate and scale the points of traj2 using traj1. The new traj will have the same start and end points as traj1. p<-StartEndTranslate(ma1,ma2) # to check if this worked transform into SpatialDataFrame # the start and end point of the new matrix are the same as the traj1 which is good, the rest of the points changed as well p_df<-as.data.frame(p) # change lat / longs to nummeric p_df$x<-as.numeric(p_df$x) p_df$y<-as.numeric(p_df$y) # generate a spatial dataframe to check if the StartEndTranslate function worked by plotting it xy<-p_df[,c(1,2)] spdf<-SpatialPointsDataFrame(coords=xy, data=p_df, proj4string = CRS(projection)) Thank you very much! On Wed, Feb 6, 2019 at 5:42 PM Barry Rowlingson <b.rowling...@gmail.com> wrote: > Had another idea which is now implemented... > > Consider any segmented path of segments of lengths L_i at angles A_i. Its > endpoint will be the vector sum of those segments, ie at (x,y) = (sum(L_i > cos(A_i)), sum(L_i sin(A_i)). > > To create a segmented path to a given (x,y), solve that expression for the > angles A_i. In R you can treat this as an optimisation problem - find a set > of angles A_i that minimise the distance of the end of the segmented path > from the target end point. > > Here's some code that does that for a path from 0,0 to 0,1: > > pathit <- function(segments){ > obj = function(angles){ > dxdy = dxdy(segments, angles) > xerr = dxdy$dx-1 > yerr = dxdy$dy > err = sqrt(xerr^2 + yerr^2) > err > } > angles = runif(length(segments), 0 , 2*pi) > optim(angles, obj) > } > > dxdy = function(segments, angles){ > dx = sum(segments * cos(angles)) > dy = sum(segments * sin(angles)) > list(dx=dx, dy=dy) > } > > plotsegs <- function(segments, angles){ > x = rep(NA, length(segments) +1) > y = x > x[1] = 0 > y[1] = 0 > for(i in 2:(length(segments)+1)){ > x[i] = x[i-1] + segments[i-1]*cos(angles[i-1]) > y[i] = y[i-1] + segments[i-1]*sin(angles[i-1]) > } > cbind(x,y) > } > > This is deliberately written naively for clarity. > > To use, set the segment sizes, optimise, and then plot: > > s1 = c(.1,.3,.2,.1,.3,.3,.1) > a1 = pathit(s1) > plot(plotsegs(s1,a1$par),type="l") > > which should show a path of seven segments from 0,0 to 0,1 - since the > initial starting values are random the model can find different solutions. > Run again for a different path. > > To see what the space of paths looks like, do lots and overplot them: > > lots = lapply(1:1000, function(i)plotsegs(s1,pathit(s1)$par)) > plot(c(-.1,1.1),c(-1,1)) > p = lapply(lots, function(xy){lines(xy)}) > > this should show 1000 paths, and illustrates the "ellipse" of path > possibles that I mentioned in the previous email. > > Sometimes the optimiser struggles to find a solution and so you should > probably test the output from optim for convergence and to make sure the > target function is close enough to zero for your purposes. For the example > above most of the time the end point is about 1e-5 from (1,0) but for > harder problems such as s = rep(.1, 11) which only has 0.1 of extra "slack" > length, the error can be 0.02 and failed convergence. Possibly longer optim > runs would help or constraining the angles. > > Anyway, interesting problem.... > > Barry > > > > > > > > On Wed, Feb 6, 2019 at 8:23 PM Barry Rowlingson <b.rowling...@gmail.com> > wrote: > >> Do you want to generate these for input into some statistical process, or >> to generate some test data that looks a bit like real data? I think >> generating test data isn't too difficult, but anything that you might want >> to put into a statistical test (eg testing some hypothesis about the birds >> maximum deviation from the straight line A-B) needs a lot more care in >> formulating the path generating process. >> >> Here's some thoughts - if you consider one of the red segments in your >> map as a piece of string (rather than 10 segments) anchored at the points, >> then you can stretch it taut with a pencil and draw an ellipse with A and B >> as the foci. Any path created with that string - taut or slack as in your >> map - has to strictly lie within the ellipse. Now you can wiggle that >> string inside that ellipse and create an infinity of paths from A to B of >> the same length. I'm not sure how you can sample uniformly from that >> infinity such that any path has an equal sampling probability. Your problem >> is similar but has the additional rigid segment constraint. >> >> Any two adjacent segments of a chain, eg 1----2-------3, as long as it >> isn't taut (ie straight) can be perturbed by holding 1 and 3 still and >> moving 2 to the "mirror image" point over the straight line from 1 to 3. >> You can also take three segments 1--2--3--4 and hold 1 and 4 still and >> perturb 2 and 3 fairly easily. In this way you could set up an initial >> chain and then run multiple perturbations on the chain to get a "random" >> chain, but quite what set of all chains it would be a sample from is not >> clear. It could at least generate reasonable looking paths, but I wouldn't >> want to test a hypothesis against it. >> >> I'm going to generate a path from my office to my home now. >> >> Barry >> >> >> >> >> >> >> On Wed, Feb 6, 2019 at 7:50 PM Hannah Justen <jus...@tamu.edu> wrote: >> >>> Hello everyone, >>> >>> Thank you very much for the suggestions. >>> >>> Regarding more details (please also see attached figure): >>> I would like to simulate a bird's migration between breeding (starting >>> polygon - blue in the figure) and wintering grounds (end polygon - green in >>> the figure). The lines can start from anywhere within the starting polygon >>> and end anywhere in the end polygon. The lines shall consist of 10 >>> connected segments with variable length between 300 and 1000 km (see red >>> lines in figure; two examples of possible lines with 10 segments between >>> the polygons). >>> >>> Thank you very much for you help, >>> Hannah >>> >>> --- >>> PhD Student |Ecology and Evolutionary Biology >>> Texas A&M University >>> >>> On Wed, Feb 6, 2019 at 5:12 AM Barry Rowlingson < >>> b.rowling...@lancaster.ac.uk> wrote: >>> >>>> Interesting, but I think we need more details... >>>> >>>> Do the lines have to start and finish at specific locations in the >>>> polygons - like the centroid, or anywhere? >>>> >>>> So one line might be 3 segments of 10km each connecting two polygon >>>> centroids that are 15km apart? Imagining three rigid rods of length 10 >>>> connected at their ends and with the first and last also connected to two >>>> fixed points tells me there's an infinite number of possible solutions. >>>> There's probably also a number of ways of sampling from those solutions. >>>> Its going to get very complicated with a larger number of segments. >>>> >>>> Hmmmmm..... >>>> >>>> Barry >>>> >>>> >>>> >>>> >>>> On Tue, Feb 5, 2019 at 11:30 PM Hannah Justen <jus...@tamu.edu> wrote: >>>> >>>>> Hi everyone, >>>>> >>>>> I am studying migratory tracks of birds for my dissertation and I would >>>>> like to model possible pathways between two polygons. Therefore, I >>>>> would >>>>> like to sample random lines between the polygons. These lines can >>>>> differ in >>>>> total length but should consist of x - number of fragments of equal >>>>> length. >>>>> Each fragment can have slightly different orientation but overall the >>>>> lines >>>>> should connect the two polygons. >>>>> >>>>> I fail to find the appropriate R package that will allow me to do this >>>>> type >>>>> of analysis. Does anyone have a suggestion how to approach analysis? >>>>> >>>>> Thank you, >>>>> Hannah >>>>> >>>>> --- >>>>> PhD Student |Ecology and Evolutionary Biology >>>>> Texas A&M University >>>>> >>>>> [[alternative HTML version deleted]] >>>>> >>>>> _______________________________________________ >>>>> R-sig-Geo mailing list >>>>> R-sig-Geo@r-project.org >>>>> https://stat.ethz.ch/mailman/listinfo/r-sig-geo >>>>> <https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Dsig-2Dgeo&d=DwMFaQ&c=ODFT-G5SujMiGrKuoJJjVg&r=JTKhaSJXwF2BxCfjjnt61w&m=RH21jOLOEbLLudn70kOTH0wnklnKHk-tFm9cxjxAB9k&s=H_HhNMga7aaqbnNsWexqY1jdRFFo7zO_m9xvk2awODo&e=> >>>>> >>>>
_______________________________________________ R-sig-Geo mailing list R-sig-Geo@r-project.org https://stat.ethz.ch/mailman/listinfo/r-sig-geo