How to test if a facet of a periodic c3t3 is on the boundary - cgal

I'm trying to extract the boundary facets of a periodic c3t3, i.e. all boundary facets including those at the periodic boundaries. My current approach is to try to iterate trough all the tetrahedra and test one by one its facets with "is_infinite" (see the code snipped bellow), but "is_infinite" is always returning false.
for(Cell_iterator cit = c3t3P.cells_begin(); cit !=c3t3P.cells_end(); ++cit) {
for(int l=0; l<4; ++l) {
const int id = V[cit->vertex(l)];
CGAL_assertion(1 <= id && id <= medit_number_of_vertices);
t[l] = id - 1;
if( tr.is_infinite(cit, l) )
std::cout << "is true!" << std::endl ;//Facet_boundary.push_back(points[t[l]]);
}
}

Here is a way you could go at your problem given the clarification in the comments above:
Start from a point on your surface
Use the locate() function of the periodic triangulation . This gives you a cell and an offset such that the point is in the tetrahedron of this cell translated by the offset parameter.
You can qualify whether a vertex of the periodic triangulation is contained in the interior, on the boundary, or in the exterior of the 3D closed shape using the class Side_of_triangle_mesh.
Walk from cell to cell (using cell->neighbor(0...3)). Note that as you walk, you will eventually reach the border of the internal representation and will need to shift offset when going to its neighboring cell: that's the purpose of the neighbor_offset() function that I mentioned in the comments.
For a given visited cell, qualify the position of its vertices as in (Side_of_triangle_mesh returns on boundary or on bounded side) or out (Side_of_triangle_mesh returns on unbounded side) of the shape. The position canonical position is given by Periodic_triangulation::point(Cell_handle, index) and you can shift it using Periodic_triangulation::construct_point(Point, Offset).
Do not explore the neighbors of a cell whose vertices are all out.
Cells whose vertices are all in are directly in your output.
For cells that have some vertices in and some vertices out, you could create a surface mesh from the tetrahedron (for example with make_tetrahedron) and compute the intersection with the shape using the corefine_and_compute_intersection.

Related

How to get triangle index using tree.any_intersection

Let's say we have a bunch of triangles 1,2,...,N, and a line segment. By making a tree, I want to get the intersection of the line segment with triangles and the index of the triangle that intersects the line segment (there is only one). How I call it from "intersection" below?
Thanks.
for (int i=0; i<NumTriangles; i++) {
Point a(Triangles[i].vert1[0], Triangles[i].vert1[1], Triangles[i].vert1[2]);
Point b(Triangles[i].vert2[0], Triangles[i].vert2[1], Triangles[i].vert2[2]);
Point c(Triangles[i].vert3[0], Triangles[i].vert3[1], Triangles[i].vert3[2]);
triangles.push_back(Triangle(a,b,c));
}
Tree tree(triangles.begin(),triangles.end());
Point a(0,0,0);
Point a(0,0,1);
Segment segment_query(a,b);
Segment_intersection intersection = tree.any_intersection(segment_query);
Each triangle you put in the three is called a primitive. This primitive has a unique identifier (also known as ID) and a geometry (datum, here a triangle).
The type of the primitive ID is defined by the template parameter of the class CGAL::AABB_primitive. If you are using the CGAL::AABB_triangle_primitive, which is just a simplified API around CGAL:AABB_primitive, then the ID is an iterator referring to the primitive within the range triangles.
The function any_intersection() returns an optional object which is a pair that contains both the geometry of the intersection (as first) and the intersected primitive (as second), from which you can get the ID with the id() function.

Get array of data based on hierarchical edges sequence in cytoscape.js

I use cytoscape.js to organize an flow of nodes that represent an tasks execution. Sometimes an task is not created hierarchicly.
At least in a visual way, edges gives the correct sequence.
I would like to get the hierarchical sequence based on the edges and list their data as an array. Each index will be dispposed as edges says so.
The image above represent a sequence based on the edges arrows. I would like to transform this edges/arrows sequence into a perfect sequence of data (array).
The cytoscape.elements().toArray() method transform visual to array, but it is delivered the same sequence of the original data.
How can it be done? Is there some method in cytoscape core?
The easiest way would be to give the nodes id's with the corresponding numbers in your sequence:
-> The first task to execute has the id 1, the second has the id 2...
After initialization you can then do a loop with n iterations (n = number of nodes in cy) and get the nodes one by one. That way you can access their information and enter this data into an array:
for (i = 0; i < cy.nodes().length; i++) {
var curr = cy.nodes("[id = '" + i + "']"); // This way you get the node with the id == i
//do stuff
array[i] = theDataYouNeed;
}
If you want the nodes to be in a hierarchy, you would have to rethink your layout. An hierarchy in cytoscape can be achieved by "directed acyclic graph" (= dagre in cytoscape).

