Best data structure & packages to represent geometric units on a grid - graph

I want to write a program with 'geometry automata'. I'd like it to be a companion to a book on artistic designs. There will be different units, like the 'four petal unit' and 'six petal unit' shown below, and users and choose rulesets to draw unique patterns onto the units:
I don't know what the best data structure to use for this project is. I also don't know if similar things have been done and if so, using what packages or languages. I'm willing to learn anything.
All I know right now is 2D arrays to represent a grid of units. I'm also having trouble mathematically partitioning the 'subunits'. I can see myself just overlapping a bunch of unit circle formulas and shrinking the x/y domains (cartesian system). I can also see myself representing the curve from one unit to another (radians).
Any help would be appreciated.
Thanks!!

I can't guarantee that this is the most efficient solution, but it is a solution so should get you started.
It seems that a graph (vertices with edges) is a natural way to encode this grid. Each node has 4 or 6 neighbours (the number of neighbours matches the number of petals). Each node has 8 or 12 edges, two for each neighbour.
Each vertex has an (x,y) co-ordinate, for example the first row in in the left image, starting from the left is at location (1,0), the next node to its right is (3,0). The first node on the second row is (0,1). This can let you make sure they get plotted correctly, but otherwise the co-ordinate doesn't have much to do with it.
The trouble comes from having two different edges to each neighbour, each aligned with a different circle. You could identify them with the centres of their circles, or you could just call one "upper" and the other "lower".
This structure lets you follow edges easily, and can be stored sparsely if necessary in a hash set (keyed by co-ordinate), or linked list.

Data structure:
The vertices can naturally be stored as a 2-dimensional array (row, column), with the special characteristic that every second column has a horizontal offset.
Each vertex has a set of possible connections to those vertices to its right (upper-right, right, or lower right). The set of possible connections depends on the grid. Whether a connection should be displayed as a thin or a thick line can be represented as a single bit, so all possible connections for the vertex could be packed into a single byte (more compact than a boolean array). For your 4-petal variant, only 4 bits need storing; for the 6-petal variant you need to store 6 bits.
That means your data structure should be a 2-dimensional array of bytes.
Package:
Anything you like that allows drawing and mouse/touch interaction. Drawing the connections is pretty straightforward; you could either draw arcs with SVG or you could even use a set of PNG sprites for different connection bit-patterns (the sprites having partial transparency so as not to obscure other connections).

Related

Efficiently find a border around a binary group of points

This is more of a mathematical question.
I have a list of 2D coordinates of length N. (Nx2 list)
The coordinates are rounded numbers and form a region. The following is an example:
enter image description here
What I would like is to have a border around these points. Like the following:
enter image description here
One option to do this is to
go through the list, and for each coordinate i
check for the 8 possible neighbours j to see
if this point doesn't overlap with given coordinates k .
if this point doesn't overlap with already found border coordinates
This works well, nut needs N*N*8 calculations. For my N=1000 points: 8 million!
Does anyone know how this could be done more efficient?
Best regards,
Martin
If the size of the grid is constrained and is on the order of N as well, you could do better and get to O(N) by making a 2-D array of ints the size of the grid.
Initialize the grid to zeros.
For each point in the list of points, set the point itself to negative in the grid array and set each neighbor that isn't negative to positive.
When you're done, each point in the 2-D grid array that's positive is the border.
Make a sorted container that enforces uniqueness (in c++ STL, that's a std::set) of coordinates. Go through the points, adding each point's eight neighbors to the set if they aren't already in there. Then go though the points a second time, subtracting them from the set if they are in the set. The points that remain are the border. That's O(N*log(N)). In general that's the best you can do. But see my other answer for a better algorithm if additional criteria exist.

How to test of 2 sets of planes (each defining a volume in 3d space) overlap?

To take a simple example, say there is 2 bounding boxes (not necessarily axis aligned), each defined by 6 planes.
Is there a good way to determine if the volumes defined by each set of planes overlap?
(Only true/false, no need for the intersecting volume).
A solution to this problem, if its general should be able to scale up to many sets of planes too.
So far the solutions I've come up with basically rely on converting each set of planes into geometry - (vertices & polygons), then performing the intersection as you would if you have to intersect any 2 regular meshes. However I was wondering if there was a more elegant method that doesn't rely on this.
The intersection volume (if any) is the set of all points on the right side of all planes (combined, from both volumes). So, if you can select 3 planes whose intersection is on the right side of all the remaining planes, then the two volumes have an intersection.
This is a linear programming problem. In your case, you only need to find if there is a feasible solution or not; there are standard techniques for doing this.
You can determine the vertices of one of your bodies by mutually intersecting all possible triples that its planes form, and then check whether each of the resulting vertices lies on the good side of the planes defining the second body. When each of the second body's planes is given as base vertex p and normal v, this involves checking whether (x-p).v>=0 .
Assume that your planes are each given as base vertices (p,q,r) and normals (u,v,w) respectively, where the normals form the columns of a matrix M, the intersection is x = inv(M).(p.u, q.v, r.w).
Depending on how regular your two bodies are (e.g. parallelepipeds), many of the dot products and matrix inverses can be precomputed and reused. Perhaps you can share some of your prerequisites.
Posting this answer since this is one possible solution (just from thinking about the problem).
first calculate a point on each plane set (using 3 planes), and simply check if either of these points is inside the other plane-set.This covers cases where one volume is completely inside another, but won't work for partially overlapping volumes of course.
The following method can check for partial intersections.
for one of the sets, calculate the ray defined by each plane-plane pair.
clip the each of these rays by the other planes in the set, (storing a minimum and maximum value per ray).
discard any rays that have a minimum value greater then their maximum.The resulting rays represent all 'edges' for the volume.
So far all these calculations have been done on a single set of planes, so this information can be calculated once and stored for re-use.
Now continue clipping the rays but this time use the other set of planes, (again, discarding rays with a min greater then the maximum).
If there are one or more rays remaining, then there is an intersection.
Note 0): This isn't going to be efficient for any number of planes, (too many On^2 checks going on). In that case converting to polygons and then using more typical geometry tree structures makes more sense.
Note 1): Discarding rays can be done as the plane-pairs are iterated over to avoid first having to store all possible edges, only to discard many.
Note 2): Before clipping all rays with the second set of planes, a quick check could be made by doing a point-inside test between the plane-sets (the point can be calculated using a ray and its min/max). This will work if one shape is inside another, however clipping the rays is still needed for a final result.

