BSP Tree construction - binary-tree

Two objects of seven faces (a, b, c, d, e, f, g) are shown in the figure below. Find a
binary space partitioning tree (BSP tree) that represents the objects (use the left nodes
for those faces in the front and the right nodes for those behind, and choose faces in
the order of a-b-c-d-e-f-g. Split a face if necessary).
I got a BSP Tree like so from Eye 1 - Blue lines indicate in front while red lines indicate behind. Is this correct?

Related

How the Bently-Ottomann algorithm determines the order of segments on sweep line

As much as I have known, the order within the status is determined by the beginning point of segments initially, and changed when the sweep line meets a corresponding intersection.
Let's see the example below. Let the sweep line sweeps from top to bottom, and event queue sorts events from left to right. When the sweep line touches vertex E, it has swept IGAC. If we use the starting point to represent segments, the order of segments within status is CAIG. Also, the intersections K and L have been detected. Then E joins the status and the order becomes CEAIG because the x-coordinate of E is between C and A.
Here is the problem, at the moment the sweep line meets E, since the left and right of E are C and A, the intersections of M and N won't be detected, hence the two event points of intersection won't join the event queue. According to the image, we can see that the next event is L. The order of C and A would change, but E still lies between C and A. Then F, the segment EF will be removed from status. M and N will never be detected.
I think I have followed the routine of the BO algorithm, but the two intersections cannot be detected in this situation. Please tell me where I'm wrong.
When the sweep line gets to E, it has the line segments AB and IJ on the left and right.
In order to determine where to insert E in the tree, you compare it to the points on those lines that are on the sweep line, directly to the left or right of E. You do not compare it to the original points that caused those lines to get inserted into the tree in the first place.
So the x position of each node in the tree changes as the sweep line moves. This is OK -- that only affects the relative ordering of nodes at intersections, and the ordering is fixed up at intersection events.

Merging angled text OCR into lines

I have a text box detection algorithm that outputs word-level detections. Here's an example:
So the output is a list of boxes in the form (x1_i,y1_i,x2_i,y2_i) indicating the bottom-left and top-right coordinates. I'd like to find a simple decent baseline algorithm to merge these boxes into lines. So the desired output would be:
["Hey how are you?" , "I'm great!"]
I've seen a few questions similar to this, but they are primarily about straight (uni-directional) text, e.g.:
Merge the Bounding boxes near by into one
My thoughts on this are to calculate vectors from the centroid of each box, and then doing merging of boxes, based on closeness and near-same direction. I'm wondering if there are any such algorithms already out there? The corner cases that I'd like to try and address are:
Multiple angles of text.
Non-overlapping boxes (like the [I'm] [great!] ones).
Crossing texts at different angles (like the two lines above).
I'd like to find a such a quick-and-easy baseline algorithm using python.
This is the simplest algorithm meeting your criteria that I can think of.
Define a function score(b1, b2) that reflects how likely it is that the word in b1 precedes the word in b2, with lower scores being better (e.g., 0 means that the right edge of b1 is the same as the left edge of b2). For each box b, define pred(b) to be the box b' minimizing score(b', b), and define succ(b) to be the box b' minimizing score(b, b'). Form a graph on the bounding boxes with arcs b->b' such that succ(b) = b' and pred(b') = b. This graph is the disjoint union of some number of simple paths. These are your lines.
I don't know the best way to define score, but one possibility is to define score(b1, b2) = f(distance(midpoint of b1's right side, midpoint of b2's right side) / max(b1's height, b2's height)) + g(angular distance(b1's angle, b2's angle)), where f and g are increasing functions (I'd start the experiments with f and g being linear).
Edit: it occurs that the word bounding box algorithm may only give you a reliable orientation modulo a half rotation. In this case, define score so that it's lower when the two boxes are likelier to precede/succeed one another, form a directed graph where each box has an arc to each of the two boxes with which it has the lowest scores, throw away arcs with no reciprocal arc, form an undirected graph with an edge for each arc pair. The latter graph consists of a disjoint union of paths and cycles. You'll have to figure out what to do with the cycles and how to orient the paths.

