I have 2 classes of points on a 2D plane.
I want to visually separate them (with a straight line/s) when drawing a graph on the screen.
In cases where they are not separable with a single straight line i thought the next best thing would be to partially separate them by having two parallel lines l1 and l2 such that all points of class A are above l2 (in regards to x-axis) and all points of class B are bellow l1. That is easy to do but i need the distance between the 2 lines to be as small as possible. How could i achieve that?
I drew a sketch demonstrating what i am trying to do.
In the sketch the 2 different classes are represented by 2 different colors (black and green).
All green points need to be under line 1 and all black points need to be above line 2, and the distance (d) between the two lines has to be as small as possible.
Related
I have a polygon in closed (ends in the starting vertex) and simple (no holes inside) form, I'm trying to think of an algorithm that draws lines between vertices such that these conditions are met:
The two sides of the line should have balanced number of vertices (at most 1 more vertex on one side is okay)
When lines join each other they have to make up either an angle of 90 or 135 degrees.
Here's an example image, as you can see the blue lines are drawn such that the above conditions are met:
Hint:
If you project the vertices orthogonally on a line, the vertices of the "sides" of your shape that are well aligned with the projection direction will form clusters, and if you pick one of these clusters, the line that projects onto the median of the cluster will meet your balancing condition.
So a possible path of attack is to consider several initial directions and the ones rotated in the appropriate multiples of 90° and 135°, and study the clusters so obtained.
Needless to say, nothing simple. (But your problem isn't.)
I know that there are efficient polygon clipping algorithms out there (e.g., Maillot, Vatti, Greiner-Hormann). However, these algorithms work for arbitrary polygons and although they fit my case, it seems to me that using such general algorithms for a simple case like mine is an overkill.
What I have is two 2D triangles (see figure below) that I want to clip the one against the other. Searching in the web didn't find anything apart from general polygon clipping algorithms.
Q: Is there a specialized algorithm for clipping two 2D triangles?
For two convex shapes the traditional approach is just Sutherland Cohen, but with more or fewer flags.
E.g. in your case:
blue A is outside red AB but inside the other two red edges; give it code 100;
blue B is the same; give it code 100;
blue C is outside red BC but inside the other two so give it code 010.
Starting from A:
code is non-zero, don't include blue A in the output;
looking at edge blue AB, the binary AND is non-zero so don't consider for output;
code for blue B is non-zero, don't include in output;
codes B and C AND to 0 so XOR* them. Gives 110. So find intersections of blue BC with edges red AB and BC, add them to the outpyt list;
code for blue C is non-zero, don't include in output;
codes for blue C and D again indicate to intersect with BC and AB so do so and add to output.
(* or OR them; we've established they share no bits in common so it makes no difference — I think XOR is a little more descriptive in saying that you're looking for differences)
Two methods, effective for convex polygons, are described here - Hoey's algorithm and O'Rourke's algorithm.
(I've used O'Rourke's one for convex quadrilaterals)
Just hints for optimization.
The complete discussion of which edges intersect and which vertexes belong to the final outline only depends on the algebraic areas of the triangles formed by a vertex of one triangle (A) and an edge of the other (B).
There are 9 such triangles, hence 9 areas and 9 signs. Anyway, the three triangles built with the same vertex of (A) have areas that sum to the area of (B), and only 9 - 3 + 1 = 7 areas need to be fully computed.
In addition, an intersection point between two edges is computed from two areas, using a formula like t= S / (S - S'), where t is the parameter along an edge.
So a completely unrolled algorithm can be written as a decision tree of depth 9 (using the 9 signed areas), with every leaf (512 of them !) generating a sequence of vertexes/intersections. There can be at worst 6 intersections.
It is known that 4 non-collinear, non-coplanar 3D points define a 3D sphere.
Is there an equivalent property/theorem for cylinder?
For cylinder you need 5 points. But I am not EXACTLY sure if 5 points uniquely defines a cylinder.
Following references justifies this:
http://library.wolfram.com/infocenter/Conferences/7521/cylinder_5_points_computation.pdf
A cylinder has 5 degrees of freedom: 4 for the axis (a line in 3D space), 1 for the radius, so in principle 5 points are required and enough.
But there can be several solutions: taking five point that form a regular bipyramid (two tetrahedra with a common base), there are 6 solutions, by symmetry.
This question is much more interesting than it looks like at a first look.
It is relatively easy to see how 5 points define a cylinder but not uniquely:
you can pick 3 of such points to define a circular cross section and let the other two define the bases. However it is not difficult to see that the choice of the three first points is not unique. It also depends on whether "define" means that the points have to lie on the surface (in which case the two last point have to lie inside the unbounded cylinder defined by the previous three) or not.
I think there is no simple elegant statement like in the case of the sphere.
For a finite cylinder you need a total of 7 parameters.
A 3D line needs 4 parameters (minimum distance from origin, and 3 for orientation). Then from the point closest to the origin you need 2 distances defining the beginning and end of the cylinder. One more parameter is needed for the radius, and voila, you have a 3D cylinder in space defined.
You can also use two 3D points plus a radius which also needs 7 parameters.
For in infinite cylinder you need 5 parameters. 4 for the line and 1 for the radius.
Sticking to the exact vocabulary of the question, you only need two points (really one point and a scalar for the radius) for a sphere.
A cylinder needs no more that 3 points. Two to define the axis and end points, plus a 3rd (really, 2 points and a scalar) to get the radius.
Given two convex polygons in 2D space, how would you go about constructing the line segment(s ) which, at any point on the lines, is equidistant from the closest point of either convex polygon?
I'm looking towards an implementation of Voronoi diagrams for convex polygons instead of points, but I'm unsure how to even begin calculating the line for just two polygons. So I figured I'd take this one step at a time and start here.
Edit To try to make the question a little clearer, I want to bisect the plane (or a subset thereof).
Suppose we have polygon A on the left and polygon B on the right. There will be some line of bisection that divides the plane into points on the left and points on the right. Every point on the line is equally distance from either polygon. Every point left of the line is closer to polygon A than to polygon B. Every point right of the line is closest to polygon B.
Here's an image generated by a Matlab script I wrote that brute-forces an approximation:
The problem, I believe, is not as simple as examining the space in "between" the two polygons, since the line must extend beyond the area directly between the two shapes. And ideally I'd like to find a solution that generalizes to more than two shapes, which, to me, seems to complicate the problem a great deal more. Here's a (obviously very rough) approximation of how that might look:
Well, proceeding one step at a time I'd look at the closest points in the polygons themselves. Let's say a in A is the closest point to B and b in B is the closest point to A. You know the middle point of AB is in the desired segments.
What are the posibilities for a? It can be a vertex of A or it can be a point in one side. The same applies for b. What happens with the "equidistant-segments"? How to build them in each case?
Since those segments are equidistant to sides of the polygons, they have to be part of the line that bissects the angle of the lines containing the corresponding sides.
Am I understanding you correctly but assuming you're wanting the line that effectively bisects the space between 2 convex polygons? If so, then ...
find the line that joins the 2 polygons (P1 & P2)
find each polygon centre (P1.centre & P2.centre) by calculating the average X and Y coordinate.
find the vertex on each polygon that's closest to the other's centre (P1.vc & P2.vc)
given that P1.vc & P2.vc now define the line joining P1 & P2
find the midpoint (mp) of P1.vc & P2.vc
Bisecting line = perpendicular of the line joining P1.vc & P2.vc that passes through mp
Given a convex polygon represented by a set of vertices (we can assume they're in counter-clockwise order), how can this polygon be broken down into a set of right triangles whose legs are aligned with the X- and Y-axes?
Since I probably lack some math terminology, "legs" are what I'm calling those two lines that are not the hypotenuse (apologies in advance if I've stabbed math jargon in the face--brief corrections are extra credit).
I'm not sure about writing an algorithm to do this but it seems entirely possible to do this for any convex polygon on a piece of paper. For each vertex project a line vertically or horizontally from that vertex until it meets another of these vertical or horizontal lines. For vertices with small changes in angle, where adjacent sides are both travelling in the same direction in terms of x and y, you will need to add two lines from the vertex, one horizontal and one vetical.
Once you have done this, you should be left with a polygon in the centre of the origonal polygon but with sides that are either vertical or horizontal because the sides have been formed by the lines drawn from the vertices of the original polygon. Because these sides are either vertical or horizontal, this shape can easily be sub-divided into a number of triangles with one horizontal side, one vertical side and one hypotenuse.
I'm assuming you've already ordered the vertices as you describe above, and that they indeed define a convex polygon.
Each vertex defines a horizontal line. For V vertices, then, you will have a set of V lines. Discard any line that meets one of the following criteria:
The vertex or vertices defining that line has/have the highest or lowest Y component (if one vertex, that line intersects the polygon only at that point; if two, that line coincides with a polygon edge)
If two vertices have equal Y coordinates otherwise, keep only one of those lines (it's duplicated).
The result will resemble a "banding" of the polygon.
Each horizontal line intersects the polygon at two points. One is its defining vertex. The other is either another vertex, or a point on a segment defined by two vertices. You can determine which is the case easily enough - just simple comparison of Y coords. The coordinates of the intersection with a segment is also easy math, which I leave to you.
Each intersection defines a vertical segment. The segment is contained within the polygon (if it coincides with an edge, you can discard it), and the other end meets either another horizontal line, or the edge of the polygon if that edge is itself horizontal. Determining the case is again a matter of mere comparison of coords. Finally, there may be 0-2 additional vertical segments, defined by the vertices with the highest and/or lowest Y coords, if there is only one of either.
The resulting diagram now shows each band with a right triangle trimmed off each end if possible. Each triangle should meet your criteria. The leftover regions are rectangles; draw an arbitrary diagonal to split each into two more right triangles meeting your criteria.
You're done.
I'm not sure if this is possible. Think about a square that's already aligned with the sides on the X and Y axes. How do you draw triangles using the vertices that are also aligned to the X,Y axes?
Or are the actual sides of the polygon allowed to be along the x,y axis. Which means you could just draw a line down the diagonal of the square. If so, it might be difficult to do with a more complex polygon where some sides are aligned to the axes, while others are not.
I'm not convinced there is a general solution to the question as posed. The problem is the aligned with the X- and Y-axes bit. That means that each vertex needs to be projected to the opposite side of the polygon in both the X and Y directions, and new vertices created at those intersection points. But that process must continue on for each new vertex added that way. You might get lucky and have this process terminate (because there's already a vertex appropriately placed on the opposite side), but in the general case it's just going to go on and on.
If you throw out that restriction, then Neil N's suggestion seems good to me.
Neil N is right, I think. Unfortunate that he didn't provide any specific links.
If you have a trapezoid whose top and bottom are parallel to the X axis, you can easily render that with 4 right triangles. Call that shape a horizontal trapezoid.
If you have a triangle with one side parallel to the X axis, you can render that with 2 right triangles -- or you can consider a degenerate case of the trapezoid with the top of bottom having length zero.
Start at either the top or bottom of your convex hull (i.e. search for coordinate with min or max y) and split it into horizontal trapezoids.
It's not to hard to write the code so that it works just as well with non-convex polygons.
I think this is not possible in the general case.
Consider the polygon {(0, 1), (1, 0), (2, 0)}
.
..
This triangle can not be split into a finite number of triangles as you describe.