Contour lines drawing in Java with a given Delaunay triangulation - java

I'm currently working on my master's thesis where I get:
A Delaunay triangulation drawn for me with given n points in (x, y, z) form.
My task is to use this triangulation and make contour lines at given z values.
I have been nearly successful at doing this by implementing the wikipedia spline interpolation : https://en.wikipedia.org/wiki/Spline_interpolation
My problem is that I get contour lines crossing each other when implementing the splines while of course the linear drawings doesn't cross.
Parametric cubic spline interpolated contour lines
If you look at the bottom part of the screen you see two contour lines crossing, I don't have enough reputation points to show that the linear drawings doesn't. You can also see that from point to point that the edges are way too rounded.
What I've tried is to interpolate more points between any pair of points to make more knot points along the lines, this to restrict them further, but to get non-crossing lines the splines look too much like a linear drawing which isn't satisfactory to the eye.
What I'd like to know, is not actual code implementation of the how, but maybe a pointer to how, readings and so forth.
(NB, I'm going to make this from scratch, no libraries).
Question: How to make a higher degree polynomial function which doesn't curve too much outside its linear counterpart. By too much I mean that a given contour at let's say 50 meters, that it doesn't cross a contour at 60 meters.
Any help is highly appreciated.

You can try a weighted delaunay triangulation. It's defined as the euklidian distance minus the weight.

Couples of years ago I solved similar task.
Here are some of my working notes. Probably it would help you.
Refer to XoomCode AcidMaps plugin, on github:
https://github.com/XoomCode/AcidMaps/tree/master/examples/isolines
Here is a demo:
http://ams.xoomcode.com/flex/index.html
Set, for example, the renderer type "Sparse" and interpolation strategy as "Linear", then press the "Update" button.
Refer to VividSolutions JTS Java library:
http://www.vividsolutions.com/jts/download.htm
http://mike.teczno.com/notes/curves-through-points.html
http://blog.csdn.net/xsolver/article/details/8913390

Related

link points with a smooth curve

I am trying to find an algorithm to draw a smooth curve passing through n points in Java.
I read a lot about the subject, but I only find examples with 3 or 4 points. I don't get how I am supposed to generalize the process with more points.
For instance, I found that answer that shows how to make a Bezier curve with 3 points. But if I repeat the process with the 3 next points, the 2 curves will not join smoothly.
I also found this interesting pdf that describes in details the process. The part I'm interested in is the 5th chapter about interpolation by cubic splines. It explains how to achieve what I want, but for 6 points. There isn't a generalization for n points.
If you see an easier approach, I would gladly take it. I just don't want Lagrange interpolation. As shown in the linked pdf, it doesn't give good results...
You can find both short introduction into cubic splines and good practical implementation in this chapter of the book Numerical Methods in C.
You can also use Catmull-Rom splines (they provide smoothness only for the first derivative)
One more simple approach for interpolation with Bezier curves proposed by Maxim Shemanarev
You did not mention what means smooth for you (what continuity c0,c1,c2...?) but in most cases for visual smoothness cubics are enough (4 point curves).
If you want your curve going through all the points then you want interpolation instead approximation so BEZIER/SPLINE is not a way (unless some additional computations are introduced).
So your question boils to 2 things. What polynomial curve to use and how to smoothly join more of them together. To achieve that you need to sequence the control points in a specific manner. Booth of these questions are answered here:
Proper implementation of cubic spline interpolation
The interpolation polynomial used there is constructed in a way that it goes through all control points and 1st derivation is smoothly connected on both ends if more such curves are put together. The point call sequence is the same as for BEZIER/SPLINE cubics.
If you want/need to use BEZIER instead interpolation (for example to use GDI for rendering it) and still want the curve going through all the points you can convert that interpolation cubics of mine into BEZIER (it is form of Catmull-Rom splines) you just convert the control points into new ones so BEZIER matches the same shape. It is easily done like this:
how to convert interpolation cubic polynomial to cubic BEZIER
Here you can find example images how the joined curves looks like
SVG Paths and the Catmull-Rom algorithm

How to overlay one MATRIX over another? [duplicate]

Say you have a collection of points with coordinates on a Cartesian coordinate system.
You want to plot another point, and you know its coordinates in the same Cartesian coordinate system.
However, the plot you're drawing on is distorted from the original. Imagine taking the original plane, printing it on a rubber sheet, and stretching it in some places and pinching it in others, in an asymmetrical way (no overlapping or anything complex).
(source)
You know the stretched and unstretched coordinates of each of your set of points, but not the underlying stretch function. You know the unstretched coordinates of a new point.
How can you estimate where to plot the new point in the stretched coordinates based on the stretched positions of nearby points? It doesn't need to be exact, since you can't determine the actual stretch function from a set of remapped points unless you have more information.
other possible keywords: warped distorted grid mesh plane coordinate unwarp
Ok, so this sounds like image warping. This is what you should do:
Create a Delaunay triangulation of your unwarped grid and use your knowledge of the correspondences between the warped and unwarped grid to create the triangulation for the warped grid. Now you know the corresponding triangles in each image and since there is no overlapping, you should be able to perform the next step without much difficulty.
Now, to find the corresponding point A, in the warped image:
Find the triangle A lies in and use the transformation between the triangle in the unwarped grid and the warped grid to figure out the new position.
This is explained explicitly in detail here.
Another (much more complicated) method is the Thin Plate Spline (which is also explained in the slides above).
I understood that you have one-to-one correspondence between the wrapped and unwrapped grid points. And I assume that the deformation is not so extreme that you might have intersecting grid lines (like the image you show).
The strategy is exactly what Jacob suggests: Triangulate the two grids such that there is a one-to-one correspondence between triangles, locate the point to be mapped in the triangulation and then use barycentric coordinates in the corresponding triangle to compute the new point location.
Preprocess
Generate the Delaunay triangulation of the points of the wrapped grid, let's call it WT.
For every triangle in WT add a triangle between the corresponding vertices in the unwrapped grid. This gives a triangulation UWT of the unwrapped points.
Map a point p into the wrapped grid
Find the triangle T(p1,p2,p3) in the UWT which contains p.
Compute the barycentric coordinates (b1,b2,b3) of p in T(p1,p2,p3)
Let Tw(q1,q2,q3) be the triangle in WT corresponding to T(p1,p2,p3). The new position is b1 * q1 + b2 * q2 + b3 * q3.
Remarks
This gives a deformation function as a linear spline. For smoother behavior one could use the same triangulation but do higher order approximation which would lead to a bit more complicated computation instead of the barycentric coordinates.
The other answers are great. The only thing I'd add is that you might want to take a look at Free form deformation as a way of describing the deformations.
If that's useful, then it's quite possible to fit a deformation grid/lattice to your known pairs, and then you have a very fast method of deforming future points.
A lot depends on how many existing points you have. If you have only one, there's not really much you can do with it -- you can offset the second point by the same amount in the same direction, but you don't have enough data to really do any better than that.
If you have a fair number of existing points, you can do a surface fit through those points, and use that to approximate the proper position of the new point. Given N points, you can always get a perfect fit using an order N polynomial, but you rarely want to do that -- instead, you usually guess that the stretch function is a fairly low-order function (e.g. quadratic or cubic) and fit a surface to the points on that basis. You then place your new point based on the function for your fitted surface.

Draw gradient around closed cubic spline

For an image editing application i'm trying to draw a gradient around a closed natural cubic spline.
The spline is drawn according to the algorithm and code explained here.
The outcome should look like this (created with GIMP using lots of gaussian blur).
As i could not find any suitable algorithm to determine the distance from the spline, i tought of the following algorithm:
Mark some key points on the spline
Grow or enlarge these points with reference to the center of the closed spline
Create a mesh of triangles between the inner points and the outer points. These
triangles will have the inner vertexes black, and the outer vertexes
white.
As you can see, this solution is quite complex (will probably have to rely on OpenGL) and hence suboptimal.
Can anybody come up with a simpler solution?
Thanks in advance.
It seems you need to build distance transform map outside the spline. Some code for doing it. It is implemented in OpenCV library too.

How to implement Hough Circle in Java

i want to find a circular object(Iris of eye, i have used Haar Cascase with viola Jones algorithm). so i found that hough circle would be the correct way to do it. can anybody explain me how to implement Hough circle in Java or any other easy implementation to find iris with Java.
Thanks,
Duda and Hart (1971) has a pretty clear explanation of the Hough transform and a worked example. It's not difficult to produce an implementation directly from that paper, so it's a good place for you to start.
ImageJ provides a Hough Circle plugin. I've been playing around with it several times in the past.
You could take a look at the source code if you want or need to modify it.
If you want to find an iris you should be straightforward about this. The part of the iris you are after is actually called a limbus. Also note that the contrast of the limbus is much lower than the one of the pupil so if image resolution permits pupil is a better target. Java is not a good option as programming language here since 1. It is slow while processing is intense; 2. Since classic Hough circle requires 3D accumulator and Java probably means using a cell phone the memory requirements will be tough.
What you can do is to use a fact that there is probably a single (or only a few) Limbuses in the image. First thing to do is to reduce the dimensionality of the problem from 3 to 2 by using oriented edges: extract horizontal and vertical edges that together represent edge orientation (they can be considered as horizontal and vertical components of edge vector). The simple idea is that the dominant intersection of edge vectors is the center of your limbus. To find the intersection you only need two oriented edges instead of three points that define a circle. Hence dimensionality reduction from 3 to 2.
You also don’t need to use a classical Hough circle transform with a huge accumulator and numerous calculations to find this intersection. A Randomized Hough will be much faster. Here is how it works (~ to RANSAC): you select a minimum number of oriented edges at random (in your case 2), find the intersection, then find all the edges that intersect at approximately the same location. These are inliers. You just iterate 10-30 times choosing a different random sample of 2 edges to settle in a set with maximum number of inliers. Hopefully, these inliers lie on the limbus. The median of inlier ray intersections will give you the center of the circle and the median distance to the inliers from the center is the radius.
In the picture below bright colors correspond to inliers and orientation is shown with little line segment. The set of original edges is shown in the middle (horizontal only). While original edges lie along an ellipse, Hough edges were transformed by an Affine transform to make those belonging to limbus to lie on a circle. Also note that edge orientations are pretty noisy.

Calculate Voronoi around polygon

I need to generate a Voronoi diagram around a concave (non-convex) inside polygon. I have looked for methods online, but I haven't been able to figure out how to do this. Basically, I generate the convex hull of the points, calculate the dual points and build an edge network between these points. However, when meeting the edges of the inside polygon, it has to look like the edge of the shape, just like the convex hull. So, by doing this and clipping all the edges at the borders, I should end up with a Voronoi diagram that has nice edges to the borders of the inside polygon and no cells that are on both sides of the inside polygon.
Let me give you an example:
The problem with this is that the cells cross the inside polygon edges and there is no visual relation between the cell structure and the polygon shape.
Does anybody know how to approach this problem? Is there some algorithm that already does this or gets close to what I'm trying to achieve?
Thank you so much for any kind of input!
You might be able to build a conforming Delaunay triangulation (i.e. a triangulation that includes the polygon edges as constraints) and then form the Voronoi diagram as the dual. A conforming triangulation will ensure that no edge in the triangulation intersects with a constraint edge - all constraint edges will be an edge in the triangulation.
Have a look at the Triangle package here, as a reference for this type of approach. In my experience it's a fast and robust library, although it's written in c not java.
I'm not sure I understand at this stage how the points (the Voronoi centres) are generated in your diagram. If you're actually looking to do mesh generation in a polygonal domain, then there may be other approaches to consider, although the Triangle package supports (conforming) Delaunay refinement mesh generation.
EDIT: It looks like you can also directly form the Voronoi diagram for general line segments, check out the VRONI library, here. Addressing your comment - I'm not sure that you can always expect to have a uniform Voronoi diagram that also conforms to a general polygonal boundary. I would expect that the shape of the polygonal boundary would impose a maximum dimension on the boundary Voronoi cells.
Hope this helps.
Clearly you need to generate your Voronoi diagram to the constraints of the greater polygon. Although you refer to it as a polygon, I notice that your example diagram has spline-based edges. Let's forget that for now.
What you want to do is to ensure that you start out with the containing polygon (whether generated by you or from another source) having edges of fairly equal length; a variance factor would make this look more natural. I would probably go for a variance of 10-20%.
Now that you have your containing polygon bounded by lines segments of approximately equal length, you have a basis from which to begin generating your Voronoi diagram. For each edge on your container:
Determine the edge normal (perp line jutting inward from centre of that segment).
Use the edge normal as a sliding scale on which to place a new Voronoi node centre. The distance away from the edge itself would be determined by what you want your average Voronoi cell "diameter" to be, if they were all taken as circles. In your example that looks like maybe 30 pixels (or whatever the equivalent in your world units would be). Again, you should apply a variance factor to this so that not every cell centre is placed equidistant from its source edge.
Generate the Voronoi cell for your newly placed centre.
Store your Voronoi cell source point in a list.
As you incrementally generate each point, you should begin to see that the algorithm subdivides each convex "constituent area" of your concave container in a radial fashion.
You may be wondering what the list is for. Well, obviously, you're not done yet, you've only generated a fraction of the total Voronoi tesselation you want. Once you have created these "boundary" cells of your concave space, you don't want new cells to be generated closer to the boundary than the boundary cells already are, you only want them inside that area. By maintaining a list of the boundary cell source points, you can then ensure that any further points you create are inside that area. It's a little bit like taking an internal Minkowski sum to ensure you have a buffer zone. Now you can randomise the rest of your cells in this derived concave space, to completion.
(Caveat emptor: You will have to be careful with this previous step. If any "passage" areas are too narrow, then the boundaries of this derived space will overlap, you will have a non-simple polygon, and you may find yourself placing points in the wrong places in spite of your efforts. The solution is to ensure that either your maximum placement distance from edges is never more than half of your minimum passage width... or use some other geometric means, including Minkowski summation as one possibility, to ensure you do not wind up with a degenerate derived polygon. It is quite possible that you will end with a multipolygon, i.e. fragments.)
I've not applied this method myself yet, but although there will certainly be bugs to work out, I think the general idea will get you started in the right direction.
Look for a paper called:
"Efficient computation of continuous skeletons" by Kirkpatrick, David G, written in 1979.
Here's the abstract:
An O(n lgn) algorithm is presented for the construction of skeletons
of arbitrary n-line polygonal figures. This algorithm is based on an
O(n lgn) algorithm for the construction of generalized Voronoi
diagrams (our generalization replaces point sets by sets of line
segments constrained to intersect only at end points). The generalized
Voronoi diagram algorithm employs a linear time algorithm for the
merging of two arbitrary (standard) Voronoi diagrams.
"Sets of line segments is the constrained to intersect only at end points" is the concave polygon you describe.

Categories

Resources