Combine Arbitrary number of polygons together

I have an arbitrary number of polygons (hexes in this case) that are arranged randomly, but they are all touching another hex.
Each individual hex has 6 x,y vertices. The vertex's are known for all the hexes.
Can anyone point me in the direction of an algorithm that will combine all the hexes into a single polygon? Essentially I'm just looking for a function that spits out an array of vertex locations that are ordered in a way that when drawing lines from one to the next, it forms the polygon.
This is my method so far:
Create array of all the vertices for all the hexes.
Determine the number of times a vertex occurs in the array
If vertex is in the array 3+ times, delete the vertices from the array.
If vertex is in the array 2 times, delete one of them.
The next step is tricky though. I'm using canvas to draw out these polygons, which essentially involves drawing a line from one vertex to the next. So the order of the vertices in the final array is important. It can't be sorted arbitrarily.
Also, I'm not looking for a "convex hull" algorithm, as that would not draw the polygon correctly.
Are there any functions out there that do something like this? Am I on the right track or is there a better more efficient way?
I would do something like this:
List all the sides. A side is defined by two pairs of coordinates.
If any side shows up more than once remove all instances of that side.
Pick an arbitrary side, and from that side choose one of its points.
Place that point in an array.
Follow the current side and put the other point in the array.
Delete the side you just followed.
Then find the other side that has a point that is the same as the last point in the array. There will be only one such side. If there is none, you're done.
Go back to step 5.
You should now have an array of points that make up, in order, the shape you want.
Just be aware that this won't handle holes. The shape must be defineable by a single path.
without keeping track of the coordinate pairs that make up the lines, it would be impossible to determine the outer border of the shape
if you know the coordinate pairs that make up the lines, THEN
Create 2 lists, one of vertexs (list 1), one of the lines (list 2)
Remove all duplicate vertexes from the vertex list
Make a new list (list 3) of all the vertexes that have 3 lines attached to them
Using list 3, remove all the lines that have 2 vertexes from list 3 as their two coordinate pairs
It's time to traverse the shape, the list of lines remaining should form the shape you want
just start with an arbitrary coordinate and then
for each coordinate
for all lines
if (x1,y1) = current coordinate then add (x2,y2) to stack and remove that line from list
break
elseif (x2,y2) = current coordinate then add (x1,y1) to stack and remove that line from list
break
For each hex you have a list of 6 vertices. Sort the list, if necessary, so that the the vertices are ordered in counter-clockwise order (that's the mathematical convention).
Now you have a set of polygons (initially hexagons). The idea is to combine polygons until there is only one (or as few as can be).
Pick an edge of a polygon, and look for that same edge (i.e. that same pair of vertices) among the other polygons. If there are two instances, combine the two polygons at that edge, e.g. (a, b, c, d, e, f) + (g, h, d, c, i, j) => (a, b, c, i, j, g, h, d, e, f). (If the two vertices are in the same order in both polygons, or if there are three or more instances of the edge, report an error and abort.) Iterate through all edges. If the hexes really formed a contiguous group, there will be only one polygon left.
The polygon may have duplicated edges. If an edge occurs more than once, eliminate it by splitting the list in two, e.g. (a, b, c, d, b, a, e, f, g) => (b, c, d) + (a, e, f, g). Or if the the edges are adjacent, remove them: (a, b, c, b, d, e) => (a, b, d, e). Or if that list has only that edge, remove the list: (a,b) => nothing.
Once you've eliminated duplicate edges, there'll be one list for the counter-clockwise outer edge of the polygon, and perhaps one or more lists for the clockwise interior edges of holes.

K-d trees: nearest neighbor search algorithm

This is my understanding of it:
1. Recurse down the tree, taking the left or right subtree according as whether ELEMENT would lie in the left or the right subtree, if it existed.
2. Set CURRENT_BEST as the first leaf node that you reach.
3. As you recurse back up, check to see whether ELEMENT lies closer to the splitting hyperplane than it does to CURRENT_BEST. If so, set CURRENT_BEST as the current node.
This is the part I got from Wikipedia and my class, and the part I don't understand:
4. Check to see whether any node in the other subtree of the splitting point singled out in 3. is closer to ELEMENT than the splitting point.
I don't see why we need to do 4., since any point that might lie in the one subtree of the splitting node must necessarily be closer to the splitting node than to any point in the other subtree.
It's obviously my understanding of the algorithm that is flawed, so help will be greatly appreciated.
Step 4 is the 'else' in step 3, what you do if the plane is closer than the point. Just because the point you found would be in the same rectangle as the point you are finding the neighbour for doesn't mean that it is the closest.
Imagine the following scenario: you have two points in your kD-Tree, A and B. A is in the middle of its rectangle, while B is just over the edge, in the partitioned area next to that of A. If you now search for the nearest neighbour to point C, which is right next to B but happens to be the other side of the edge and in the partition area of A, your first point you choose will be A due to the initial Depth First Search that chooses whatever would be in the same partition as your search point. However, B is actually closer, so even though you chose A, you need to check whether B is closer otherwise your kD-Tree won't actually give you correct results.
A good way of visualising this is to draw it out:
A-------------C--|--B
A is the first point we found in the DFS, C is our point we want the nearest neighbour of, B is the actual nearest neighbour, | is our split plane.
Another way to think of it is to draw a circle with radius dist(A,C) around point C. If any other rectangles have any portion of themselves fall within this circle, then there is a chance that they hold a point which might be closer to C than A is, so they must be checked. If you now find B, you can reduce the radius of your circle (because B is closer) so that less rectangles have a chance of intersecting, and once you have checked all the rectangles which intersect with your circle (reducing your circle radius as your find closer neighbours) you can definitively say that there are no closer points.
I wrote a basic C++ implementation on github. It has both an iterative and recursive version.
function kdtree (list of points pointList, int depth)
{
// Select axis based on depth so that axis cycles through all valid values
var int axis := depth mod k;
// Sort point list and choose median as pivot element
select median by axis from pointList;
// Create node and construct subtrees
var tree_node node;
node.location := median;
node.leftChild := kdtree(points in pointList before median, depth+1);
node.rightChild := kdtree(points in pointList after median, depth+1);
return node;
}

Anyone know were i could find an algorithm or have a algorithm they could share to split a sphere (mesh) into random parts?

I have a list a vertices and a list of triangles. I'd like to split this single mesh into, say 5, randomly shaped meshes. When the 5 randomly shaped meshes are in place the sphere should all line up and look like 1 solid mesh.
I need a algorithm to do this programmatically, not a tool to do it form me. Any pointers would be great!
Similar to Svante's proposal but a slightly different approach:
Select five random vertices, mark these vertices as "visited" with the number 1 to 5
From each of the visited vertices, go to all adjacent vertices. Store the same number there as well.
If you visit a vertex which already has a number assigned, stop there
Stop, if all vertices are visited. All vertices marked with the same number end up in the same piece
This appears to me to be the simplest to implement, while still resulting in nice puzzle pieces. For added random-ness, you could add a probability, of visiting each adjacent vertex.
Nevertheless, any "too random" approach might result in heavily concave pieces, like very long pieces consisting only of a long strip of single triangles; and pieces with deep ugly thin cuts into them. You should possibly specify another question on how to make nice puzzle pieces (and what nice puzzle pieces are!) if you care for that.
You could make a crack by walking a random walk across the edges, until the number of pieces you want is achieved. If you want to have mostly big pieces, you could modify the randomness of the walk by reducing the attractiveness of edges that are close to an existing crack.
Select 3 random points and split along that plane. What is the problem?
When you split a triangle along a plane you end up in one of two situations: either the plane doesn't intersect either line segments in the triangle or it intersects exactly two line segments. Only triangles that are intersected are interesting.
If you have triangle (A, B, C), with A, B and C being vertices.
Assume that the plane intersects the line segments (A, B) and (A, C) in the points D and E.
Define a vertex, F, between B and C (for example B + (C - B) / 2), but any vertex on the line segment between B and C will do).
Your new triangles are then the following
(A, D, E), (B, D, F), (D, E, F) and (C, E, F)

Resources