Mapping a point cloud onto a 3D "fabric" then flattening.
So I have a scientific dataset consisting of a point cloud in 3D, this point cloud comprises points on a surface that is curved. In order to perform quantitative analysis I however need to map these point clouds onto a surface I can then flatten. I thought about using mapping tools sort of like in the case of the 3d world being flattened onto a map, but not sure how to even begin as I have no experience in cartography and maybe I'm trying to solve an easy problem with the wrong tools.
Just to briefly describe the dataset: imagine entirely transparent curtains on the window with small dots on them, if I could use that dot pattern to fit the material the dots are on I could then "straighten" it and do meaningful analysis on the spread of the dots. I'm guessing the procedure would be to first manually fit the "sheet" onto the point cloud data by using contours or something along those lines then flattening the sheet thus putting the points into a 2d array. Ultimately I'll probably also reduce that into a 1D but I assume I need the intermediate 2D step as the length of the 2nd dimension is variable (i.e. one end of the sheet is shorter than the other but still corresponds to the same position in terms of contours) I'm using Matlab and Amira though I'm always happy to learn new tools!
Any advice or hints how to approach are much appreciated!
You can use a space filling curve to reduce the 3d complexity to a 1d complexity. I use a hilbert curve to index lat-lng pairs on a 2d map. You can do the same with a 3d space but it's easier to start with a simple curve for example a z morton order curve. Space filling curves are often used in mapping applications. A space filling curve also adds some proximity information and a new sort order to the 3d points.
You can try to build a surface that approximates your dataset, then unfold the surface with the points you want. Solid3dtech.com has the tool to unfold the surfaces with the curves or points.
Related
I'm neither a geometry student or a native speaker, so apologies if my question isn't clear enough.
As part of my master's thesis, I have to plot bounded regions of the night sky onto a 2D plane. My current solution consists of a rectangular mapping where (ra, dec) values are plotted to (x,y) coordinates. While this approach works well enough for small regions in relatively low ascension values, the resulting plots get progressively distorted for higher ||dec|| values, as expected.
At some point I'll have to change this to a more versatile approach. Thing is, I'm not exactly clear on what to search for. I guess I have to be able to map angular coordinates to a square (or hexagon) subgrid, but most search results I get are concerned with full-surface mapping.
I know I won't be able to achieve a perfect, distortion-free plotting, but I don't require perfect solutions; only a more general projection that will work well near the poles. Something like this, where I put my Photoshop skills to work and try to simulate a 20ยบ region under my current approach and the one I'm looking for:
What I want:
What I have:
TL;DR: how do I convert between coordinates on a sphere (ra/dec) to cartesian coordinates on a locally-defined grid?
I'm writing a data analysis program and part of it requires finding the volume of a shape. The shape information comes in the form of a lost of points, giving the radius and the angular coordinates of the point.
If the data points were uniformly distributed in coordinate space I would be able to perform the integral, but unfortunately the data points are basically randomly distributed.
My inefficient approach would be to find the nearest neighbours to each point and stitch the shape together like that, finding the volume of the stitched together parts.
Does anyone have a better approach to take?
Thanks.
IF those are surface points, one good way to do it would be to discretize the surface as triangles and convert the volume integral to a surface integral using Green's Theorem. Then you can use simple Gauss quadrature over the triangles.
Ok, here it is, along duffymo's lines I think.
First, triangulate the surface, and make sure you have consistent orientation of the triangles. Meaning that orientation of neighbouring triangle is such that the common edge is traversed in opposite directions.
Second, for each triangle ABC compute this expression: H*cross2D(B-A,C-A), where cross2D computes cross product using coordinates X and Y only, ignoring the Z coordinates, and H is the Z-coordinate of any convenient point in the triangle (although the barycentre would improve precision).
Third, sum up all the above expressions. The result would be the signed volume inside the surface (plus or minus depending on the choice of orientation).
Sounds like you want the convex hull of a point cloud. Fortunately, there are efficient ways of getting you there. Check out scipy.spatial.ConvexHull.
I've got data representing 3D surfaces (i.e. earthquake fault planes) in xyz point format. I'd like to create a 3D representation of these surfaces. I've had some success using rgl and akima, however it can't really handle geometry that may fold back on itself or have multiple z values at the same x,y point. Alternatively, using geometry (the convhulln function from qhull) I can create convex hulls that show up nicely in rgl but these are closed surfaces where in reality, the objects are open (don't completely enclose the point set). Is there a way to create these surfaces and render them, preferably in rgl?
EDIT
To clarify, the points are in a point cloud that defines the surface. They have varying density of coverage across the surface. However, the main issue is that the surface is one-sided, not closed, and I don't know how to generate a mesh/surface that isn't closed for more complex geometry.
As an example...
require(rgl)
require(akima)
faultdata<-cbind(c(1,1,1,2,2,2),c(1,1,1,2,2,2),c(10,20,-10,10,20,-10))
x <- faultdata[,1]
y <- faultdata[,2]
z <- faultdata[,3]
s <- interp(x,z,y,duplicate="strip")
surface3d(s$x,s$y,s$z,col=a,add=T)
This creates generally what I want. However, for planes that are more complex this doesn't necessarily work. e.g. where the data are:
faultdata<-cbind(c(2,2,2,2,2,2),c(1,1,1,2,2,2),c(10,20,-10,10,20,-10))
I can't use this approach because the points are all vertically co-planar. I also can't use convhulln because of the same issue and in general I don't want a closed hull, I want a surface. I looked at alphashape3d and it looks promising, but I'm not sure how to go about using it for this problem.
How do you determine how the points are connected together as a surface? By distance? That can be one way, and the alphashape3d package might be of use. Otherwise, if you know exactly how they are to be connected, then you can visualize it directly with rgl structures.
I have a set of points like this (that I have clustered using R):
180.06576696, 192.64378568
180.11529253999998, 192.62311824
180.12106092, 191.78020965999997
180.15299478, 192.56909828000002
180.2260287, 192.55455869999997
These points are dispersed around a center point or centroid.
The problem is that the points are very close together and are, thus, difficult to see.
So, how do I move the points apart so that I can distinguish each point more clearly?
Thanks,
s
Maybe I'm overlooking some intricacy here, but...multiply by 10?
EDIT
Assuming the data you listed above are Cartesian (x,y) coordinate pairs, you can visualize them as a scatter plot using Google Charts. I've rounded your data to 3 decimal places, because Google Charts doesn't appear to handle higher precision than that.
I don't know the coordinates for your central point. In the above chart, I'm assuming it is somewhere nearby and not at (0,0). If it is at (0,0), then I imagine it will be difficult to visualize all of the data at once without some kind of "zoom-in" feature, scaling the data, or a very large screen.
slotishtype, without going into code, I think you first need to add in the following tweaking parameters to be used by the visualization code.
Given an x by y display box, fill the entire box, with input parameters [0.0 to 1.0]...
overlap: the allowance for points to be placed on top of each other
completeness: how important is it to display all of your data points
centroid_display: how important is it to see the centroid in the same output
These produce the dependent parameter
scale: the ratio between display distances to numerical distances
You will need code to
calculate the distance(s) to the centroid like you said,
and also the distances between data points, affecting the output based on the chosen input parameters.
I take inspiration from the fundamentals in the GraphViz dot manual. Look at the "Drawing Orientation, Size and Spacing" on p12.
I need to convert arbitrary triangulated 3D mesh to cloud of particles that are uniformly spaced.
First thought was to try find a way to fill one 3D triangle. And then fill each triangle of mesh, removing duplicated particles on edges, but that's just hard and too much work. I was hoping for some more-math way.
Can anyone point me to an algorithm which can help me do my task correctly... well, at least approximatively?
Thanks
There are two main options:
Voxelization of mesh. Easy to implement the conversion of mesh to voxels, but it's inaccurate since uniform spacing cannot be achieved: distance between cubes can be x, x*sqrt(2) or x*sqrt(3) depending if neighbor cubes are in same plane and adjacent.
Poisson disk sampling on surface. Hard to implement and lack of research material and code, but mathematically very correct. Some links:
http://research.microsoft.com/apps/pubs/default.aspx?id=135760
http://web.mysites.ntu.edu.sg/cwfu/public/Shared%20Documents/dualtiling/index.html
You could convert the TIN to raster using a GIS package or software such as R, then retrieve one point at the center of each pixel representing the value. (Example in ArcGIS)
EDIT: If the irregular 3D mesh has multiple heights per {x, y} a similar approach would be to sample the mesh using a voxel "grid" and keep one value per voxel. GRASS GIS has the functionality to take the vertices of the TIN (3d mesh) and convert them to voxels, then back to a regular 3d cloud.