Intersection of segment with polygon - matlab

I have to create a function in MATLAB that performs the following task:
Input:
p polygon in the form
p = [x1,y1; x2,y2; x3,y3; x4,y4...]
s struct with the segment from A to B
s = struct('A',[x,y],'B'[u,w])
Return:
1) An integer indicating how many intersections there are between the segment and the polygon (e.g., 0,1,2)
2) A new segment from A to B, where A is the first intersection or the initial point of the input segment and B the second point of the intersection or the last point of the segment input.
I have an idea on how to do it by using the function inpolygon. I have been reading how to use this function, and know that to use that, I should provide a query point and the coordinates of the polygon vertices. It will return 1 or 0 depending on whether it is inside or not.
My question is, how can I get the query point of the segment that is placed exactly in the boundary (in the case that the segment intersects with it)?

If you have the Mapping Toolbox installed, you could use polyxpoly. As this is a rather basic problem, there are quite a few free MATLAB-codes out there on the File Exchange. Here is what I found for the search term 'polygon intersect':
2D Polygon edges intersection by Bruno Luong
Find the intersection points of the edges of two 2D polygons, a simple function made to follow up a Newsgroup discussion
Curve Intersect 2 by Sebastian Hölz
This file is based on the Curve Intersect function by Duane Hanselman. It extends the scope of the function to handle arbitrary lines / polygons, which may also have vertical segments or segments with non-increasing x-values.
Curve intersections by NS
While a few other functions already exist in FEX that compute the
intersection points of curves, this short piece of code was written
with speed being the highest priority. No loops are used throughout,
taking full advantage of MATLAB's vectorization capabilities
Fast and Robust Curve Intersections by Douglas Schwarz
This function computes the (x,y) locations where two curves intersect. The curves can be broken with NaNs or have vertical segments. It is also very fast (at least on data that represents what I think is a typical application).
geom2d by David Legland
[...] derive new shapes: intersection between 2 lines, between a line and a circle, parallel and perpendicular lines

Related

Intersection over union for rectangles with different orientation

I need to implement an algorithm in swift to find the intersection over union (IoU) between two rectangles with different orientations in 2-dimensional space. I could not find any tutorials or sample codes to teach how to implement such an algorithm.
Could someone provide relevant resources?
You can use O'Rourke algorithm for calculation of intersection of two convex polygons.
C and Java code is availaible on the page for book "Computational Geometry in C"
Algorithm traverses edges of polygons until it finds intersection (using
orientation test). After intersection it chooses "the most inner" edge from two possible next ones to build intersection core polygon (always convex).
When you have ordered list of vertices, you can calculate polygon area with shoelace formula.
To get area of union, we can calculate (thanks to Yves Daoust for hint)
Area(Union) = Area(P) + Area(Q) - Area(Intersection)
Alternatively to the very good solution of MBo/O'Rourke, you can use a sweep line approach.
For convenience, assume that one of the polygons is axis aligned. Then there are two "events" when the line hits the top and bottom sides of the aligned rectangle and four events when the line hits the vertices of the other (depending on the orientation, there are 8 possible permutations of the vertices).
The intersection of the rectangles occurs inside the vertical ranges defined by these events (you perform a merge of the two event sets) and there are up two six intersections to be computed between the oblique sides and the horizontals. For every event line, it is an easy matter to determine the X intervals spanned by both rectangles, and find their intersection or union. And the areas between two event lines are trapezoids.
To cope with rectangles in general position, you can
rotate both polygons to align one of them,
work with a counter-rotated coordinate system,
perform the sweep with an horizontal line anyway without moving the polygons; but then there are 8 events instead of 6 and up to 8 intersection computations.

How to find closest points between two convex hull in MATLAB?

