Family Tree display - algorithm

I am creating a family tree program. My question is how do i position the nodes? Originally i positioned the root at the center of my screen and it works fine if it is a perfect binary tree and the levels are very less. However it is not most often the case. This is a sample tree :-
A
B C
D E F I J
K L N O
As you can see, the main problem is regarding the position of the nodes. If a node has many childs and it's adjacent node also has many children, they tend to overlap.(MAIN PROBLEM) I am using absolute positioning of the node using Canvas in Silverlight. You may not bother with the Silverlight and Canvas part if you are not a Silverlight developer. I just need the logic of how to position the nodes.
The height of the tree can be computed fairly easily by knowing the total number of levels of tree but the width of the tree is what is troubling me. How can i calculate the width of the tree (total width of the canvas)
Can somebody give me some general guidelines regarding how to set the width of the canvas and what logic will work perfect for the positioning of the nodes.
NOTE :- I am not asking for the whole algorithm and it is not my homework. I already have the algorithm and database. I just need guideline for the positioning part of the node.
Thanks in advance :)

If you implement a function: width(node) for arbitrary node of this tree, it is easy to positioning each node
This function may be defined recursively:
- for a tree of height 1 it tree this is exactly length of this node
- for a tree of height bigger than 1 this is a sum of lengths of all direct children of this node (plus some spaces between those)

I would recommend starting with the widest level of the tree if you want to guess the width of the canvas. You can calculate by traversing the tree breadth-first. Multiply the number of nodes at that level by the amount of lateral space each node needs and you have the width of canvas you require.
However, that's no guarantee that adjacent nodes on the widest level won't each have many children. So, to perform spacing with no overlap, start by positioning the leaves of the tree at the deepest level and traverse the tree backwards, adding parents above and putting leaves into the gaps and at the sides.

I would suggest to give zoom in and zoom out functionality to unclutter the GUI Real Estate.
A Node with many children can be grouped and a special icon to denote it can be zoomed in to next level would be good i feel, as the family grows, as user can get big picture at first and as then can zoom into any branch he wishes too.
Take cues from google map's UI, might help.

Related

Algorithm to fill out a monochrome area - ideas?

I am looking for an algorithm which pretty much does the same as flood-fill, which is fill out a monochrome area. Instead of the recursion and the nearest-Neighbor approach i want the algorithm to be some sort of "turtle" or "mouse" that fills out the image, while leaving a path behind. This path must not contain diagonal movements. The result should be similar to a perfect Snake Game, where the entire square is filled (the snake represents the path in this case). It can cross its own path but that amount should be kept to a minimum and it should only occur in special cases (e.g: when the "mouse" enters a passage of width = 1px, where it would fill that passage out and turn around).The amount of changes in direction it takes should also be kept at a minimum.
P.S: not that this will be applied on an image, not a graph
I would model this as a graph problem where you are trying to visit all the nodes in the graph. Each pixel is a node and an edge exists between nodes that are directly next to each other.
I believe that creating an algorithm in which is a variation of a breadth first search on a graph modeled like this would achieve the result you were looking for. Ensuring that you do not visit nodes twice.
You would need to delve deeper into the implementation of the breadth first search in order to make sure it prefers a 'straight' path. Possibly when writing the breadth first search logic, create an is_straight() which checks the next node to see if it's straight or not, and prefer the straight node and only pick a non straight node when is_straight() returns false on all the child nodes.

Tree that contains points - improvement needed

