R generate points with condition using runifpoint function - r

I am trying to generate randomly distributed points in a rectangle.
To create 50 random points in a rectangle, I used
i=50
pp<-runifpoint(i, win=owin(c(0,19.5),c(0,3.12))
If I were to add conditions on the coordinates before randomly generating points,
e.g. 0.24 <x<19.26 ,0.24<y<2.64 ,
then generate random points, what code can I imply?
The ultimate goal is to generate points in the rectangle except for the grey shaded area, in the below image

This is a question about the R package spatstat.
The argument win specifies the spatial region in which the points will be generated. In your example you have specified this region to be a rectangle. You just need to replace this rectangle by the region in which you want the points to be generated.
You can construct spatial regions (objects of class owin) in many ways. See help(owin), or help(spatstat) for an overview.
In your example, you could build up the shape by forming the union of several rectangles. For example to make a simple cross shape, I could just write
require(spatstat)
A <- owin(c(-1,1), c(-4, 4))
B <- owin(c(-4,4), c(-1,1))
U <- union.owin(A, B)
plot(U)
Another way would be to specify the corners of the polygon shape and use W <- owin(poly=p) where p = list(x, y) contains the coordinates of the corners, listed in anticlockwise order without repetition. See help(owin).
This is also covered in Section 3.5 of the spatstat book. You can download Chapter 3 for free.

Related

Calculate area on 3D surface mesh encolosed by four arbitrary points from coordinate data

I have human facial data as below:
library(Rvcg)
library(rgl)
data(humface)
lm <- matrix(c(1.0456182e+001, -3.5877686e+001, 5.0972912e+001, 2.2514189e+001,
8.4171227e+001, 6.6850304e+001, 8.3239525e+001, 9.8277359e+000,
6.5489395e+001, 4.2590347e+001, 4.0016006e+001, 5.9176712e+001),
4)
shade3d(humface, col="#add9ec", specular = "#202020", alpha = 0.8)
plot3d(lm, type = "s", col = "red", xlab = "x", ylab = "y", zlab = "z",
size = 1, aspect = FALSE,add=T)
for lm, four landmarks are placed on the surface of the mesh, in the following oder:
The yellow lines are drawn by hand for illustration purpose. I wish to calculate the surface area of the quarilateral enclosed by the four red dots, i.e., the surface area inside the yellow edges.
If surface area cannot be calculated, I also welcome methods to calculate the area (not area of the surface of the face) of the quadrilateral. I know one could calculate the sum of areas of triangle 123 and triangle 234. However, I my real application, I have no idea of the ordering and relative spatial position of the four points. Since I have thousands of qudrilateral areas to calculate, it is impossible to plot each quadrilateral and determine how to decompose the quadrilateral into two triangles. For example, I may accidentally pick triangle 123 and triangle 124, and the sum of these two triangle ares is not what I want.
Therefore, I am interested in either surface area or area of the quadrilateral. Solution to either is welcome. I just do not want to plot each quadrilateral and I want an area value directly computed from the coordinates.
The rgl::shadow3d function can compute a projection of the quad onto the face. Then you'd compute the area by summing the areas of triangles and quads in the result. #DiegoQueiroz gives you some pointers for doing that,
plus the Rvcg package contains vcgArea:
quad <- mesh3d(lm, triangles = cbind(c(1,2,4), c(1,4,3)))
projection <- shadow3d(humface, quad, plot = FALSE)
Here's what that looks like:
shade3d(projection, col = "yellow", polygon_offset = -1)
The projection ends up containing 3604 triangles; the area is
vcgArea(projection)
# [1] 5141.33
There are a few ambiguities in the problem: the quadrilateral isn't planar, so you'd get a different one if you split it into triangles along the other diagonal. And the projection of the quad onto the face is different depending on which direction you choose. I used the default of projecting along the z axis, but in fact the face isn't perfectly aligned that way.
EDITED TO ADD:
If you don't know how to decompose the 4 points into a single quadrilateral, then project all 4 triangles (which form a tetrahedron in 3-space):
triangles <- mesh3d(lm, triangles = cbind(c(1,2,3), c(1,2,4), c(1,3,4), c(2,3,4))
projection <- shadow3d(humface, triangles, plot = FALSE)
This gives a slightly different region than projecting the quad:
vcgArea(projection)
# [1] 5217.224
I think the reason for this is related to what I referred to in the comment above: the area depends on the "thickness" of the object being projected, since the quad is not planar.
I believe your question is more appropriate for math.stackexchange.com because I think it's more a question about the math behind the code than the code itself.
If you are concerned about precision, you may want to use techniques for smoothing the calculated area of a mesh, like the one presented in this paper.
However, if you don't really need that area to really model the surface, then you can ignore the face and compute the convex quadrilateral area using the many available formulas for that, however, the simplest one requires you to have the vectors that correspond to the quadrilateral's diagonals (which you can find by checking this question)
If you decide to find the diagonals and use the simplest vectorial formula (half the magnitude of the cross-product between the diagonals), you should use the cross() and Norm() functions from the pracma package as R's crossprod() computes a different type of cross product than the one you will need.

how to set the ranges of coordinates X & Y for observation window geometry in spatstat package in R

Hi? I have a data of seedlings distribution which contains species types, X and Y coordinates in UTM. I want to create a point pattern by their X & Y coordinate location with the help of ppp() function in spatstat package. I tried it with following 2 ways:
p.patt <- ppp(mydata$X, mydata$Y)
p.patt <- ppp(mydata$X, mydata$Y, owin(c(100,131), c(100,130)))
But there is a “Warning message: 435 points were rejected as lying outside the specified window” for both of them.
I guess this is related to ranges of X and Y coordinates that should be specified in this code in c(…), c(…). I checked the range of X &Y and R gave me following ranges:
for X: 368615 and 368746,
for Y: 4587355 and 4587485
When I plot the data, a shape of the plot looks like "tilted rombo". I don't know if it is help.
Here I have just randomly chosen tried some numbers: 100 & 131 & 130. I couldn’t find any information how to set them online.
So my question is how I can use these ranges of coordinates to set observation window geometry of point patterm in spatstat package in R?.
Thank you very much in advance!
The numbers in the owin call are not the width and height of the window; they are the X and Y coordinates of the corners of the window.
Since the range of X coordinate values of the data points is from 368615 to 368746, the window needs to contain this range, at least. Similarly the range of Y values must be contained in the window. The minimal window that will not give a warning is
p.patt <- ppp(mydata$X, mydata$Y, owin(c(368615,368746), c(4587355,4587485)))
or equivalently
p.patt <- ppp(mydata$X, mydata$Y, c(368615,368746), c(4587355,4587485))
But this is just the minimal window that is acceptable; for a proper analysis, you need information about the survey region. If it is not a rectangle then, as Ege says, you need to specify owin(poly=...) using the coordinate locations of the vertices of the polygon.
Don't you have information about the plot? E.g. the coordinates of the corners of a polygonal region delimiting the plot? If you have these coordinates use them as input in the argument poly of owin. See the help file for owin for details. In lack of any information you can try ripras to estimate the boundary of the plot.
What you do right now is to say that you define a point pattern in the rectangle [0,131]×[0,130] and then you provide a bunch of points with coordinates outside this area (much larger coordinate values) and they are all discarded.

R: Is it possible to plot a grid from x, y spatial coordinates?

I've been working with a spatial model which contains 21,000 grid cells of unequal size (i by j, where i is [1:175] and j is[1:120]). I have the latitude and longitude values in two seperate arrays (lat_array,lon_array) of i and j dimensions.
Plotting the coordinates:
> plot(lon_array, lat_array, main='Grid Coordinates')
Result:
My question: Is it possible to plot these spatial coordinates as a grid rather than as points? Does anyone know of a package or function that might be able to do this? I haven't been able to find anything online to this nature.
Thanks.
First of all it is always a bit dangerous to plot inherently spherical coordinates (lat,long) directly in the plane. Usually you should project them in some way, but I will leave it for you to explore the sp package and the function spTransform or something like that.
I guess in principle you could simply use the deldir package to calculate the Dirichlet tessellation of you points which would give you a nice grid. However, you need a bounding region for this to avoid large cells radiating out from the border of your region. I personally use spatstat to call deldir so I can't give you the direct commands in deldir, but in spatstat I would do something like:
library(spatstat)
plot(lon_array, lat_array, main='Grid Coordinates')
W <- clickpoly(add = TRUE) # Now click the region that contains your grid
i_na <- is.na(lon_array) | is.na(lat_array) # Index of NAs
X <- ppp(lon_array[!i_na], lat_array[!i_na], window = W)
grid <- dirichlet(X)
plot(grid)
I have not tested this yet and I will update this answer once I get the chance to test it with some artificial data. A major problem is the size of your dataset which may take a long time to calculate the Dirichlet tessellation of. I have only tried to call dirichlet on dataset of size up to 3000 points...

How to create a legend for edge colors when plotting networks in R?

I have generated a connectivity matrix representing a network of geographical points connected by ocean currents. Each point releases particles that are received by the others. The number of particles released and received by each point is summarized in this square matrix. For example an element Aij of the matrix correspond to the amount of particles emitted by the ith point and received by the jth.
My purpose is to be able to plot this as a network such that each point constitutes a vertex and the connections between two points constitute an edge. I would like those edges to be of different colors according to the amount of particles exchanged. Those have to be marked by an arrow.
I could plot those points according to their geographic coordinates and I could plot those edges the way I wanted. My only concern is now how to add a legend relating the color of the edges with the amount of particles they represent.
Can anyone help me with that? Here is my code so far:
library(ggplot2)
library(plyr)
library(sp)
library(statnet)
connectivityMatrix <- as.matrix(read.table(file='settlementMatrix001920.dat'))
coordinates <- as.matrix(read.table(file='NoTakeReefs_center_LonLat.dat'))
net <- as.network(connectivityMatrix, matrix.type = "adjacency", directed = TRUE)
minX<-min(coordinates[,1])#-0.5
maxX<-max(coordinates[,1])#+0.5
minY<-min(coordinates[,2])#-0.5
maxY<-max(coordinates[,2])#+0.5
p<-plot(net, coord=coordinates,xlim=c(minX,maxX),ylim=c(minY,maxY),edge.col=connectivityMatrix,object.scale=0.01)
without having your real data, here as a sample example
matrixValues<-matrix(c(0,1,2,3,
0,0,0,0,
0,0,0,0,
0,0,0,0),ncol=4)
net<-as.network(matrixValues)
plot(net,edge.col=matrixValues)
# plot legend using non-zero values from matrix
legend(1,1,fill = unique(as.vector(matrixValues[matrixValues>0])),
legend=unique(as.vector(matrixValues[matrixValues>0])))
you may have to adjust the first two coordinate values in legend to draw it where you need on the plot. You could also construct your network slightly differently so that the values were loaded in from the matrix (see the ignore.eval argument to as.network(). In which case you would use edge.col='myValueName' for the plot command and get.edge.attribute(net,'myValueName') to feed the values into legend.

Plotting lines between two points in 3D

I am writing an regression algorithm which tries to "capture" points inside boxes. The algorithm tries to keep the boxes as small as possible, so usually the edges/corners of the boxes go through points, which determines the size of the box.
Problem: I need graphical output of the boxes in R. In 2D it is easy to draw boxes with segments(), which draws a line between two points. So, with 4 segments I can draw a box:
plot(x,y,type="p")
segments(x1,y1,x2,y2)
I then tried both the scatterplot3d and plot3d package for 3D plotting. In 3D the segments() command is not working, as there is no additional z-component. I was surprised that apparently (to me) there is no adequate replacement in 3D for segments()
Is there an easy way to draw boxes / lines between two points when plotting in three dimensions ?
The scatterplot3d function returns information that will allow you to project (x,y,z) points into the relevant plane, as follows:
library(scatterplot3d)
x <- c(1,4,3,6,2,5)
y <- c(2,2,4,3,5,9)
z <- c(1,3,5,9,2,2)
s <- scatterplot3d(x,y,z)
## now draw a line between points 2 and 3
p2 <- s$xyz.convert(x[2],y[2],z[2])
p3 <- s$xyz.convert(x[3],y[3],z[3])
segments(p2$x,p2$y,p3$x,p3$y,lwd=2,col=2)
The rgl package is another way to go, and perhaps even easier (note that segments3d takes points in pairs from a vector)
plot3d(x,y,z)
segments3d(x[2:3],y[2:3],z[2:3],col=2,lwd=2)

Resources