Finding the specific outline of a set of points - c#

I have a set of "blocks" (denoted by the red and green lines) that are placed inside a "container" (denoted by the blue lines).
All of the intersection points of the blocks (green and red dots) and all relevant information of the container (angle, gradient, start,end points, etc.) are known.
I want to extract the "top-most" outline of the resultant figure after the blocks are placed (denoted by the green lines and dots).
I tried to use methods such as convex hull (shown by purple lines in the following diagram), but it does not give the exact lines.
My question is can anyone point me to a solution or some kind of algorithm that I can apply to solve these type of problems?

Fill the list (array ) with all points. (Repeat points in T-nodes like 2nd green point at your picture)
Sort this list by Y-coordinates
Scan list (starting from top points) like sweep line algorithm.
At every stage you'll get a pack of points with the same Y-coordinate (a pair or more).
Remove points covered be intervals (see below) both from left and from right.
Make intervals (by X-coordinates) from pairs of these points.
Add these intervals in interval (segment) tree.
Join neighbor intervals.
Repeat until single interval cover all the top part.

The convex hull should do the job.
You can check: Fast and improved 2D Convex Hull algorithm and its implementation in O(n log h) for many convex hull algorithms.
As soon as it touch red points, you get before and after.

Related

How to find inner border of shape represented as point collection?

I need to get inner border of shape. Previously, I found nearest point to the center of shape in case of square or circle shape, but how can I do it in M-shape case.
What I have (I need marked points at screenshot №2):
Any algorithms, steps to find these points?
UPD: Now, I have segments direction vector like (1, 0) or (0.5, 0.5)
It looks like the first step is to simplify by averaging near-neighbour dots into a single point. Then find the smallest convex polygon that contains all points (easily done). Then selectively punch some sides in to meet the internal points (the polygon becomes concave). There are many ways to select which sides to punch in, and which points to punch in to first, and I can't be sure what's best without knowing more about your specific goals.
A simple approach would be to deal first with those points that are closest to an existing side, and punch the nearest side in to meet them. But you may want to apply other scoring conditions to choose the best points to deal with first and the best sides to punch in. For instance, you may want to give higher scores to points that are closely vertically or horizontally aligned with one of the vertices of the current polygon, so that they are dealt with earlier rather than later; and give the sides adjoining that vertex a higher score as candidates for punching in. You probably also want to award longer sides with higher scores as candidates for punching in.
I imagine that with a few simple weighting criteria such as these, you will quickly get some sensible results.
Finally, if you wish, you can refer back to your original set of unaveraged dots, and make further small adjustments to the shape to ensure that all those dots fall outside its boundaries.

Quadrilateral Intersection 4 points

Rectangle Possibilities
I am trying to figure out if 2 rectangles that are rotated are intersecting.
The image(Rectangle Possibilities) shows examples of intersecting rectangle possibilities. The information that I know about each rectangle is the 4 vertices.
Rotate the two rectangles so that one becomes axis parallel, and check non-interference of the two axis-aligned bounding boxes. Then repeat with the second. This is necessary and sufficient to guarantee no overlap.
Powerfule method of checking whether two convex polygons do intersect is using Separating Axes Theorem. Yet more description.
It is rather simple (and fast) for rectangles.

algorithm for creating shapes out of arrays

I'm looking for an algorithm which could create shapes based
on arrays with coordinates. I have two 50x50 arrays: one with x and second with y coordinates.
There is always 2500 points. Then I have another 50x50 array with my values for coordinates.
I create 3 to 6 areas based on value (for example 0-100, 200-300 and 300-500). Points with certain values creates areas.
I need an algorithm which can calculate if there is only one shape in area or more and fill shapes with colors.
I need that because I must fill shapes with certain colors for each area.
Language is C#.
Example points.
Expected edges.
Expected result
Basically you could use hierarchical clustering to find the clusters.
Each point is its own cluster
Find two cluster closest together and merge them
Repeat until end condition is met
Couple of specifics: In step 2 you could use many metrics to find the closest clusters. Mean-to-mean distance or minimum distance over all point pairs are probably best choices
In Step 3, you can either stop when remaining number of clusters is 2 (or some other number). Or stop when distance is more than a threshold.
To find the actual outline, I suggest coming up with some optimization function that minimizes the length of outline while minimizing the area of the outline. And the some heuristics to optimize the function.
Something like Area - constant*Length.

Algorithm for filling space between points with color

I have points from arrays which looks like this after printing:
Points are printed based on three arrays: one with x coordinate, second with y coordinate and third with value for color .Now I need an algorith to fill space between those points. Important thing is I don't want to fill space between separate shapes. Is there any method for doing that except using concave hull (there is no implementation in c#)
edit: is it possible to somehow separate those areas and then use flood fill?
How precise do you need the algorithm to be?
If you can tolerate some imprecision (a small area around the point shapes would be selected too), you could do with a blur.
It would go like this:
1) Blur the image with a small radius (equal to half of the maximum allowed distance between the points).
2) Each pixel that has color which is precisely equal to the background color is considered "outside" (each pixel with a different color is within a small disance to one of the darker points).
There is BlueBitmapEffect in WPF, but that probably cannot be used in your scenario. You can find countless blur implementations online though.
If you need to be precise, you are out of luck in my opinion. Your goal is basically the definition of convex/concave hull.

Recognizing Rectangle shape

I have a list of points of a stroke and I want to detect if this stroke is rectangular.
So 4 angles of approximately 90 degrees. Afterwards I need the size, position and orientation of the rectangle.
I am using C# but algorithms in other languages or pseudocode are also usefull.
Thanks
Well, I've made something like this a while ago.
You can download it here.
http://up352.siz.co.il/up2/lhmjmdenn53m.png
This thing allows you to detect edges - as you see its pretty accurate.
When you get the edges all you need is to calculate the angles between them - and if it's ~ 90 then its a rectangle.
I'll assume that you collected each stroke into a separate list:
Find the trend line for the stroke (I'd start with Simple linear regression for this).
Find the angle between the each two intersecting trend lines (compare to 90 deg with some threshold).
Find orientation (angle) of any of the trend lines to get orientation of shape (of course anything which is near 0 mod 90 deg is the same as 0 in case of a square).
Find the length of any of the trend lines (distance from one intersection to the other), and the length of on of it's adjacent (intersecting) lines, these two lengths will be your length and width (or width and height if you like) for size calculation (area, or anything else).
In step 1 you can use many trend line computing algorithms, and it might be worth your time checking a few of them out.
In case all points are sampled into the same collection, you first need to break this collection into the 4 strokes (which is a though task on it's own...tougher task)

Categories