Line segment in a triangle - c++

How can we check if a line segment falls partially or fully inside a triangle?
Cheers.

Get the function for the line from the end points of the line segment. Check where this line crosses any of the sides of the triangle.
If any part of the line segment is inside the triangle, the line will either pass in through one side and out through another, or it will pass exactly along one side of the triangle and pass through two of it's corners.
If the line passes through the triangle, you compare the points where the line crosses the triangle sides (or corners) with the end points of the segment, to see if the segment is part of the line that crosses the triangle.

For checking if a line is fully inside a triangle, you need to check whether both end points of the line segment are located inside of the triangle.
Checking if a point is inside of a triangle can be done using techniques described here.
Checking if a segment intersects the triangle partially is a bit more complex, since checking its end points may not be enough. There are two possible cases of partial intersection:
One end point is inside of the triangle, and the other isn't
Both end points are outside of the triangle, but the segment crosses at least one of the triangle sides.
Checking 1. can be done by this technique. Checking 2. can be done by algorithms that check whether two segments intersect. One example of how it can be done is here.

If one of the points of the segment is inside of the triangle => partially, if both are => fully
Point O is inside of the triangle if and only if the sum of angles AOB, BOC, COA equals 360 deg.
Cheers,
Gleb

Better algorithm follows:
Why not do this:
If both end points of the line segment lie inside or on triangle, then line segment must lie on or inside triangle.
To check if a point lie inside triangle:
Stand at the point, look at each vertex of the triangle
If you look at each vertex in clockwise / anticlockwise direction then you are inside or outside

Related

Project a line segment onto a mesh

What are the graphic/mathematical algorithms I have to look for in order to achieve the red line in the following image?
Explaining it better: I need to plot two points on the mesh and then generate a straight line segment from one point to the next. This line segment would be formed by new vertices created on every single edge in its way.
I'm currently working with CGAL and Libigl, but none of them seem to have the solution. I have tried CGAL::Surface_mesh_shortest_path but it adds too much overhead (code runs very slowly) and the line would not be guaranteed to be straight depending on the mesh deformation.
Ignoring whatever you mean as "straight", here is one simple algorithm I can think of that would produce images to the one similar shown in the question. There is no guarantee of what is produced being the shortest path. I'm just spitballing here with no knowledge on the topic, there are probably better ways.
Pick 4 variables:
The starting point
The ending point
The line's normal
A marching constant
Let's calculate a few constants from the variables:
Direction = ending point - starting point
Increment vector = normalize(Direction) * marching constant.
Begin from the starting point and march towards your ending point by some constant, checking above and below your current position for where you are on the mesh. You use the line's normal to understand the "up" and "down" directions in order to perform intersection tests.
On each intersection test, if you do not intersect for both the up and down directions, then the normal you chose will not work for the given two points and mesh, and you'll have to try a different normal. If you do end up intersecting from one of the directions, you will need to add 2 points to your final line: a point on the calculated direction line closest to the start that lies on the triangle, and a point on the calculated direction line farthest from the start that lies on the triangle. If there's both an intersection on the up and down directions, choose the up direction to work with.

How to find list of line segments inside a polygon

I have a line and a polygon . The line can be partially inside and partially outside the polygon . The line can intersect the polygon at a single point or at multiple points. The example lines are shown as below
Please refer the picture . For horizontal red colored line I would like to get list of line segments . The desired output is (A-B) (C-D) (E-F) and for vertical line I want to get line segments 1-2 .
I went through how to detemine if a line segment is inside of a polygon? and other questions of stack overflow .
but could not get most optimized algorithm to get a list of line segments inside the polygon.
I went through the following link also
https://en.wikipedia.org/wiki/Bentley%E2%80%93Ottmann_algorithm but my question is there more optimized algorithm to find line segments within the polygon ?
I am answering in the case that no preprocessing is allowed, i.e. you have a single line segment (or a few) to process for a given polygon. The polygon is general (and can be with holes).
Rotate the line to make it horizontal, and simultaneously rotate the polygon vertices.
Then a side of the polygon intersects the supporting line of the segment if the endpoints have ordinates of a different sign. In this case, you can compute the location of the intersection.
The subsegments inside the polygon are made from the ordered intersection points found between the segment endpoints.

Finding a point inside a Boost::Geometry::Polygon