How to maximize the value of the path?

We are given a N*N grid. And we are at the top left corner of the grid initially. Every square of the grid has some value attached to it, that is if someone reaches that square he wins the amount of money in dollars equal to the value attached to the square. Now legal moves are one step towards the right or one step towards the bottom. We have to reach the bottom right corner of the grid in a path such that we can maximize the amount of money won. Obviously we have to stay within the grid and cannot wander off it.
I started this problem by a greedy approach that at each step we look at the immediate right square and immediate square below the occupied square, and at each step choose the square having the higher value. But this does not give the right result all the time. For example in the following grid,
{ 6, 9, 18, 1 }
{ 2, 10, 0, 2 }
{ 1, 100, 1, 1 }
{ 1, 1, 1, 1 }
here my algorithm gives the maximum valued path as
6 -> 9 -> 18 -> 1 -> 2 -> 1 -> 1
which totals to 37, but we could have earned more on the path
6 -> 9 -> 10 -> 100 -> 1 -> 1 -> 1
which totals to 128. Could you people please help me in building a suitable algorithm? I have not yet coded this one because it would give a wrong output anyway. I don't know how to cope with this problem without brute force which would consist of seeing the values in all the paths not containing the square with the minimum value, and then finding the maximum.
#include <iostream>
#include <queue>
using namespace std;
int main()
{ int n; cin >> n;
int a[n+1][n+1], b[n+1][n+1];
for (int i=0;i<n;i++)
{
for (int j=0;j<n;j++)
{
cin >> a[i][j]; b[i][j]=a[i][j];
}
}
queue <int> q; int u,v,m=0;
q.push(0);q.push(0);
while (q.size()!=0)
{
u=q.front(); q.pop(); v=q.front(); q.pop();
if (v<n-1)
{
m=b[u][v]+a[u][v+1];
if (m>b[u][v+1])
{ b[u][v+1]=m; }
q.push(u);q.push(v+1);
}
if (u<n-1)
{
m=b[u][v]+a[u+1][v];
if (m>b[u+1][v])
{ b[u+1][v]=m; }
q.push(u+1);q.push(v);
}
}
cout << b[n-1][n-1];
return 0;
}
The problem can be solved with the following approach. Each cell at position (i,j) gets associated with a value val(i,j) which is the maximum total value possible by reaching it with the described legal moves (to the bottom, to the right) starting at position (0,0). The value at position (0,0) is the value from the grid, in the sequel termed as grid(i,j) for every i, j in {0,...,N-1}. We obtain the follwing recurrence relation
val(i,j) = grid(i,j) + max{ val(i-1,j), // path coming from upper cell
val(i,j-1) // path coming from left cell
}
where we suppose that indices outside of {0,...,N-1} * {0,...N-1} yield a value of negative infinity and are never really used. The recurrence relation is valid as there are at most two cases to reach a cell, namely from its upper neighbor or its left neighbour (except for cells at the border, which perhaps may be reached from only one neighbour).
The key point for an efficient evaluation of val is to organize the calculation of values in a sequence such that all needed neighbors are already evaluated; this can be done by succesively staring calculation at the leftmost cell for which val is not yet calculated and working from there in an upwards-rightwards manner until the top row is reached. This is iterated until position val(N-1,N-1) is evaluated, which yields the desired result.
If in addition the specific path to (N-1,N-1) is demanded, either backtracking or some auxiliary data structure has to be used to store how the value in the above recurrence relation was calculated, i.e. which term yields the maximum.
Edit
Alternatively, the evaluation can be done row-wise from left to right, which also has the desired property that all necessary values for the recurrence relation are already calculated; this is apparently easier to implement. In either case, the runtime bound will be O(n^2).
Actually this is a problem which is solvable using dynamic programming. You only need to adapt the algorithm for calculating the edit distance allowing for varying rewards.
The algorithm is described for example in https://web.stanford.edu/class/cs124/lec/med.pdf
The basic idea is that you start from top and you fill a square whenever you now its neighbouring (top,left) field.
The value you put in the field is the value of the higher of the two neighbours and the value of the current field. When you reach bottom right you just have to follow the path back.

Find polygons from set of lines

