Java - filling an overlapping polygon - java

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().

Related

How to draw the area around a shape

I worked on a very simple map editor phase for a game in java. The goal is to put some islands with different shape on the map. But there is some constraints:
islands must not be a specific distance far from another island (lets call it L)
islands must not be a specific distance close from another island (lets call it S)
In the game, the island is place with the mouse. The gamer can see areas where the island can be place or not as you can see.
My problem is that I realize my disalow area is not good. For example, the rectangle island have a rectangle disallow area (my first naive attempt) but in fact I must draw area of S around the rectangle ; that leads to a shape like this:
I'm able to draw these kind of areas as long as my shapes are just composed of lines. But my island can have cubic or quadratic curve (and even though i'll need this kind of area for other shapes later).
The closer I manage to do is that:
In this case, the disallow area around the circle must be ... a circle (simple geometry). But as you can see, I have a weird rounded rectangle.
I currently try to transform each segment of the pathiterator of a Shape to get the area. It's not as simple as scaling a shape (remember the rectangle case). I've allready try many ways to transform the shape and get the area.
Question:
Does someone have information, formula, clues, algorithms, libs to get this area from any java.awt.Shape (or PathIterator) and a distance?
http://www.java2s.com/example/java/java.lang/expand-or-shrink-a-shape-in-all-directions-by-a-defined-offset.html
This site describe how to use stroke to get the offset area.
There is just a single modification to solve my problem ; I have to use BasicStroke.JOIN_ROUND to get the good rectangular Shape.
Then I get:

Filling a 2D curved concave shape in libgdx

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.

Find intersection between Rectangle and Union of a set of rectangles?

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.

java circle recognition from an arraylist of points

I currently have an arraylist of points from a freehand drawing on a canvas. I was wondering if there is a simple algorithm to detect if that shape represents a circle.I have already researched this a little and the main items I am pointed at are either the Hough transform or having bitmap images but both of these seem a little over the top for what I need it for. Any pointers to algorithms or implementation would be very helpful.
thanks in advance sansoms,
If I interpret your question correctly, you want to know if all the points are on a circle.
As illustrated in the picture, we pick three points A, B, C from the list and compute the origin O of the presumed circle. By checking the distance between O and each point from the list, we can conclude whether these points are on a circle.
If you do not know what the user wanted to draw (e.g., a circle, an ellipse, a line, or a rectangle), you could use some basic optimization algorithm to find the shape best matching the hand-drawn points.
for each basic shape (oval, rectangle, triangle, line, etc.), create a random instance of that shape and measure the error w.r.t. the given points
optimize each of the shapes (individually) until you have the oval best matching the given points, the rectangle best matching the points, the best triangle, etc.
pick the shape that has the lowest error and draw it
Maybe this answer can give you some ideas: https://stackoverflow.com/a/940041/12860
In short: calculate the second derivative. If it is quite constand, it is probably a circle.
Reading your comment, an easier method to draw a circle is for the user to click the center point, then drag the radius of the circle. It's a lot less calculation, and easier for the user to draw.
You can do the same thing with a rectangle, or any other convex polygon.

Calculate shape orientation in Java (Image analysis)

I have an image such as this:
and I need to calculate the orientation of it. In this case the shape is pointing towards the top left of the screen. Accuracy isn't hugely important as long as 3 or 4 calculations average out to within 5 degrees or so of the actual orientation (it will be moving slightly).
Can anyone point me towards an algorithm to do this? I don't mind if the orientation is returned as a double or as a vector.
If the image is always T-shaped, you can simply get the furthest pair of pixels, then find the furthest pair from either both of those (the edges of the T), find which is further from the other two, draw a line from that one to the middle point of those two.
You can further refine it by then finding the base of the T by comparing the middle line with the edges of the base, and adjusting the angle and offset until it is actually in the middle.
The definitive solution is impossible I guess, since requires image recognition. I would project the 2D image onto axis, i.e. obtain the width and height of the image and get direction vector from these values taking them as components.
First, a couple of assumptions:
The center and centroid are "close"
The descending bar of the T is longer than the cross-bar
First, determine the bounding rectangle of the image and find the points of the image that lie along this rectangle. For points that lie along the line and are a certain distance from one another (say 5 pixels to pick a value) you'll need to only take 1 point from that cluster. At the end of this you should have 3 points, i.e. a triangle. The shortest side of the triangle should be the cross-bar (from assumption 2), i.e. find the two points closest to each other. The line that is perpendicular to the line crossing those two points is then your orientation line, i.e. find the angle between it and the horizontal axis.
I would try morphological skeletonization to simplify the image, followed by some straightforward algorithm to determine the orientation of the longer leg of the skeleton.
The solution in the end was to use a Convex Hull Algorithm, which finds the minimum number of points needed to enclose a shape with a bound.

Categories

Resources