Currently, I'm making my own structure that holds points in 2D space. I know that there are many ready-made algorithms and kind of trees but I want to have something lightweight. So I have (x, y) point that is inside of each node, each node contains 4 children: topLeft, topRight, botLeft, botRight next node.
Inserting:
Every new node is inserted depends on its position.
If the tree is empty, insert the new node / If the tree is not empty, go to the first node and do:
1. Decide what is the position of the current node in regard of the new node.
2. If it is e. g. topLeft and it is not occupied then insert the new node.
3. If position topLeft is occupied go to this node and repeat.
Removing:
The structure I need does not need to have "removing particular node" function, so if the job is done the destructor deletes the whole tree recursively.
Check if the node is inside of particular area:
If the tree is not empty go the first node and then:
1. Check if given area's x is less than node's x and area's y is less than node's y if it is then go to the topLeft children node (if it exists).
2. The same for the topRight (check area's x + width position and y).
3. The same for botRight (check area's x + width and y + height).
4. The same for botLeft (check area's x and y + height).
5. Check if current node is inside of area if it is do stuff you want to do with a point. Recursively go back and repeat.
That's how my structure looks like, the image shows which bonds would be checked for particular area (orange color):
link
My question is, is there is a better algorithm? What Can I improve? I saw quadtree but it seems to be different and it contains more data. I need something that can easily hold moving objects in 2D. I appreciate your help.
What you have is basically a quadtree, but you use your data for doing splits instead of the typical middle.
You can improve the system a bit by switching to a KD tree. It's similar except at each point you split along a single dimension. The main difference is that you only have two pointers per node (instead of 4) so you save about half the memory.
Another thing is that you split your space until you get to 1 point. Because modern CPUs do really fancy things, for small values, linear search will be faster than traversing the tree. So I would only split a space when you have 50-100 points already in there. This will also save a bunch of pointers that don't need to stored at all.
If you know something about the distribution of your points you might be able to do something better. If the distribution is kinda uniform you can simply chunk your space into uniform cells and store the points in the associated cells. A rule of thumb says if you have N points you should have sqrt(N) cells, but you should try and see what works best.

Algorithm placing nodes in 2D - Diagram Creation

Is there an unlicensed algorithm for placing nodes/vertices in a compact, clear way, with nodes being close to each other without overlapping and having short edges and those with many links not being all in the center etc, i.e. all that matters in a good diagram?
In other words, how do I isomorph a graph in the most clearly arranged position?
Oh, and the nodes are rectangles (as I said, it's for a diagram) can differ in size depending on their content

Suggestions on speeding up edge selection

I am building a graph editor in C# where the user can place nodes and then connect them with either a directed or undirected edge. When finished, an A* pathfinding algorithm determines the best path between two nodes.
What I have: A Node class with an x, y, list of connected nodes and F, G and H scores.
An Edge class with a Start, Finish and whether or not it is directed.
A Graph class which contains a list of Nodes and Edges as well as the A* algorithm
Right now when a user wants to select a node or an edge, the mouse position gets recorded and I iterate through every node and edge to determine whether it should be selected. This is obviously slow. I was thinking I can implement a QuadTree for my nodes to speed it up however what can I do to speed up edge selection?
Since users are "drawing" these graphs I would assume they include a number of nodes and edges that humans would likely be able to generate (say 1-5k max?). Just store both in the same QuadTree (assuming you already have one written).
You can easily extend a classic QuadTree into a PMR QuadTree which adds splitting criteria based on the number of line segments crossing through them. I've written a hybrid PR/PMR QuadTree which supported bucketing both points and lines, and in reality it worked with a high enough performance for 10-50k moving objects (rebalancing buckets!).
So your problem is that the person has already drawn a set of nodes and edges, and you'd like to make the test to figure out which edge was clicked on much faster.
Well an edge is a line segment. For the purpose of filtering down to a small number of possible candidate edges, there is no harm in extending edges into lines. Even if you have a large number of edges, only a small number will pass close to a given point so iterating through those won't be bad.
Now divide edges into two groups. Vertical, and not vertical. You can store the vertical edges in a sorted datastructure and easily test which vertical lines are close to any given point.
The not vertical ones are more tricky. For them you can draw vertical boundaries to the left and right of the region where your nodes can be placed, and then store each line as the pair of heights at which the line intersects those lines. And you can store those pairs in a QuadTree. You can add to this QuadTree logic to be able to take a point, and search through the QuadTree for all lines passing within a certain distance of that point. (The idea is that at any point in the QuadTree you can construct a pair of bounding lines for all of the lines below that point. If your point is not between those lines, or close to them, you can skip that section of the tree.)
I think you have all the ingredients already.
Here's a suggestion:
Index all your edges in a spatial data structure (could be QuadTree, R-Tree etc.). Every edge should be indexed using its bounding box.
Record the mouse position.
Search for the most specific rectangle containing your mouse position.
This rectangle should have one or more edges/nodes; Iterate through them, according to the needed mode.
(The tricky part): If the user has not indicated any edge from the most specific rectangle, you should go up one level and iterate over the edges included in this level. Maybe you can do without this.
This should be faster.

Trying to understand Quadtree concept and apply it to storing coloring info of an image

I've read so many articles, but none seem to answer this question. Or maybe I'm just not understanding. I'm attempting to build a quadtree so that it can represent an image. The leaf nodes are to hold pixels, and non-leaf nodes will hold the average value pixel of its children.
My question is:
How does it work that the leaf nodes only hold pixels? Why don't the other nodes hold pixels? And how do we know how many times to subdivide our original root node to represent that given image? Do we just subdivide it n times, where n is the height and width (for a square)?
Edit: So how do I keep track of leaf nodes, so I know when to add pixels at that location? Right now I have a helper function that divides the regions for me, keeping track of width and height.
Quadtrees work best for square images whose size is a power of 2 (for example, most textures). You shouldn't think of each node as representing a "pixel". Instead, think of it as representing a "square block of pixels of size 2^k". In the case of final leaves, k is 0, so each leaf node represents a square block of pixels of size 1, that is, a single pixel. Internal nodes in the tree represent increasingly large sections of image.
Why do only leaf nodes hold pixels? Ask yourself if a non-leaf node held a pixel, then what would its children hold? Since you can't subdivide a pixel, the answer is obviously nothing -- there can be no such nodes.
How do we know how many times to subdivide? Well, there are multiple ways to do it, of course, depending on why you're building the quadtree. In general, the areas of the image with more entropy -- more "detail" -- should be subdivided more, while the lower-entropy, "flatter" areas can be divided less. There are a number of different algorithms for choosing when and where to subdivide. Generally, they compare pixel values within a region, and split when the differences are above some threshold.
how does it work that the leaf nodes
only hold pixels? Why dont the other
nodes hold pixels?
This depends on what you're using the Quadtree for. You can link any kind of information to the other nodes, f.e. a pointer to the upper-left corner and the width/height of the rectangle this node describes, but you won't need it in most cases (or need things like the average values you can precompute to speed things up).
And how do we know how many times to
subdivide our original root node to
represent that given image?
With every subdivision, you half the width and height of a region, so for a square image of size n you'll need to subdivide log2(n) times, for a non-square image of size n*m you'll need at most max(log2(n), log2(m)) steps.
I think the best way to answer your question is to answer two questions that you didn't ask.
What is a quadtree?
How can this be
applied to modelling systems of
erratic density?
A quadtree is a binary tree in two dimensions. That's why there are (up to) four children for every non-leaf node. This allows you to apply an index to a plane just as a database uses a binary-tree or some variation thereof to index a single dimension, with the same highly advantageous sparse phase space representation properties.
The application of this to image compression and progressive display is pretty obvious: if you do a tree-walk limited to a depth of n then you get 4^n items of picture info spanning the entire image space. If you one level deeper, each pixel splits into four. JPEG2000 works like this, if I recall correctly. I said "items of picture info" because they need not be single bit; items could be 32bit ARGB or any other property (or properties) describing the space at that point.

Resources