What are the approaches to color-filling a curved concave shape in libgdx?
Let us assume that:
1) The shape-to-be-rendered is built from an array of vertices that are close to each other.
2) Edges between the vertices are known.
3) The vertices' positions might dynamically change over time. We are guaranteed that no self-intersections will occur (and that the shape will not be hollow).
The right-most picture is what I'm trying to render in libgdx (with-or-without the outline).
From what I've read, triangulation is a popular approach to non-curved shapes, but in order for it look any good for shapes with curvature, I imagine we would need a huge number of vertices (so that the many lines "zoomed out" resemble a smooth curve).
Triangulatin is not the only one way to go with this. I am not familiar with your gfx lib but I would do this in low level:
Subdivide your polyline to set of convex ones
you need to know which segment is line and which is curve and for the curve you also need to know the control points from neighboring patch so the connection is smooth. The concave boundary can be detected by the fact that angle change swaps sign so if you got consequent points p(0)...p(n) with consistent widing rule then
d(i ) = p(i+1)-p(i )
d(i-1) = p(i )-p(i-1)
n(i) = cross( d(i) , d(i-1) )
n(i).z * n(i-1).z < 0.0
so the cross product will give you normal and if the direction of the normal swaps it mean the winding is changed... The equatio assumes points are in xy plane or parallel to it. If not the case the last line should be
dot( n(i) , n(i-1) ) < 0.0
if true p(i) is your concave boundary and you should split your shape by it
fill the polylines
you can use the same approach as for triangles or convex polygons see:
how to rasterize rotated rectangle
Algorithm to fill triangle
render polyline outline
Of coarse if you do not have fast pixel access or horizontal line rendering available is this not a good way to go. There is one simple but not as fast option:
render outline
flood fill inside
this step is slow which might cause problems for bigger resolutions.
Related
I'm looking for a way to calculate the area of an intersection between a single rectangle and the union of a small set of rectangles.
I'm using Java and all of the rectangles are represented in integers (x,y,w,h). All rectangles are axis aligned with x/y axis.
Any suggestions?
You're going to potentially have a unique intersection between Rect1 and every rectangle in the RectSet union. So you are going to have do the intersection between Rect1 and each rectangle in the union separately. The intersecting area is the union of all intersecting sections between Rect1 and the rectangles in the union.
An optimization is to create a abounding rectangle for the union of rectangles (hopefully done as the union is created). If Rect1 doesn't intersect with this bounding rectangle, you can the skip doing any further intersections and the area in null.
An intersection of two rectangles is a rectangle itself (possibly degenerate, but those have zero area and can be ignored). Further, an intersection of unions is the same as a union of intersections (distributivity law). Therefore, you may intersect R1 with each of Rj and find the union of resulting rectangles.
To find the union, the easiest method is perhaps breaking the scene into vertical stripes, by drawing a vertical line through each vertex. Then within each stripe it's a well-known one-dimensional problem, solved by counting points in and out and removing those with count greater than one.
Go through and express your rectangles not as (x,y,w,h) but as (x1,y1,x2,y2), which is simply (x,y,x+w,y+h).
Then, loop over all Rj`s and "clip" the rectangles to the coordinates of Rect1:
Rj.x1 = max(Rj.x1, Rect1.x1)
Rj.y1 = max(Rj.y1, Rect1.y1)
Rj.x2 = min(Rj.x2, Rect1.x2)
Rj.y2 = min(Rj.y2, Rect1.y2)
Now, go through and remove any Rj's where Rj.x1>=Rj.x2 or Rj.y1>=Rj.y2 as in that case, the rectangles didn't intersect.
After, sum up all the areas of the remaining rectangles (simply (Rj.x2-Rj.x1) * (Rj.y2-Rj.y1)).
At this point, you will have double-counted any area where any of the clipped Rj`s overlap.
So, you then need to go through and loop over all Ri's and all Rj's where j>i and, clip the two with each other, but this time, if there is an intersection (same test as above), you need to subtract the area of the intersection from the value you have so far to remove the double-counting.
Unfortunately, this will double-remove any areas of a triple-overlap. So, you will then need to find those areas and add them back in. And so on and so forth for quadruple-overlaps, quintuple-overlaps, etc.
Sounds like it'll get pretty messy...
Maybe the easiest is to just draw the Rj's to a canvas in red and then count the red pixels inside Rect1 at the end. (Of course, you don't have to use a real Canvas. You can write your own using a bit-array.) There might even be scenarios (like a small coordinate space with lot's of tiny rectangles), where this is faster than the analytical solution. But, of course this will only work if you have integer coordinates.
Both n.m's answer and PQuinn's answer suggest to distribute the intersection across the union, then find the area of the union. That's a good idea.
In java, I suggest creating a new set of non-degenerate intersections between R1 and your Rj's, based on the assumption that most intersections will be degenerate. Then use the algorithm at http://codercareer.blogspot.com/2011/12/no-27-area-of-rectangles.html to find the area of the set of intersections.
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.
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.
I'm trying to draw a 5 point star in AWT.
Each point in the 2d grid is 72 degrees apart - so I thought I could draw the polygon using only 5 points by ordering the points 144 degrees apart, so the polygon gets fed the points in order 1,3,5,2,4
Unfortunately, this involves a lot of intersecting lines, and the end result is that there are 5 triangles with my desired colour, circling a pentagon that has not been coloured.
Looking through, it has something to do with an even-odd rule, that intersecting points will not be filled.
I need my star to be drawn dynamically, and using the specific shape described (for scaling and such).
If I manually plot the points where it intersects, I get some human error in my star's shape.
Is there any way to just turn this feature off, or failing that, is there a way to get the polygon to return an array of x[] and y[] where lines intersect so I can just draw another one inside it?
Thanks.
Draw it with ten points, 36 degrees apart, at two alternating radii.
Establish the 10-point Polygon in cartesian coordinates, as suggested by relet and as shown in this example. Note how the coordinate system is centered on the origin for convenience in rotating, scaling and translating. Because Polygon implements the Shape interface, the createTransformedShape() method of AffineTransform may be applied. A more advanced shape library may be found here.
Is there a way to get the polygon to return an array of x[] and y[] where lines intersect?
Although typically unnecessary, you can examine the component coordinates using a Shape's PathIterator. I found it instructive to examine the coordinates before and after invoking createTransformedShape().
I'm currently writing an application that actually acts as a "cut" tool for 3D meshes. Well, I had some problems with it now which I am clueless on how to solve, since it is my first application.
I have loaded a model from an object file onto the canvas, then on the same canvas, I use the mouse drag event to draw lines to define the cutting point.
Let us say I want to cut a ball into half and I draw the line in the middle. How do I detect the vertices of the ball under the line.
Secondly, if I rotate/translate the ball, would all the the vertices information change?
Think of what you'd do in the real world: You can't cut a ball with a line, you must use a knife (a line has no volume). To cut the ball, you must move the knife through the ball.
So what you're looking after is a plane, not a line. To get such a plane, you must use some 3D math. What you have is the canvas orientation and the "side view" of the plane (which looks like a line).
So the plane you're looking for is perpendicular to the canvas. A simple way to get such a plane is to take the canvas orientation and create a plane which has the same orientation and then rotate the plane around the line by 90°.
After that, you can visit all edges of your model and determine on which side of the plane they are. For this, determine on which side of the plane the end points of the edge are. Use the cross product. If they are on the same side (both results of the cross products will have the same sign), you can ignore the edge. Otherwise, you need to determine the intersection point of the edge and plane. Create new edges and connect them accordingly.
See this page for some background on the math. But you should find some helper methods for all this in your opengl library.
if I rotate / translate the ball, would all the the vertices information change
Of course.
It's not going to be that easy.
I assume the line you are drawing induces a plane which then cuts the sphere.
To do so, you have to calculate the intersecting area of the sphere and the plane.
This is not a trivial task and I suggest using an existing framework for this or if you really want to do this yourself, read about basic intersection problems to get a feeling for this kind of problem. This paper offers a good introduction to various intersection tests.
In general boundary represended volumes, as in your case, are difficult to handle when it comes to more advanced manipulations. Cutting a sphere in half is easy compared to burring a small hole into it. Sometimes it's better to use a volume representation, like tetrahedral meshes or CSG.
Regarding your second question, you shouldn't rotate or translate the sphere, rotate and translate the camera.