I am writing some 2D graphic software. And in my project i used Voronoi algorithm. And result is correct as I expected (Pic 1). Then i want to add some feature on boundary points just like (Pic 2). So i think i need to implement Concave hull on boundary points and then create arcs on it.
Pic 1.
But my concave hull is not working correct because of concavity parameter. What is the best way and best algorithm to transform my software result into Pic 2.
Pic 2.
You can create a b/w bitmap with the concave hull and compare it with every point of the voronoi diagram. I used a php function imagefilledpolygon in my php implementation contour plot:https://cntm.codeplex.com/.
You can also try this answer and reconstruct voronoi edges at the border, usually infinity edges:Colorize Voronoi Diagram.
You should be able to do a walk around the voronoi looking for vertices with only a single adjacent edge (not a bad idea to start with a vertex that has just one adjacent edge). Find the first one, walk to the next one, then connect the edges with an arc, repeat until your back at the first edge. The algorithm should be rather efficient O(N) if the voronoi is structured as a graph.
The walk:
The walk is done by angle-sorting the edges and taking the next clockwise edge to the one you started on.
For example:
If the angles (in degrees) are 40, 50, 60, 70, and the previus edge was in the direction of the 50, then you would follow the 60 or 40 edge (depending on if you've decided to go clockwise or counterclockwise) but you wouldn't follow the 70 regardless as that leads inside rather than sticking to the outside.
Related
Problem
I struggle to split a CanvasRenderingContext2D.quadraticCurveTo() path lengthwise into two colors.
Question (framings)
How can I split the color of a quadratic curve lengthwise?
How can a draw two parallel quadratic curves?
Background
The user must draw a line in an annotation tool and indicate polarity based on the line's color (this convention is predefined and can not be changed). Example:
Current best solution
The user specifies N points through which to draw a smooth line (based on this StackOverflow answer). To split the path, I calculate a perpendicular vector for each subpath, merge them to find the average perpendicular vector for the entire path, and redraw the line twice, once shifted up and once shifted down along the perpendicular.
This approach works fine for most curves:
However, it fails, e.g., for back curving curves:
Next, I would try using a perpendicular gradient as described in this blog. However, the computation seems to be highly inefficient and I would appreciate any hints on how else I could solve this problem.
I'm trying to connect two polygons that are described as DCEL data structure and find it hard to do so at some edge cases where, for example, edges intersect with each other at their interior or overlap each other.
Here's the definition of the problem:
The polygons are of rectangular shape with straight edges (edges at vertices make straight angles)
There are no more than 8 edges that meet at the vertex. The only case where it's possible is that all 4 polygons meet at single vertex (aka 4 rectangles)
It's impossible to have more than 2 edges intersecting in their interior
It's impossible that polygons intersect not on segments. All intersections are done on edges and all of them are mix of overlapping cases or interior intersections
There are no holes in polygons
Dissolving internal faces is not allowed here. Edge in between still must be present
If this helps the polygons are representing imaginary regions enclosed under the imaginary country that's why they meet at edges only.
Here are some examples of polygons:
Case 1:
Overlapping edges
Case 2:
One edge contains another
PS: Right now I'm reading Bergs 'Computational Geometry' and trying to practice in DCEL implementation
PSS: In addition I've read a lot of info across the Internet regarding handling subdivision overlapping, but haven't seen the explanation about how to handle such cases. What I think here is that I need to handle edge removal while Berg does not tell this in his book.
Also extra source: same Berg, but with more fancy images
https://cw.fel.cvut.cz/b201/_media/courses/cg/lectures/09-intersect-split.pdf (p. 26/96)
So after tons of trials and errors I found the solution to my problem. It's not ideal because I still don't know the 'correct' answer on how to split edges when they are neighboring to each other for arbitrary polygon, but have a solution to my problem that I was trying to solve.
According to the algorithm that Berg described in his book edges must be refined using sweep line algorithm. Previous and next edge must be selected in the CCW or CW order (CCW = counter clockwise, CW = clockwise) depending in what direction edge is pointing, but it's hard to do so when you have overlapping edges. Additional complexity here will be that the edge consists of two half edges and it's a nightmare to refine both of them according to simplified algorithm described above. Instead, what we can do here is to forget about two half edges and use only one. It will always have incident face but no twin. In this case overlapping is detected perfectly using sweep line algorithm and polygon stitching becomes straightforward: the overlapping edges become twins to each other when edge refinement is done (splitting edge at the event point in case if edge contains it in the interior). When edge is split the other edge that belongs to another polygon becomes its twin
It looks a bit messy without thorough explanation, but I'll attach image that will show what I mean by that
On the image you can see edges like a2 that gets split into two new edges - a2' and a2'' plus old shrunk a2. Refinement of a2 was done at two points - v5 and v8. Each point is a beginning of the new half edge and the end of previous one. When we have two edges that are ending at a point (it's impossible to have more than 2 edges in my problem) we mark them as twins (b4 and a2'). Resolving next and previous here is really easy.
To bypass the contour of stitched polygon (black lines) you can use info about the twin of next edge. If it has a twin then switch to the twins next edge at next step (next_edge = a2'.twin.next is the same as next_edge = b4.next)
PS: it will not work for case when you have multiple polygons overlapping at the same edge. It's hard to make twins in such case, but it's a question whether the correct solution exists or not?
I have a camera with the coordinates x,y at height h that is looking onto the x-y-plane at a specific angle, with a specific field of view. I want to calculate the 4 corners the camera can see on the plane.
There is probably some kind of formula for that, but I can't seem to find it on google.
Edit: I should probably mention that I mean a camera in the 3D-Graphics sense. Specifically I'm using XNA.
I've had to do similar things for debugging graphics code in 3D games. I found the easiest way of thinking about it was creating the vectors representing the corners of the screen and then calculating the intersection with whatever relevant objects (in this case, a plane).
Take a look at your view-projection (or whatever your Camera's matrix stack looks like multiplied together) and realize the screen space they output to has corners with homogonized coordinates of (-1, -1), (-1, 1), (1, -1), (1, 1). Knowing this, you're left with one free variable and can solve for the vector representing the corner of the camera.
Although, this is a pain. It's much easier to construct a vector for each corner as if the camera isn't rotated or translated and then transform them by the view matrix to give you world space vectors. Then you can calculate the intersection between the vectors and the plane to get your four corners.
I have a day job, so I leave the math to you. Some links that may help with that, however:
Angle/Field of view calculations
Line plane intersection
ignoring lens distortions and assuming the lens is almost at the focal point then you just have a triangle formed by the sensor size and the lens, then the lens to the subject - similar trianlges gives you the size of the subject plane.
If you want a tilted object plane that's just a projection onto the perpendicular object plane
I currently develop an application that creates polygons from lines and I experience a small problem:
I have a set of points, representing a line. I would like to create a polygon that displays the line with a specific width (e.g. for a street). I have several ideas how to calculate the outer polygon points, but I think they are too complicated...
My best idea was the one pictured below: Every point of the line must be projected to at least two points: Both points must be 90° to the following line segment and have a distance half of the preferred polygon width.
This works good, as you can see at the end and start points of the pictured polygon. Now the complicated part: With this method, at a corner, each point gets four points. But these points are not correct for the outer polygon, because they are in the shape. The lines intersected and created an ugly polygon.
How can I find the correct points for such a polygon? I think my method is far too complicated for solving this problem.
Can anybody help me with this (propably very common) problem?
Info: I tagged this with openstreetmap because renderer like Mapnik have this problem, too.
What you are looking for is a polygon (or line) offsetting algorithm. This is not necessarily an easy problem to solve, by the way: An algorithm for inflating/deflating (offsetting, buffering) polygons.
For the last couple of weeks I've been working on a line offsetting algorithm for Maperitive. In my case I only needed to offset the line so I wasn't looking for a solution to create a buffered polygon around it, but I guess the algorithm could be extended further in the future:
Basic flow (roughly, but the devil is in the details):
For each polyline point find a point that has an L distance from the original point and lies on a line that's orthogonal to the original line and goes through the original point.
Now draw an offset line through that new point. The line must be parallel to the original line.
For corner angles you must extend the two neighbouring offset lines and find the intersection point, which will be the next point of the offset line.
Some things to observe:
Notice the miter limit applied on concave angles to the right of the picture.
Before calculating the offset line you need to simplify the original polyline to exclude segments that are too small to hold the offset (the results can be seen at the center left of the picture).
I only implemented support for miter joins, but a good algorithm should be able to render round joins, too (using arcs).
I have an array of thousands of quads; 4-sided 3D polygons. All I know are the coordinates of the quad corners.
A subset of these quads define the closed outer shell of a 3D shape. The remaining quads are on the inside of this closed solid.
How do I figure out which quads are part of the shell and which quads are part of the interior? This is not performance critical code.
Edit: Further constraints on the shape of the shell
There are no holes inside the shape, it is a single surface.
It contains both convex and concave portions.
I have a few points which are known to be on the inside of the shell.
This might be hard to implement if your shape self intersects, but if you can find one quad that you know is on the surface (possibly one furthest away from the centroid) then map out concentric circles of quads around it. Then find a continuous ring of quads outside that and so on, until you end up at the "opposite" side. If your quads intersect, or are internally connected, then that's more difficult. I'd try breaking apart those which intersect, then find all the possible smooth surfaces, and pick the one with the greatest internal volume.
How about this?
Calculate the normal vector of a quad (call this the 'current' quad).
Do an intersection test with that vector and all the remaining quads.
If it intersects another quad in the positive portion of the vector you know the current quad is an internal quad. Repeat for all the remaining quads.
This assumes the quads 'face' outward.
Consider that all of the quads live inside a large sealed box. Pick one quad. Do raytracing; treat that quad as a light source, and treat all other quads as reflective and fuzzy, where a hit to a quad will send light in all directions from that surface, but not around corners.
If no light rays hit the external box after all nodes have had a chance to be hit, treat that quad as internal.
If it's convex, or internal quads didn't share edges with external quads, there are easier ways.
It can be done quite easily if the shape is convex. When the shape is concave it is much harder.
In the convex case find the centroid by computing the average of all of the points. This gives a point that is in the interior for which the following property holds:
If you project four rays from the
centroid to each corner of a quad you
define a pyramid cut into two parts,
one part contains space interior to
the shape and the other part defines
space that might be exterior to the
shape.
These two volumes give you a decision process to check if a quad is on the boundary or not. If any point from another quad occurs in the outside volume then the quad is not on the boundary and can be discarded as an interior quad.
Edit: Just seen your clarification above. In the harder case that the shape is concave then you need one of two things;
A description (parameterisation) of the shape that you can use to choose quads with, or
Some other property such as all of the boundary quads being contiguous
Further edit: Just realised that what you are describing would be a concave hull for the points. Try looking at some of the results in this search page.
You may be able to make your problem easier by reducing the number of quads that you have to deal with.
You know that some of the quads form a closed shell. Therefore, those quads are connected at their edges. If three mutually adjacent edges of a quad (that is, the edges form a closed loop) overlap the edge of another quad, then these quads might be part of the shell (these mutually adjacent edges serve as the boundary of a 2D region; let's call that region the "connected face" of the quad). Make a list of these "shell candidates". Now, look through this list and throw out any candidate who has an edge that does not overlap with another candidate (that is, the edge overlaps an edge of a quad that is not in the list). Repeat this culling process until you are no longer able to remove any quads. What you have left should be your shell. Create a "non-shell quads" list containing all of the quads not in the "shell" list.
Draw a bounding box (or sphere, ellipse, etc) around this shell. Now, look through your list of non-shell quads, and throw out any quads that lie outside of the bounding region. These are definitely not in the interior.
Take the remaining non-shell quads. These may or may not be in the interior of the shape. For each of these quads, draw lines perpendicular to the quad from the center of each face that end on the surface of the bounding shape. Trace each line and count how many times the line crosses through the "connected face" of a quad in your shell list. If this number is odd, then that vertex lies in the interior of the shape. If it is even, the vertex is on the exterior. You can determine whether a quad is inside or outside based on whether its vertices are inside or outside.