In part of an Artificial Neural Network matlab code, I want to find nearest points of two convex polygons.
I saw
dsearchn(X,T,XI)
command's description here, but that finds closest points between two sets of points, and polygons (like convexs) have infinites points.
So can you suggest any way/idea?
Notice: I'm using MATLAB 2014a. I have the coordinate of each convex's vertex point.
If you are not happy with what is provided by dsearchn, then, If I were you, I would do one of two following:
Find Nearest Neighbours on the vertices (for example which vertex of
polygon A is the NN of a given vertex of polygon B).
Pick a random point inside polygon A (you may want to compute the
convex hull of A, but you may skip that and take into account only
the vertices you know already). That random point is the query. Find
an NN of that point from the vertices of polygon B.
You may want to ask in Software recommendations for more.
Edit:
Another approach is this:
Create a representative dataset of polygon A. Set the size of the dataset yourself and fill it with samples of points that lie inside the polygon. Choose them uniformly randomly inside the polygon.
Then take a point of polygon B (either a vertex or a random point inside polygon B) and that's the query point, for which you will seek Nearest Neighbour(s) inside the representative dataset of polygon A.
Of course that's just an approximation, but I can't think of something else now.
Notice that you can of course do the same for polygon B.
With This File in File Exchange, I've find the solution.
With a little code modification, I have drawn a perpendicular bisector which I wanted. Of course, this way is time consuming.

Use $within with a buffered MondoDB Linestring

I need to evaluate the proximity of a Point to a LineString using MongoDB.
Because the $near operator can only compare a Point to another Point, I need to generate a polygon out of the LineString, so I can use the $within operator. The distance between the LineString and the edges of the polygon should represent the radius I want to search in, such as represented in red below:
What might be a useful algorithm in order to accomplish this?
I think much easier would be to write your own function
To find (perpendicular) distance between point and line and then creating thickness of poly-line by polygon means.
Where:
P0,P1 are line endpoints
P is point
d is distance between them
Line is defined as: p(t)=P0+(P1-P0)*t where t=<0.0,1.0>
So the function should do this:
create perpendicular line
q(t)=P+DQ*u where u=(-inf,+inf)
DQ is perpendicular vector to (P1-P0)
In 2D you can obtain it easily like this (x,y) -> (y,-x). In higher dimensions use cross product with some non coplanar vectors.
compute line vs. line intersection
there are tons of stuff about this so google or solve the equation yourself here you can extract mine implementation.
now after successful intersection
just compute d as distance between P and intersection point. Do not forget that parameter t must be in range. If not (or if no intersection) then return min(|P-P0|,|P-P1|)
[hints]
t and u parameters can be obtained directly from intersection test so if the perpendicular vector to (P1-P0) is normalized to size = 1 then the abs(u) parameter of intersection point is the distance
[notes]
I am not familiar with mongodb so if you have no means to use own tests inside then this answer is of coarse obsolete.
Unfortunately, MongoDB provides very basic geospatial query, so you should create the buffer by your own. You can read how to do it here: Computing a polygon that surrounds a multi-point line
If you have longitude/latitude coordinates like WGS84 you must adjust this code; Read here how to calculate distance between point on a sphere https://en.wikipedia.org/wiki/Haversine_formula

Calculate distance between coordinates but with restrictions

I managed to find the intersections of an arbitrary number of lines within a binary image.
Then i use a function where i detect the intersections between the lines. So now i have the coordinates of the intersections saved in an array.
Now i want to calculate the distance between the intersections(an imaginary line that connects all my intersections) but i want the distance calculation to traverse along the lines that are already on the binary image.
So the distance calculation cannot escape a line while calculating, instead it must ''walk along it''.
The imaginary path(of which eventually we calculate its distance) must walk along the already drawn lines.
EDIT** THIS IS MY INTERSECTION DETECTION ''ALGO''
clear all
pellara4=imread('C:/users/lemesios/desktop/pellara4.jpg');
blackwhitepellara=im2bw(pellara4,0.5);
I = blackwhitepellara;
C = corner(I);
num_of_rows=size(C,1);
num_of_cols=size(C,2);
for z =1:num_of_rows
k=C(z,2);
j=C(z,1);
if (I(k+1,j)==0)&& (I(k,j+1)==0) && (I(k-1,j)==0) && (I(k,j-1)==0)
imshow(I);
hold on
plot((j), (k), 'b*');
disp(k);
disp(j);
end
end
I feel this is similar to Dijkstra's algorithm. You can denote the intersection points by nodes. Then generate a mesh where each intersecting point is connected to every other intersecting point. Then if there exists a line in the binary image, assign a unit weight, otherwise assign inf i.e. infinite weight. When you have to measure distnace between m-th point and n-th point (say), then make m-th point as source and n-th point as destination and find the shortest path according to Dijkstra's algorithm.