I'm working in 2D.
My user can draw some lines & line-segments, which I store in a custom object class, but basically in startX-Y & endX-Y.
Now I want to find, actually only the polygon where the ball is inside, but after reading and researching about some algoirthms etc. I think I have to find all polygons and serach after that the right one.
Is there anyone with some example code, c#, java objective-c !?
I tried several times with some pseudo-code explanations, I don't get it.
Overview
There are a number of different interesting questions at play here:
1. Given you have a set of lines on the screen, and the user places their finger from an arbitrary point and drags it to an arbitrary end point, we need to form a new line which does not cross over lines and where the start and end point actually lie on existing lines or on borders.
2. The next question is how do we maintain an active set of "relevant" line segments which form the convex hull which the ball resides in.
3. Finally given we have an active set of line segments how do we find the area of this shape.
Now It seems you've already answered part 1. So we focus on parts 2 and 3.
For part 2, we will also be interested in asking:
4. If we have a convex hull and a point, how do we determine if that point is in the hull.
We refer to here for the solution to 4 Find if a point is inside a convex hull for a set of points without computing the hull itself
The full implementation can be done efficiently if you are careful with the data structures you are using. This is left as a simple exercise. Let me know if I have done something incorrect here or you do not understand something. I look forward to playing your game when its ready!
Solution to Part 3
In fact 3 is easy from 2, since if we know the active set of line segments containing the ball (this is a list of pairs of tuples ((x_1start,y_1start), (x_1end, y1_end))), there are two ways to compute the area. The first is to do a straightforward algorithm to compute the area of the convex hull formed by all start and end points in this list of tuples. Look up more sophisticated algorithms for area, but if you cannot find one, note that the hull with n sides has n-2 non-overlapping triangles, and the area of triangles is easy to compute (http://www.mathopenref.com/polygontriangles.html). Note:
area = abs((x1-x2)*(y1-y3)-(y1-y2)*(x1-x3)) for triangle (x1,y1)(x2,y2)(x3,y3)
Now if you sort all (x,y) points by their angle about the positive x axis, then we simply fix the first point, and consecutively walk through the remaining pairs and find the areas of those triangles. Left as an easy exercise why this sorting step is required (hint: draw a picture).
Solution to Part 2
Now the tough part is 2. Given that we have an active set of line segments enclosing the ball, how do we add a new line, and then adjust the size and number of line segments inside our active set. Note that at the beginning of the game there are precisely 4 lines in the active set which are the borders of the screen (this will be our base case if you like induction).
Now suppose we have an arbitrary active set containing the ball, and the user adds a new line, we assume it hits exactly two existing line segments and does not cross any line segments (by part 1 algorithm). Now we need to modify the active set. By algorithm 1, we know which line segments are hit by this point. So the only way that the active set can change is if both line segments hit by this point are in the active set (draw a picture to see this fact).
Now assume that the new line segment hits two lines inside the active set (this means it essentially splits the active set into two convex hulls). If we maintain our active set in a rotated order (that is to say we ensure that it is always sorted by angle about the positive x axis), we simply need to add our new points in a way that maintains this sorted ordering. So for instance suppose our points of the active set (collapsing line segments to single lines) are:
[(x1, y1), (x2, y2), (x3, y3), ..., (xn, yn), (x1, y1)]
And we want to add the new line segment ((x', y'), (x'', y'')), and our new set looks like:
[(x1, y1), (x2, y2), (x', y'), (x3, y3), ..., (xn, yn), (x'', y''), (x1, y1)]
Then there are now two convex hulls that are formed:
1. [(x1, y1), (x2, y2), (x', y'), (x'', y''), (x1, y1)]
2. [(x', y'), (x3, y3), ..., (xn, yn), (x'', y'')]
So the only remaining question is which is our new active set. Simply use algorithm 4.
Data Structures for Part 2
First we need the classes line segment and point (im avoiding implementing things like equals, hashcode for simplicity):
class Point {
public int x;
public int y;
}
class LineSegment {
public Point lineStart;
public Point lineEnd;
}
Now we can represent our active set datastructure:
class ActiveSet {
public List<Line> thesortedlist;
}
Now we first initialize our active set with four lines and denote the center of the screen as (0,0):
LineSegment TopBorder = new LineSegment(new Point(10, 10), new Point(-10, 10));
LineSegment LftBorder = new LineSegment(new Point(-10, 10), new Point(-10, -10));
LineSegment BtmBorder = new LineSegment(new Point(-10, -10), new Point(10, -10));
LineSegment RightBorder = new LineSegment(new Point(10, -10), new Point(10, 10));
ActiveSet activeset = new ActiveSet();
activeSet.theActiveLines.add(TopBorder);
activeSet.theActiveLines.add(LftBorder);
activeSet.theActiveLines.add(BtmBorder);
activeSet.theActiveLines.add(RightBorder);
Now say the user adds a line from point (0, 10) to (10, 0), so this is a diagonal (call it newSegment) and the new active set will look like:
------
- -
- -
- -
- -
- -
- B -
- -
-----------
Note the cut in the upper right corner, and B denotes the ball. Now by algorithm 1 we know that lines TopBorder and RightBorder are hit. Now both of these are inside the activeset (we can test membership faster by using a hashmap). Now we need to form two activesets as follows:
ActiveSet activesetLeft = new ActiveSet();
ActiveSet activesetRight = new ActiveSet();
Now in order to build these sets proceed as follows:
List<LineSegment> leftsegments = activeset.GetSegmentsBetween(TopBorder,
RightBorder);
List<RightSegment> rightsegments = activeset.GetSegmentsBetween(RightBorder,
TopBorder);
This function GetSegmentsBetween(LineSegment firstline, LineSegment secondline) should just locate firstline in the list and then return all elements until it finds secondline (this may need to do two passes through the list). It should not include these firstline or secondline in its return value. Now suppose we have activesetLeft and activesetright, we need to do the following:
activesetLeft.append(new Line(secondLine.lineStart, newSegment.lineStart));
activesetLeft.append(newSegment);
activesetLeft.append(new Line(newSegment.lineEnd, firstLine.lineEnd));
activesetRight.append(new Line(firstLine.lineStart, newSegment.lineEnd));
activesetRight.append(new Line(newSegment.lineEnd, newSegment.lineStart));
activesetRight.append(new Line(newSegment.lineStart, secondLine.lineEnd));
It is really hard to understand in code, but the order of everything above is important, sicne we want to maintain sorted going in counterclockwise order.
It is left as an exercise how you can speed this up (in fact you dont need to build two active sets, just first figure out if the ball is above or below the new segment and build the left or right activeset accordingly).

Uniform distance between points

How could I, having a path defined by several points that are not in a uniform distance from each other, redefine along the same path the same number of points but with a uniform distance. I'm trying to do this in Objective-C with NSArrays of CGPoints but so far I haven't had any luck with this.
Thank you for any help.
EDIT
I was wondering if it would help to reduce the number of points, like when detecting if 3 points are collinear we could remove the middle one, but I'm not sure that would help.
EDIT
Illustrating:
Reds are the original points, blues the post processed points:
The new path defined by the blue dots does not correspond to the original one.
I don't think you can do what you state that you want to do. But that could be a misunderstanding on my part. For example, I have understood from your comment that the path is straight between successive points, not curved.
Take, for example, a simple path of 3 points (0,1,2) and 2 line segments (0-1,1-2) of different lengths. Leave points 0 and 2 where they are and introduce a new point 1' which is equidistant from points 0 and 2. If point 1' is on one of the line segments 0-1, 1-2, then one of the line segments 0-1', 1'-2 is not coincident with 0-1, 1-2. (Easier to draw this, which I suggest you do.) If point 1' is not on either of the original line segments then the entire path is new, apart from its endpoints.
So, what relationship between the new path and the old path do you want ?
EDIT: more of an extended comment really, like my 'answer' but the comment box is too small.
I'm still not clear how you want to define the new path and what relationship it has to the old path. First you wanted to keep the same number of points, but in your edit you say that this is not necessary. You agree that replacing points by new points will shift the path. Do you want, perhaps, a new path from point 0 to point N-1, defined by N points uniformly spaced on a path which minimises the area between the old and new paths when drawn on the Cartesian plane ?
Or, perhaps you could first define a polynomial (or spline or other simple curve) path through the original points, then move the points to and fro along the curve until they are uniformly spaced ?
I think the problem is simple and easily solvable actually :)
The basic idea is:
First check if the distance between your current point (P) and the end point of the line segment you are on is >= the distance between P and the next point (Q).
If it is, great, we use some simple trigonometry to figure it out.
Else, we move to the adjacent line segment (in your ordering) and deduct the distance between P and the endpoint of the line segment you are on and continue the process.
Pseudocode:
Defined previously
struct LineSegment
{
Point start,end;
int ID;
double len; // len = EuclideanDistance(start,end);
LineSegment *next_segment;
double theta; // theta = atan2(slope_of_line_segment);
}
Function [LineSegment nextseg] = FindNextLineSegment(LineSegment lineseg)
Input: LineSegment object of the current line segment
Output: LineSegment object of the adjacent line segment in your ordering.
nextseg.ID = -1 if there are no more segments
Function: Find the next point along your path
Function [Point Q, LineSegment Z] = FindNextPt(Point P, LineSegment lineseg, int dist):
Input: The current point P, the distance between this point and the next, and the LineSegment of the line segment which contains P.
Output: The next point Q, and the line segment it is on
Procedure:
distToEndpt = EuclideanDistance(P,lineseg->end);
if( distToEndpt >= d )
{
Point Q(lineseg->start.x + dist*cos(lineseg.theta), lineseg->start.y + dist*sin(lineseg.theta));
Z = lineseg;
}
else
{
nextseg = lineseg->next_segment;
if( nextseg.ID !=-1 )
{
[Q, Z] = FindNextPt(nextseg->start,nextseg->ID,dist-distToEndpt);
}
else
{
return [P,lineseg];
}
}
return [Q,Z]
Entry point
Function main()
Output: vector of points
Procedure:
vector<LineSegment> line_segments;
// Define it somehow giving it all the properties
// ....
vector<Point> equidistant_points;
const int d = DIST;
[Q Z] = FindNextPoint(line_segments[0].start,line_segments[0],DIST);
while( Z.ID != -1 )
{
equidistant_points.push_back(Q);
[Q Z] = FindNextPt(Q,Z,d);
}
My sense is that this is a very hard problem.
It basically amounts to a constrained optimization problem. The objective function measures how close the new line is from the old one. The constraints enforce that the new points are the same distance apart.
Finding a good objective function is the tricky bit, since it must be differentiable, and we don't know ahead of time on which segments each new point will lie: for instance, it's possible for two new points to lie on an extra-long old segment, and no new points lying on some extra-short old segment. If you somehow know a priori on which segments the new points will lie, you can sum the distances between points and their target segments and use that as your objective function (note that this distance function is nontrivial, since the segments are finite: it is composed of three pieces and its level-sets are "pill-shaped.")
Or you might forget about requiring the new points to lie on old segments, and just look for a new polyline that's "close" to the old one. For instance, you might try to write down an L2-like metric between polylines, and use that as your objective function. I don't expect this metric to be pleasant to write down, or differentiate.
I think a perturbative approach will work for this one.
I assume:
we know how to slide a point along the path and recalculate the distances (pretty trivial), and
the end points must remain fixed (otherwise the whole problem becomes trivial).
just iterate over the remaining (n-2) points: if point k is closer to point (k-1) than to point (k+1), move it a little forward along the path. Likewise if it's closer to point (k+1), move a little back along the path.
It's probably best to start with large step sizes (for speed) then make them smaller (for precision). Even if the points pass each other, I think this approach will sort them back into order.
This will use quite a bit of vector math but is quite simple really.
First you will need to find the total distance of the path. Depending on how the points of the path are stored is how you will do it. Here is a basic example on a 2 Dimensional Path in Pseudo-code.
// This would generally be done with vectors, however I'm not sure
// if you would like to make your own class for them as I do so I will use arrays.
// The collection of points
int Points[4][2] = { {0,0}, {1,2}, {5,4}, {6,5} };
int Points2 = Points;
// goes to 3 because there are 4 points
for(int i=0; i<3; i++) {
x = Points[i+1][0] - Points[i][0];
y = Points[i+1][1] - Points[i][1];
d += sqrt(( x * x ) + ( y * y ));
}
// divide distance by number of points to get uniform distance
dist = d/4;
// now that you have the new distance you must find the points
// on your path that are that far from your current point
// same deal here... goes to 3 because there are 4 points
for(int i=0; i<3; i++) {
// slope
m = ( Points[i+1][1] - Points[i][1] ) / ( Points[i+1][0] - Points[i][0] );
// y intercept
b = -(M * Points[i][0]) + Points[i][1];
// processor heavy which makes this problem difficult
// if some one knows a better way please say something
// check every degree grabbing the points till one matches
// if it doesn't then check next segment.
for(float j=0; j<360; j += 0.1) {
x = dist * sin(j);
y = sqrt((dist * dist) - ( x * x ));
if (y - (M * x + C)) {
// then the point is on the line so set it
Points2[i+1][0] = x;
Points2[i+1][1] = y;
}
}
}
The last step is what makes it unreasonable but this should work for you.
There may be a small math error somewhere I double checked this several times but there could be something I missed. So if anyone notices something please inform me and I will edit it.
Hope this helps,
Gale