I have a Polygon object and I'm looking for an efficient way to find any point strictly inside it (not on its boundary). What is the best way to do so?
I had the following ideas, which I don't really like:
Triangulating the polygon and reporting a point on one of the triangulation edges (too expensive).
Checking the polygon's winding direction and reporting a point located in an epsilon-distance from one of the polygon's edges (doesn't work in edge-cases).
Given a polygon, you can find the first two points where the polygon crosses a line parallel to x axis and lies between the yMin & yMax of your polygon (0 & 1 in the image below).
Any point between these points will be inside your polygon. The basic idea comes from scan converting a polygon —i.e. these are the points you would fill. The part of the line after the second point has a winding of 0 or 2, depending on your polygon.
The first two crossings (or last) has to be taken, as the crossing points are sorted along the x-axis.
Some corner cases:
If you omit all points of the polygon which just touches the line, in some cases this can fail (image below).
If there are overlapping lines in your polygon, you have to resolve those.
To avoid the first issue, make sure to take the first point as a definite crossing and the next one can be either a crossing or a point where polygon just touches the line.
This can be easily implemented without using any special functions in most languages. Since I am not familiar with Boost methods, I am posting a sketch of the basic idea in javascript.
The drawing is done using paper.js —although, the code for the algorithm outlined here itself is self contained.
You can translate this to C++ as long as you can enumerate through all points in a Boost::polygon
Here is the demo.

How to split a general closed polygon by a line segment

I need a good (robust) algorithm for splitting a polygon into two sets(left/right) by a line segment. My polygon representation is simply a list of integer coordinates(ordered clock wise, never self intersecting) and the line segment is represented by a start and end point. The line always starts and ends outside the polygon, i.e. intersects the polygon an even number of times.
Here is an example:
The output of the algorithm should be the two sets(travelling clock wise):
Left: HABCH, FGDEF
Right: HCDGH, BAB, FEF
I can identify the points A-H by iterating the polygon and checking if a polygon segment crosses the line, taking care to respect border cases. I can also determine which side each multi-line belongs to. I cannot though, for the life of me, decide how to string these segment together.
Before you suggest a general purpose clipping library: I am using boost polygon which is very good at clipping polygons against each other, but I haven't found any library which let's you clip a polygon against a line segment and it is not possible in general to turn the line segment into a polygon which I could clip with.
EDIT: I had missed FEF and the fact that a polygon can have parts on both sides of the line segment.
Ok, here is a rather simple recipe of how to arrive at the answer:
Start with the set of intersection points ordered by traveling the contour clockwise:
ABCDEFGH
Sort them according to distance from the start of line:
HCFEDGBA
We also need to remember for each point if it is a left-to-right or right-to-left intersection.
Start with any point. Let's say G. Follow the contour clockwise and add GH
to the current polygon.
Now we need to travel along the line. The
direction depends on which side of the line we are. We are on the
right side, so we need to pick the value to the right of H in the
sorted set: C. Add HC to the current polygon.
Follow the contour clockwise and add CD to the current polygon.
We are on the right side, so we need to pick the value to the right of D in the sorted set: G. Add DG to the current polygon.
We have now reached the
starting point, so let's save the polygon(GHCDG) and remove used
points from the list.
Start over with another point.
For each intersection of the polygon border with the line segment:
Add a new point to the polygon.
Remember the new points in a new-point set.
Add the original polygon to the polygon set.
For each pair of points in the new-point set:
For each polygon in the current polygon set:
If the line segment between the points is completely inside the polygon.
Replace the polygon in the polygon set with two polygons
generated by dividing the original polygon along the line
segment between the points.
For each polygon in the polygon set:
Add it to the Left result set or the Right result set.
(Note this may not be possible.
Consider your example of the segment starting between C and F:
You will end up with a polygon (GABCFG) that touches both
sides of the dividing segment. Is that a Left or a Right?
I've solved something similar once and I gave up trying to be clever.
Run round all the vertices making them into connected line segments,
starting a new segment with a new point every time you intersect the
cutting line.
Find all segments which share an end point and join them back up into one longer one.
Connect all the open ends.

CGAL: extend segment until the polygon boundary

If I have a segment between 2 vertices of a polygon, is there a way to extend this segment until it reaches the polygon boundary, using CGAL? (this can happen if at least one of the vertices is a reflex vertex).
You could get the supporting line of the segment via mySegment.supporting_line() and check where this line intersects with the polygon boundary. You can then create a new Segment that is based on the found intersection points.
Let p1 and p2 be the Vertices of your Segment. If I get you right, you'd want to sort the intersection points by their coordinates and create a Segment that goes from the 1st intersection Point smaller than p1 and p2 to the 1st intersection point greater than p1 and p2. (Note that several special cases are to be handled here.)
To get the intersection points, you can iterate over the segments of your polygon and intersect each one with the mentioned supporting line via CGAL::intersection.
A more sophisticated approach would be to create an Arrangement containing your polygon, attaching an Observer to it and then adding the mentioned supporting line to the Arrangement. You'd then get the information you need from the automatic calls to obs.before_split_face() and obs.before_split_face().