Find inner geometry from edges - algorithm

First I am not sure which keywords to use for this and I think I am probably using the wrong ones to google about it, so if someone could give me any hint it would be much appreciated.
My problem is the following:
I need to find the "rooms" inside a house plan. For example take this geometry:
The desired algorithm would tell me which vertexes bound each of the rooms. So for this example it would be:
room A: 1, 2, 9, 10, 3, 4, 5, 8 ,1
room B: 2, 3, 10, 9, 2
room C: 11, 12, 14, 13, 11
room D: 5, 6, 7, 8, 5
I have the vertexes and the edges as input data.
Edit:
The edge data is as follows (edge 8, 1 ,2):
x y
47 196
47 85
258 85
it is in pixel coord.

Graph Theory did not really help me because I have disconnected loops that share information. For example [1 2 9 10 3 4 5 8 1] AND [11 12 14 13 11]. So in the end I ended up doing a image fill, when expanding the boarders of the fill 1 pixel and doing a boolen operation to figure out which vertex are inside the filled image.

This is planar graph. It has V vertices, E edges and F = E - V + 2 faces (including outer face). We have to determine the edge list for all the faces. Every edge will be used twice in these lists (in forward and backward direction).
Create main arc list, add all the arcs (i.e. for 1-2 undirected edge add both 1-2 and 2-1 directed arcs)
Find the lowest vertex point. If there are some such points, choose the leftmost one (7th here).
Travel the outer face (contour) in CCW direction (choose the rightmost outgoing arc at every vertex): 7-6-5-4-3-2-1-7. Remove visited arcs from the main list.
Get any arc from the main list, travel the first inner face, follow the right-hand rule (i.e. 7-8-5-6-7), remove visited arcs.
Repeat until the main list is empty.
Repeat all the procedure for disconnected components (11-12-13-14)

One of possible solutions is to triangulate this area so that every input edge is an edge of some triangle. Then split triangles into connected sets and find their border.
There are several algorithms for triangulation: ear-clipping, Delaunay, ...

Related

Given a continuous graph. Find the number of intersections by a line segment in log(n)

