Original domain in periodic triangulation with CGAL - cgal

I have some questions regarding the periodic triangulation in CGAL.
1) According to my understanding of the manual examples (http://doc.cgal.org/latest/Periodic_2_triangulation_2/examples.html) and the reference manual if we don't use Iso_rectangle in constructing triangles, (0,0,1,1) is chosen as the default value, am I right?
2) What is the meaning of this statement from manual? "input point is required to be an element of the half-open square representing the original domain"
3) "Another effect is that when the algorithm switches from 9-sheeted covering to 1-sheeted covering the Vertex_handles and Face_handles referencing deleted items becomes invalid", Does this mean that If I have vertex circulator in code, those adjacent vertices that are in periodic boxes, are neglected and not displayed in the output?

1) yes
Triangulation_2 (const Iso_rectangle &domain=Iso_rectangle(0, 0, 1, 1), const Geom_traits &traits=Geom_traits())
http://doc.cgal.org/latest/Periodic_2_triangulation_2/classCGAL_1_1Periodic__2__triangulation__2.html#a1e9c60f7c9844a33edff96b95aeb6c85
2) all insert functions have a precondition ensuring that input points are in the half-open square defined in Secrtion 1 of the user manual
http://doc.cgal.org/latest/Periodic_2_triangulation_2/index.html#title0
3) I am not sure that I understand what you mean by "neglected".
When the triangulation is in 1-sheeted covering mode, each vertex/face is stored only once, without copy, so the iterators/circulators simply traverse the triangulation directly in the flat torus. For a vertex circulator, you get all adjacent vertices.

Related

How to access net displacements in pyiron

Using pyiron, I want to calculate the mean square displacement of the ions in my system. How do I see the total displacement (i.e. not folded back by periodic boundary conditions) without dumping very frequently and checking when an atom passes over the boundary and gets wrapped?
Try to compare job['output/generic/unwrapped_positions'][-1] and job.structure.positions+job.output.total_displacements[-1]. If they deliver the same values, it's definitely fine both ways. If not, you can post the relevant lines in your notebook here.
I'd like to add a few comments to Jan's answer:
While job['output/generic/unwrapped_positions'] returns the unwrapped positions parsed from the output files, job.output.total_displacements returns the displacement of atoms calculated from each pair of consecutive snapshots. So if an atom moves more than half the box length in any direction, job.output.total_displacements will give wrong coordinates. Therefore, job['output/generic/unwrapped_positions'] is generally more trustworthy, but it is not available in all the codes (since some codes simply do not provide an output for unwrapped positions).
Moreover, if an interactive job is used, it is possible that job.structure.positions does not return the initial positions, i.e. job.structure.positions+job.output.total_displacements won't be initial positions + displacements.
So, in short, my answer to your question would be rather "Use job['output/generic/unwrapped_positions'] and if it's not available, use job.structure.positions+job.output.total_displacements but be aware of potential problems you might be running into."

Generate OPEN surface mesh from a set of 3D points