How to represent a polygon with hole(s)?

It's usually popular to work with polygons with their vertices sorted CW or CCW in vectors(2*1 or 1*2 matrices). However, how to state polygons with holes in vectors?
I'm going to apply various process on these polygons, so I want a way of representing with which I could work easily or efficiently.(i.e how to state that kind of polygons in my program in order to ease my algorithms?)
polygons are 2D and I'm programming in MATLAB.
EDIT 1 : I'm going to calculate visibility graph of these polygons(with or without holes).
As others have mentioned, a polygon with holes can be represented as an exterior boundary, plus zero or more interior boundaries, all of which are mutually nonoverlapping*. If you use nonzero winding number to determine inside/outside, be sure to specify your interior boundaries in the opposite direction as the exterior boundaries (counterclockwise for exterior and clockwise for interior, or vice-versa) so that the contour integrals are zero inside the holes.
FYI, tis kind of definition/representation has been formalized in the OpenGIS Simple Features Specification (PDF).
As far as representation:
I'd probably have a cell array of K Nx2 matrices, where the first element in the cell array is the exterior boundary, and the remaining elements (if any) in the cell array are the interior boundaries. I would use a cell array because there may not be the same number of points on each boundary.
*nonoverlapping = except at individual points, e.g. a diamond inside a square:
You can break a polygon with a hole in it into two shapes without a hole. When you're doing contour integration in a complex plane, you can create a "cut" from one edge of the polygon that brings you to the edge of the hole; integrate around one side of the hole and back; then traverse around the other side for the second polygon. You end up with two path integrals along each cut that cancel each other out.
"visibility graph" - is this for a radiation view factor calculation with shading? Or a ray-tracing graphics algorithm?
A polygon, plus a list of polygonal holes. Just be sure the various polygons don't intersect.
What do you plan to do with this thing?
It sounds like each hole is just a polygon inside the polygon itself. Perhaps you could store a vector like you describe for the outer polygon, then a vector of more polygon vectors for the holes.
Presumably you'll want to have a tree structure if you want this to be as generic as possible (i.e. polygons with polygonal holes that have polygons inside them with holes inside that, ...). Matlab isn't really great at representing tree structures efficiently, but here's one idea...
Have a struct-array of polygons.
Each polygon is a struct with two fields, 'corners', and 'children'.
The 'corners' field contains a matrix of (x,y) coordinates of the corners, accessed as "data{polyIdx}.corners(:,cornerIdx)".
The 'children' field is a struct-array of polygons.
Here's an example of some code to make a triangle with bogus children that are holes (they aren't really valid though because they will likely overlap:
polygon = struct;
npoints = 3;
polygon.corners = rand(2,npoints);
polygon.children = struct;
nchildren = 5;
for c=1:nchildren
polygon.children(c).corners = rand(2,npoints);
polygon.children(c).children = struct;
end
You could continue to recursively define children that alternate between creating holes and filling them.
What exactly do you mean under "a visibility graph" ?
Two "full" poligons, two states possible, either +1 or -1.
If you're representing a hole, you've got one with state +1 and one with state -1, which represents a hole, resulting in state 0.
If you've got overlapping polygons, you'll end up with resultant state >1. Then you can calculate the borders of a new polygon.
If you've got two polygons with holes that intersect, then first calculate the state of a new polygon which consists of outer borders of the two old ones, then deal with holes.
Anyways, ... I think you get the general principle.
Have no idea how to do it in matlab, I used it only marginally so far, and even that for very simple things.