Given an array, example : Arr[1 3 4 4 7 8 6 8 6 4 2], where 10^10>Arr[i]>0, which represents y co-ordinate. x co-ordinate is their corresponding Array index. A continuous graph is formed by joining (i,Arr[i]) and (i+1,Arr[i+1), and so on. So basically it is a graph formed by joining straight lines. Given a line segment parallel to y-axis from x-range (x1 to x2). If given line segment passes through an intersection point, then we count that as 2 intersections except when the left endpoint of intersecting line is (x2,y) or its right endpoint is (x1,y), then we count that as 1 intersection only. Can we find the number of intersections by this line segment log(n) time ?
This is from an ongoing contest. Wait one more day for the editorials.

What is the logic behind calculating diagonals on a chessboard?

Given the position of a Bishop on an 8 * 8 chessboard, the task is to count the total number of squares that can be visited by the Bishop in one move. The position of the Bishop is denoted using row and column number of the chessboard.
Examples:
Input: Row = 4, Column = 4
Output: 13
Input: Row = 1, Column = 1
Output: 7
Approach: In the game of chess, a Bishop can only move diagonally and there is no restriction in distance for each move.
So, We can also say that Bishop can move in four ways i.e. diagonally top left, top right, bottom left and bottom right from current position.
We can calculate the numbers of squares visited in each move by:
Total squares visited in Top Left move = Math.min(r, c) – 1
Total squares visited in Top Right move = Math.min(r, 9 – c) – 1
Total squares visited in Bottom Left move = 8 – Math.max(r, 9 – c)
Total squares visited in Bottom Right move = 8 – Math.max(r, c)
where, r and c are the coordinates of the current position of the Bishop on the chessboard.
Guys I cannot figure out the logic behind the above diagonal calculations. Please help me find out that by what logic the diagonals are calculated above ??? I JUST NEED THE LOGIC. No code required.
( Also If you can help with the basic behind logic of similar kinds of chess problems or matrix it would be fantastic)
Chessboard image for reference
The top-left distance to the edge of the board is indeed min(r, c) - 1. Given that the bishop starts on rank r, it can move up no more than r - 1 ranks before landing on the first rank. It may hit the first file before that if c < r, in which case it will only be able to move c - 1 squares. For example if the bishop starts at r = 5 and c = 4, it will be able to move three squares, not four. Thus the top-left formula is min(r - 1, c - 1), which can be refactored to min(r, c) - 1.
Similarly, when heading towards the bottom-left corner, the rank increases while the file decreases. The bishop can move at most 8 - r ranks and at most c - 1 files, so the bottom-left formula is min(8 - r, c - 1). That can be refactored to 8 – max(r, 9 – c), although this expression seems more convoluted.
To count elements in the left-top and right-bottom sides of the diagonal (in which Bishop is placed), the following formula is enough:
n-abs(r-c)-1, where n is the size of the board e.g. n=8 in the above case.
So three (instead of four) formulae can give all the cells that Bishop can visit diagonally:
[8-abs(r-c)-1] + [Math.min(r, 9 – c) – 1] + [8 – Math.max(r, 9 – c)]
simply apply this formula for any directions: distance = max(abs(x1 - x2), abs(y1 - y2))

How to rotate in red black tree

I'm trying to solve this exercise with red black tree: I need to insert 2, 1, 4, 5, 9 in this order. After the last input I need to balance it with the Insert-Fixup algorithm:
The part of the algorithm I need to follow is:
if z == z.p.right
z = z.p
LEFT-ROTATE (T, z)
z.p.color = BLACK
z.p.p.color = RED
RIGHT-ROTATE (T, z.p.p)
(Z is the node I want to insert) and z.p is its father. So I tried to follow the steps until the left rotation and this is the result: is it right?
I searched on internet and I read that there are double rotation algorithm, but I cannot figure out if I can use them here instead of using the single rotation (for example I don't know hot to right rotate the node with the 4).
You are following the wrong case. I have explained the answer in the following steps. In the last step, i.e. inserting 9, we have to do left-rotate(4) and recoloring.
Following is the pic in which I have explained the steps:

Algorithm: How to find positions on a traced line or curve?

Given a traced line or curve (say a mouse tracing app in which you can draw any uninterrupted line or curve), I would like to place points of equi-distance on that line or curve (the number of points placed can be varied). What's the best way to go about doing this?
I recommend using a Centripetal Catmull-Rom spline.
http://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline
Catmull-rom curve with no cusps and no self-intersections
This lets you use the original "points" that the user either clicks or that you pick up during various mouse move events. You still need to add just two points on the end that control the initial and final directions of the line.
The reason to use Centripetal Catmull-Rom instead of the regular one is to avoid self-intersections and cusps, which are undesirable loops on the line itself.
The original Catmull-Rom parameterizes the distance along the curve as t. Since any segment of the curve uses the point preceeding the segment, and the point following the segment, the coordinate for any point between the middle two points can be interpolated by just passing a parameter t into the equation ranging from 0 to 1, with 0 equating to P1, and 1 being P2, where the four control points are P0, P1, P2, and P3.
The modified versions of the Catmull-Rom play with the positioning between the control points. It still uses the same 4 control points, and still takes in a t value that you can use to get your answer, but t no longer ranges from 0 to 1 extending between P1 and P2. Instead, the value you use for t will depend on the euclidean distances.
So, as an example of the Centriptal case, lets say I have 4 control points, and the segment distances are 4, 9 and 16. I will actually be using the square root of the distances, so the t values of the control points will be:
UNIFORM CHORDAL CENTRIPETAL
T0 = 0 0 0
T1 = 1 4 Sqrt(4) = 2
T2 = 2 4 + 9 = 13 2 + Sqrt(9) = 5
T3 = 3 13 + 16 = 29 5 + Sqrt(16) = 9
And then to interpolate between P1 and P2, I would pick a t value evenly spaced between T1 and T 2, which in the Centripetal case is 2 and 5.

An algorithm to solve a simple(?) array problem

For this problem speed is pretty crucial. I've drawn a nice image to explain the problem better. The algorithm needs to calculate if edges of a rectangle continue within the confines of the canvas, will the edge intersect another rectangle?
We know:
The size of the canvas
The size of each rectangle
The position of each rectangle
The faster the solution is the better! I'm pretty stuck on this one and don't really know where to start.
alt text http://www.freeimagehosting.net/uploads/8a457f2925.gif
Cheers
Just create the set of intervals for each of the X and the Y axis. Then for each new rectangle, see if there are intersecting intervals in the X or the Y axis. See here for one way of implementing the interval sets.
In your first example, the interval set on the horizontal axis would be { [0-8], [0-8], [9-10] }, and on the vertical: { [0-3], [4-6], [0-4] }
This is only a sketch, I abstracted many details here (e.g. usually one would ask an interval set/tree "which intervals overlap this one", instead of "intersect this one", but nothing not doable).
Edit
Please watch this related MIT lecture (it's a bit long, but absolutely worths it).
Even if you find simpler solutions (than implementing an augmented red-black tree), it's good to know the ideas behind these things.
Lines that are not parallel to each other are going to intersect at some point. Calculate the slopes of each line and then determine what lines they won't intersect with.
Start with that, and then let's see how to optimize it. I'm not sure how your data is represented and I can't see your image.
Using slopes is a simple equality check which probably means you can take advantage of sorting the data. In fact, you can probably just create a set of distinct slopes. You'll have to figure out how to represent the data such that the two slopes of the same rectangle are not counted as intersecting.
EDIT: Wait.. how can two rectangles whose edges go to infinity not intersect? Rectangles are basically two lines that are perpendicular to each other. shouldn't that mean it always intersects with another if those lines are extended to infinity?
as long as you didn't mention the language you chose to solve the problem, i will use some kind of pseudo code
the idea is that if everything is ok, then a sorted collection of rectangle edges along one axis should be a sequence of non-overlapping intervals.
number all your rectangles, assigning them individual ids
create an empty binary tree collection (btc). this collection should have a method to insert an integer node with info btc::insert(key, value)
for all rectangles, do:
foreach rect in rects do
btc.insert(rect.top, rect.id)
btc.insert(rect.bottom, rect.id)
now iterate through the btc (this will give you a sorted order)
btc_item = btc.first()
do
id = btc_item.id
btc_item = btc.next()
if(id != btc_item.id)
then report_invalid_placement(id, btc_item.id)
btc_item = btc.next()
while btc_item is valid
5,7,8 - repeat steps 2,3,4 for rect.left and rect.right coordinates
I like this question. Here is my try to get on it:
If possible:
Create a polygon from each rectangle. Treat each edge as an line of maximum length that must be clipped. Use a clipping algorithm to check weather or not a line intersects with another. For example this one: Line Clipping
But keep in mind: If you find an intersection which is at the vertex position, its a valid one.
Here's an idea. Instead of creating each rectangle with (x, y, width, height), instantiate them with (x1, y1, x2, y2), or at least have it interpret these values given the width and height.
That way, you can check which rectangles have a similar x or y value and make sure the corresponding rectangle has the same secondary value.
Example:
The rectangles you have given have the following values:
Square 1: [0, 0, 8, 3]
Square 3: [0, 4, 8, 6]
Square 4: [9, 0, 10, 4]
First, we compare Square 1 to Square 3 (no collision):
Compare the x values
[0, 8] to [0, 8] These are exactly the same, so there's no crossover.
Compare the y values
[0, 4] to [3, 6] None of these numbers are similar, so they're not a factor
Next, we compare Square 3 to Square 4 (collision):
Compare the x values
[0, 8] to [9, 10] None of these numbers are similar, so they're not a factor
Compare the y values
[4, 6] to [0, 4] The rectangles have the number 4 in common, but 0 != 6, therefore, there is a collision
By know we know that a collision will occur, so the method will end, but lets evaluate Square 1 and Square 4 for some extra clarity.
Compare the x values
[0, 8] to [9, 10] None of these numbers are similar, so they're not a factor
Compare the y values
[0, 3] to [0, 4] The rectangles have the number 0 in common, but 3 != 4, therefore, there is a collision
Let me know if you need any extra details :)
Heh, taking the overlapping intervals answer to the extreme, you simply determine all distinct intervals along the x and y axis. For each cutting line, do an upper bound search along the axis it will cut based on the interval's starting value. If you don't find an interval or the interval does not intersect the line, then it's a valid line.
The slightly tricky part is to realize that valid cutting lines will not intersect a rectangle's bounds along an axis, so you can combine overlapping intervals into a single interval. You end up with a simple sorted array (which you fill in O(n) time) and a O(log n) search for each cutting line.

Resources