pointsinside {nat} | R Documentation |
Find which points of an object are inside a surface
Description
Find which points of an object are inside a surface
Usage
pointsinside(x, surf, ...)
## Default S3 method:
pointsinside(x, surf, ..., rval = c("logical", "distance", "mesh3d"))
Arguments
x |
an object with 3D points. |
surf |
The reference surface - either a |
... |
additional arguments for methods, eventually passed to as.mesh3d. |
rval |
what to return. |
Details
Note that hxsurf
surface objects will be converted to
mesh3d
before being passed to Rvcg::vcgClostKD
, so if you are
testing repeatedly against the same surface, it may make sense to
pre-convert.
pointsinside
depends on the face normals for each face pointing out
of the object (see example). The face normals are defined by the order of
the three vertices making up a triangular face. You can flip the face
normal for a face by permuting the vertices (i.e. 1,2,3 -> 1,3,2). If you
find for a given surface that points are outside when you expect them to be
inside then the face normals are probably all the wrong way round. You can
invert them yourself or use the Morpho::invertFaces
function to fix
this.
If you find that some points but not all points are not behaving as you
would expect, then it may be that some faces are not coherently oriented.
The Rvcg::vcgClean
function can sometimes be used to
correct the orientation of the faces. Fixing more problematic cases may be
possible by generating a new surface using
alphashape3d::ashape3d
(see examples).
Value
A vector of logical values or distances (positive inside, negative
outside) equal to the number of points in x or the mesh3d
object
returned by Rvcg::vcgClostKD
.
Examples
# check if the vertices in these neurons are inside the mushroom body calyx
# surface object
inout=pointsinside(kcs20, surf=subset(MBL.surf, "MB_CA_L"))
table(inout)
# be a bit more lenient and include points less than 5 microns from surface
MBCAL=subset(MBL.surf, "MB_CA_L")
inout5=pointsinside(kcs20, surf=MBCAL, rval='distance') > -5
table(inout5)
# show which points are in or out
# Hmm seems like there are a few red points in the vertical lobe
# that are well outside the calyx
points3d(xyzmatrix(kcs20), col=ifelse(inout5, 'red', 'black'))
plot3d(MBL.surf, alpha=.3)
# Let's try to make an alphashape for the mesh to clean it up
library(alphashape3d)
MBCAL.as=ashape3d(xyzmatrix(MBCAL), alpha = 10)
# Plotting the points, we can see that is much better behaved
points3d(xyzmatrix(kcs20),
col=ifelse(pointsinside(kcs20, MBCAL.as), 'red', 'black'))
## Not run:
# Show the face normals for a surface
if(require('Morpho')) {
# convert to a mesh3d object used by rgl and Morpho packge
MBCAL.mesh=as.mesh3d(subset(MBL.surf, "MB_CA_L"))
fn=facenormals(MBCAL.mesh)
wire3d(MBCAL.mesh)
# show that the normals point out of the object
plotNormals(fn, long=5, col='red')
# invert the faces of the mesh and show that normals point in
MBCAL.inv=invertFaces(MBCAL.mesh)
plotNormals(facenormals(MBCAL.inv), long=5, col='cyan')
}
## End(Not run)