i am trying to use an octree to find fast intersection between a volume of interest and several curves in 3d space, similar to what you see here at 0:25
https://www.youtube.com/watch?v=tL2AjQ4XEn4&t=119s
basically, i want to be able to quickly detect which curves intersect my volume of interest, which in my case is a sphere. so i want to avoid looping over all the points in each curve, to check the distance from the sphere which takes too long for a real time application.
can anyone give me the basic call structure to an octree that would be used to accomplish this? i know an octree is the correct data structure, i'm just not sure how to use it to accomplish this task.
thanks
Related
I want to construct a 3D cube in MATLAB. I know that the units of any 3D shape are voxels not pixels. Here is what I want to do,
First, I want to construct a cube with some given dimensions x, y, and z.
Second, according to what I understand from different image processing tutorials, this cube must consists of voxels (3D pixels). I want to give every voxel an initial color value, say gray.
Third, I want to access every voxel and change its color, but I want to distinguish the voxels that represent the faces of the cube from those that represent the internal region. I want to axis every voxel by its position x,y, z. At the end, we will end up with a cube that have different colors regions.
I've searched a lot but couldn't find a good way to implement that, but the code given here seems very close in regard to constructing the internal region of the cube,
http://www.mathworks.com/matlabcentral/fileexchange/3280-voxel
But it's not clear to me how it performs the process.
Can anyone tell me how to build such a cube in MATLAB?
Thanks.
You want to plot voxels! Good! Lets see how we can do this stuff.
First of all: yeah, the unit of 3D shapes may be voxels, but they don't need to be. You can plot an sphere in 3D without it being "blocky", thus you dont need to describe it in term of voxels, the same way you don't need to describe a sinusoidal wave in term of pixels to be able to plot it on screen. Look at the figure below. (same happens for cubes)
If you are interested in drawing voxels, I generally would recommend you to use vol3D v2 from Matlab's FEX. Why that instead of your own?
Because the best (only?) way of plotting voxels is actually plotting flat square surfaces, 6 for each cube (see answer here for function that does that). This flat surfaces will also create some artifacts for something called z-fighting in computer graphics. vol3D actually only plots 3 surfaces, the ones looking at you, saving half of the computational time, and avoiding ugly plotting artifacts. It is easy to use, you can define colors per voxel and also the alpha (transparency) of each of them, allowing you to see inside.
Example of use:
% numbers are arbitrary
cube=zeros(11,11,11);
cube(3:9,3:9,3:9)=5; % Create a cube inside the region
% Boring: faces of the cube are a different color.
cube(3:9,3:9,3)=2;
cube(3:9,3:9,9)=2;
cube(3:9,3,3:9)=2;
cube(3:9,9,3:9)=2;
cube(3,3:9,3:9)=2;
cube(9,3:9,3:9)=2;
vold3d('Cdata',cube,'alpha',cube/5)
But yeah, that still looks bad. Because if you want to see the inside, voxel plotting is not the best option. Alphas of different faces stack one on top of the other and the only way of solving this is writing advanced computer graphics ray tracing algorithms, and trust me, that's a long and tough road to take.
Very often one has 4D data, thus data that contains 3D location and a single data for each of the locations. One may think that in this case, you really want voxels, as each of them have a 3D +color, 4D data. Indeed! you can do it with voxels, but sometimes its better to describe it in some other ways. As an example, lets see this person who wanted to highlight a region in his/hers 4D space (link). To see a bigger list I suggest you look at my answer in here about 4D visualization techniques.
Lets try wits a different approach than the voxel one. Lets use the previous cube and create isosurfaces whenever the 4D data changes of value.
iso1=isosurface(cube,1);
iso2=isosurface(cube,4);
p1=patch(iso1,'facecolor','r','facealpha',0.3,'linestyle','none');
p2=patch(iso2,'facecolor','g','facealpha',1,'linestyle','none');
% below here is code for it to look "fancy"
isonormals(cube,p1)
view(3);
axis tight
axis equal
axis off
camlight
lighting gouraud
And this one looks way better, in my opinion.
Choose freely and good plotting!
Using CGAL, I have a 3D Delaunay Triangulation of a set of random points on the unit sphere, that I obtained via:
Delaunay T(points.begin(), points.end());
Now, what I would like to be able to do is query T (using locate() or something like that) to find the three vertices of the surface facet that an arbitrary point (also on the unit sphere) is contained inside.
When I use locate(), I get interior cells as results sometimes, which include the infinite vertex. I don't want any of these. I just want the surface facets and to be able to do this for any arbitrary point I try to find that is also on the unit sphere. Trying to figure this out has taken a lot longer than I thought it would.
Any help would be much obliged. Thanks.
So I would use find_conflit(), with CGAL::Emptyset_iterator for cit because you don't need these.
In bfit, you will get the facets of the boundary of the "hole", and the hole is all tetrahedra in conflict with your point (whose circumscribing sphere contains the point, with a natural extension to the infinite vertex).
So, for bfit, put them in a standard container using std::back_inserter for example. Then, iterate over these, tests if they are finite facets. The finite facets you get are those that separate your point from the rest of the triangulation, so, you can then do orientation() tests with the center of the sphere to get the one you are interested in.
So, this is going to be pretty hard for me to explain, or try to detail out since I only think I know what I'm asking, but I could be asking it with bad wording, so please bear with me and ask questions if need-be.
Currently I have a 3D vector field that's being plotted which corresponds to 40 levels of wind vectors in a 3D space (obviously). These are plotted in 3D levels and then stacked on top of each other using a dummy altitude for now (we're debating how to go about pressure altitude conversion most accurately--not to worry here). The goal is to start at a point within the vector space, modeling that point as a particle that can experience physics, and iteratively go through the vector field reacting to the forces, thus creating a trajectory of sorts through the vector field.
Currently what I'm trying to do is whip up code that would allow me to to start a point within this field and calculate the forces that the particle would feel at that point and then establish a resultant force vector that would indicate the next path of movement throughout the vector space.
Right now I'm stuck in the theoretical aspects of the code, as I'm trying to think through how the particle would feel vectors at a distance.
Any suggestions on ways to attack this problem within MatLab or relevant equations to use?
In order to run my code, you'll need read_grib.r4 and to compile that mex file here is a link to a zip with the code and the required files.
https://www.dropbox.com/s/uodvixdff764frq/WindSim_StackOverflow_Files.zip
I would try to interpolate the wind vector from the adjecent ones. You seem to have a regular grid, that should be no problem. (You can use interp3 for this)
Afterwards, you can use any differential-equation solver for your problem, as you have basically a field of gradients and an initial value. Forward euler would be the simplest one but need a small step size. (N.B.: Your field should be a gradient field)
You may read about this in Wikipedia: http://en.wikipedia.org/wiki/Vector_field#Flow_curves
In response to comment #1:
Yes. In a regular grid, any (arbitrary chosen) point will have eight neighbors. interp3 will so a trilinear interpolation to determine an interpolated gradient vector.
If you use forward-euler, you will then move a small distance in that direction. There you interpolate a gradient and go a small step into this new direction and so on. What happens are two things:
You get a series of points that lie on a streamline and thus form the trajectory of a particle moving along the field
Get large errors, the further you move and the larger the step size is. Use a small step size or use a better solver (Runge-Kutta comes to my mind)
If all you want is plotting, then the streamline function might help.
I am working with structured 2.5D and unstructured 3D data, which generally is available in (X,Y,Z) coordinates, i.e. point clouds. Now I want to impose a regular voxel grid onto the data. This is not meant for visualization purposes, but rather for "cleaning" or fusing the data. I imagine cases, where e.g. 3 points fall within the volume of one voxel. Then I would aim at either just setting this voxel to "activated" and discarding the 3 original points or alternatively I would like to calculate the euclidian mean of the points and return the thus "cleaned" point cloud as an irregularly structured one again.
I hope I could make my intentions clear enough: It's not about visualization and not necessarily about using volumetric cubes instead of points. It's only about manipulating possibily irregular point clouds in a structured way.
I was thinking about kd-tree or octree based solutions in this context, but can anybody point me in the proper direction? Hinting at existing MATLAB implementations would be most appreciated.
If the data is irregularly spaced, what you want to use is something which both smooths and interpolates your data points. A very good method for doing so is Gaussian process regression. Here's an example for the same problem but in 2D.
I have 3D space. And I know for example N points in this space (x1,y1,z1), (x2,y2,z2)..., (xn,yn,zn). I want to interplolate points, that is different from this. How can I do this in Matlab?
interp3 may help you. Here is the documentation.
As always, there are questions left unanswered by your one line query.
If the data is of the form where there is a functional relationship z(x,y), (or y(x,z) or x(y,z)) then you might potentially be able to use one of the interpolation tools. Thus, suppose you have data that lies on a lattice in the (x,y) plane, thus some value of z at each point in that lattice. In this case, you can use interp2.
Alternatively, if the data is scattered, but there is some single valued functional relationship z(x,y) that you don't have, but it is some continuous function. Infinite first derivatives are a problem too here. In this case, assuming that you have data that at least fills some convex domain in the (x,y) plane, you can still interpolate a value of z. For this, use griddata, or TriScatteredInterp. Or you might use my own gridfit tool, as found on the file exchange.
Next, the way you describe the data, I'm not at all positive that you have something in one of the above forms. For example, if your data lies along some curved path in this 3D domain, and you wish to interpolate points along that curved arc can be done using my interparc tool, also found on the file exchange.
One last case that people often seem to have when they talk about interpolation of a spatial set like this, is just a general surface, that they wish to build a neatly interpolated, smooth surface. It might be something as simple as the surface of a sphere, or something wildly more complex. (These things are never simple.) For this, you might be able to use a convex hull to approximate something, if it is a closed convex surface. More complex surfaces might require a tool like CRUST, although I have no implementation of it I can offer to you. Google will help you there, if that is what you need.
The point of all this is, how you interpolate your data depends on what form the data is in, what it represents, and the shape of the relationship you will be interpolating.