I have a set of points on an OPEN surface in 3D space.
I have identified a subset of points which lay on the boundary.
I mean to generate a triangulation of those points, which gives me an open surface and keeps my selected points on the boundary.
All references I found deal with (sometimes?) closed surfaces, e.g., CGAL.
See examples below.
In addition, some CGAL algorithms require oriented normals at each point, which I do not have.
Is there an available algorithm and code for this? (either CGAL Advancing_front_surface_reconstruction, properly handled, or any other)
See also this and this.
Example 1
I compiled and ran example reconstruction_surface_mesh.cpp from examples/Advancing_front_surface_reconstruction, out-of-the box (which uses file half.xyz as input for data points), and I obtained a closed surface:
I would like to get rid of the few triangles that close the surface.
I tried adding an extra point at the end of half.xyz, and I got
which is an open surface.
So far, with what I tested, I do not know:
How to indicate an open surface.
How to indicate which vertices lay at the boundary.
If this is a non-empty set (and it should have at least three vertices) this would imply an open surface.
Ideally, one would have a workflow which works without manual intervention.
Example 2
I compiled and ran example boundaries.cpp, out-of-the box (which also uses file half.xyz as input for data points).
The output is:
0 outliers:
Boundaries:
boundary
0.178269 0.438589 0.129521
0.0795598 0.419465 0.244812
0.0549683 0.377617 0.3119
-0.0295721 0.360972 0.329075
-0.111332 0.334417 0.342617
-0.186667 0.2953 0.346683
-0.2719 0.16555 0.375017
-0.336304 0.117058 0.339323
-0.393517 0.0775 0.285917
-0.421419 -0.126854 0.215271
-0.395217 -0.214417 0.20015
-0.354783 -0.2953 0.170767
-0.237067 -0.395867 0.172233
-0.178246 -0.438588 0.129553
0.0227767 -0.4873 0.0700833
0.220338 -0.438589 -7.23321e-06
0.293 -0.395867 0
0.36025 -0.334417 0
0.418077 -0.258382 6.0303e-05
0.46025 -0.17265 0
0.484417 -0.0425167 -0.0763333
0.485067 0.03875 -0.0782667
0.471547 0.117058 -0.076827
0.44605 0.197567 -0.0700833
0.4092 0.27125 -0.0433167
0.364885 0.329645 0
0.313633 0.377617 0.0441167
0.2509 0.41425 0.0879333
I did not find how to use this for
automatically removing triangles which would make my target boundary vertices not laying at the boundary.
Moreover, the output seems to be the list of boundary points, without the "spurious" triangles (I am not sure). I would like to specify this list.
The CGAL advancing front reconstruction algorithm does generate open surfaces in general.

Does ordering of mesh element change from run to run for constrained triangulation under CGAL?

I iterate over finie_vertieces, finite_edges and finite_faces after generating constrained delauny triangulation with Loyd optimization. I am on VS2012 using CGAL 4.12 under release mode. I see for a given case finite_verices list is repeatable (so is the vertex list under finite_faces), however, the ordering of the edges in finite_edges seems to change from run to run
for(auto eit = cdtp.finite_edges_begin(); eit != cdtp.finite_edges_end(); ++eit)
{
const auto isConstrainedEdge = cdtp.is_constrained(*eit);
auto & cFace = *(eit->first);
auto cwVert = cFace.vertex(cFace.cw(eit->second));
auto ccwVert = cFace.vertex(cFace.ccw(eit->second));
I use the above code snippet to extract vertex list, and vertex list with a given edge changes from run to run.
Any help is appreciated resolving this, as I am looking for consistent behavior in the code. My triangulation involves many line constraints on a two dimensional domain.
I was told it's likely dependable behaviour, but there is no guarantee of order. IIRC the documentation says the traversal order is not guaranteed. I think it's best to assume the iterators' transversal is not deterministic and could change.
You could use any of the _info extensions to embed information into the face, edge, etc (a hash perhaps?) which you could then check against to detect a change.
In my use case, I wanted to traverse the mesh in parallel and OpenMP didn't support the iterators. So I hold a vector of the Face_handles in memory which I can then easily index over. In conjunction with the _info data, you could use this to build a vector of edges,faces, etc with a guaranteed order using unique information in the ->info() field.
Another _info example.

Building an MKPolygon using outer boundary of a set of coordinates - How do I split coordinates that fall on either side of a line?

I'm trying to build a MKPolygon using the outer boundary of a set of coordinates.
From what I can tell, there is no delivered functionality to achieve this in Xcode (the MKPolygon methods would use all points to build the polygon, including interior points).
After some research I've found that a convex-hull solves this problem.
After looking into various algorithms, the one I can best wrap my head around to implement is QuickHull.
This takes the outer lat coords and draws a line between the two. From there, you split your points based on that line into two subsets and process distance between the outer lats to start building triangles and eliminating points within until you are left with the outer boundary.
I can find the outer points just by looking at min/max lat and can draw a line between the two (MKPolyline) - but how would I determine whether a point falls on one side or the other of this MKPolyline?
A follow up question is whether there is a hit test to determine whether points fall within an MKPolygon.
Thanks!
I ended up using a variation of the gift wrap algorithm. Certainly not a trivial task.
Having trouble with formatting of the full code so I'll have to just put my steps (probably better because I have some clean up to do!)
I started with an array of MKPointAnnotations
1) I got the lowest point that is furthest left. To do this, I looped through all of the points and compared lat/lng to get lowest point. This point will definitely be in the convex hull, so add it to a NSMutableArray that will store our convex hull points (cvp)
2) Get all points to the left of the lowest point and loop through them, calculating the angle of the cvp to the remaining points on the left. Whichever has the greatest angle, will be the point you need to add to the array.
atan(cos(lat1)sin(lat2)-sin(lat1)*cos(lat2)*cos(lon2-lon1), sin(lon2-lon1)*cos(lat2))
For each point found, create a triangle (by using lat from new point and long from previous point) and create a polygon. I used this code to do a hit test on my polygon:
BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polygonView.path, NULL, polygonViewPoint, NO);
If anything was found in the hit test, remove it from the comparison array (all those on the left of the original array minus the hull points)
Once you have at least 3 points in your cvp array, build another polygon with all of the cvp's in the array and remove anything within using the hit test.
3) Once you've worked through all of the left points, create a new comparison array of the remaining points that haven't been eliminated or added to the hull
4) Use the same calculations and polygon tests to remove points and add the cvp's found
At the end, you're left with a list of points in that make up your convex hull.