How do you Uniquely Identify a line segment?

I'm working on a problem to eliminate common line segments in a collection of Paths. Many of these paths share the same segment.
It seems that a 2D line would have some way to uniquely identity itself. Like a Key.
So a Line [(A,B), (C,D)] is the same as [(C,D), (A,B)]
Only Solution I could come up with is to sort the points.
This seems like it would be a common problem in Math or Graphics but the solution escapes me.
From a mathematical point of view, this looks like a matter of an undirected graph (as opposed to a directed graph).
Sorting the points is one way to handle this: it's a straightforward way to represent an unordered edge with a single, unambiguously selected value (it shouldn't matter what ordering you choose, as long as it is consistent for all possible segments). You do need to ensure that you maintain this ordering as an invariant: accidentally slipping in a mis-ordered edge could cause problems for anything that depends on the ordering.
However, mathematically speaking, undirected graphs are often defined as directed graphs with a symmetry property: if (A,B) is an edge, then so is (B,A). This suggests another way: ensure that you always store both (A,B) and (B,A). Perhaps both segment orderings could have a link to any common data, and possibly a fast way to access one from the other. (As with the sorted point method, you need to maintain this symmetry as an invariant.)
The best choice depends on your application. If you're using your segments as a key, the sorting method might be best. However, some applications are a better match for the symmetric method. For example, the doubly connected edge list is a data structure which represents each edge as two linked "half-edges", one in each direction.
Since you mention graphics, note that the doubly connected edge list is often used to represent the edges of 3-D polytopes.
Also, note the similarity to oriented triangles: there are good, practical reasons for computer graphics to treat triangles as "one-sided", such that drawing a triangle visible from one side is distinct from drawing the same triangle visible from the other. Like half-edges, this distinction is determined by the order of the vertices: clockwise for one side, counterclockwise for the other.

Computing the area of a complex (self-intersecting) polygon

I'm making a program that selects an area within a canvas by clicking a sequence of points. The points clicked are linked by some lines this way: every new point is linked with the first and the last ones. I'm looking for an algorithm that computes the area of the resulting polygon.
Intersections are allowed, and here is the complexity, so the algorithm must manage this case by finding the polygon according to the ordered sequence of points clicked and calculating its area.
After many searches, the best I've found is this http://sigbjorn.vik.name/projects/Triangulation.pdf, but I would need something easier to implement in Processing.js.
First cut the line segments where they intersect. If the input set is small, you can simply check every pair. Otherwise use an R-Tree. Then compute a constrained (Delaunay) Triangulation. Then determine the inner triangles using rayshooting and sum up their areas.
hth

Rendering massive amount of data

I have a 3D floating-point matrix, in worst-case scenario the size could be (200000x1000000x100), I want to visualize this matrix using Qt/OpenGL.
Since the number of elements is extremely high, I want to render them in a way that when the camera is far away from the matrix, I just show a number of interesting points that gives an approximation of how the matrix look like. When the camera gets closer, I want to get more details and hence more elements are calculated.
I would like to know if there are techniques that deals with this kind of visualization.
The general idea is called level-of-detail rendering and is a whole science in itself.
For your domain i would recommend two steps:
1) Reduce the number of cells by averaging (arithmetic-mean function) them in cubes of different sizes and caching those cubes (on disk as well as RAM). "Different" means here, that you have the same data in multiple sizes of cubes, e.g. coarse-grained cubes of 10000x10000x10000 and finer cubes of 100x100x100 cells resulting in multiple levels-of-detail. You have to organize these in a hierarchical structure (the larger ones containing multiple smaller ones) and for this i would recommend an Octree:
http://en.wikipedia.org/wiki/Octree
2) The second step is to actually render parts of this Octree:
To do this use the distance of your camera-point to the sub-cubes. Go through the cubes and decide to either enter the sub-cube or render the larger cube by using this distance-function and heuristically chosen or guessed threshold-values.
(2) can be further optimized but this is optional: To optimize this rendering organize the to-be-rendered cube's into layers: The direction of the layers (whether it is in x, y, or z-slices) depends on your camera-viewpoint to which it should be near-perpendicular. Then render each slice into a texture and voila you only have to render a single quad with that texture for each slice, 1000 quads are no problem to render.
Qt has some way of rendering huge number of elements efficiently. Check the examples/demo that is part of QT.

Resources