connect line between two boxes avoiding passing others

I have several boxes (x,y,width,height) randomly scattered around, and some of them need to be linked from point (x1,y1) in box1 to point (x2,y2) in box2 by drawing a line. I am trying to figure a way to make such line avoid passing through any other boxes (other than box1 and box2) by drawing several straight interconnected lines to go around any box in the way (if it is not possible to go with one straight line). The problem is that I don't know an algorithm for such thing (let alone having a technical/common name for it). Would appreciate any help in the form of algorithm or expressed ideas.
Thanks
Assuming that the lines can't be diagonal, here's one simple way. It's based on BFS and will also find the shortest line connecting the points:
Just create a graph, containing one vertex for each point (x, y) and for each point the edges:
((x,y),(x+1,y)) ((x,y),(x-1,y)) ((x,y),(x,y+1)) ((x,y),(x,y-1))
But each of this edges must be present only if it doesn't overlap a box.
Now just do a plain BFS from point (x1,y1) to (x2,y2)
It's really easy to obtain also diagonal lines the same way but you will need 8 edges for each vertex, that are, in addition to the previouses 4:
((x,y),(x-1,y+1)) ((x,y),(x-1,y-1)) ((x,y),(x+1,y-1)) ((x,y),(x+1,y+1))
Still, each edge must be present only if it doesn't overlap a box.
EDIT
If you can't consider space divided into a grid, here's another possibility, it won't give you the very shortest path, though.
Create a graph, in which each box is a vertex and has an edge to any other box that can be reached without the line to overlap a third box. Now find the shortet path using dijkstra between box1 and box2 containing the two points.
Now consider each box to have a small countour that doesn't overlap any other box. This way you can link the entering and the exiting point of each box in the path found through dijistra, passing through the countour.
Put all (x,y) coords of the corners of the boxes in a set V
Add the start- and end coordinates to V.
Create a set of edges E connecting each corner that does not cross any box-side (except for the diagonals in the boxes).
How to check if a line crosses a box side can be done with this algorithm
Now use a path-finding algorithm of your choice, to find a path in the graph (V, E).
If you need a simple algorithm that finds the shortest path, just go with a BFS.
(This will produce a path that goes along the sides of some boxes. If this is undesirable, you could in step 1 put the points at some distance delta from the actual corners.)
If the edges may not be diagonal:
Create a large grid of lines that goes between the boxes.
Throw away the grid-edges that cross a box-side.
Find a path in the grid using a path-finding algorithm of your choice.