Java how to draw and fill a Polygon which has holes - java

I am currently trying to draw and fill a Polygon which has a hole in it in Java. Normally this would not be a big problem, since I would draw the exterior ring and then draw the interior ring with the color of the background.
But the problem is, that the polygon is displayed above a image which should be "seen" through the hole.
I am writing the code in Java and am using JTS Topology Suite for my geometry data.
This is my current code, which just paints the border and fills the polygon with a color.
private void drawPolygon(com.vividsolutions.jts.geom.Polygon gpoly, Color color, Graphics2D g2d){
java.awt.Polygon poly = (java.awt.Polygon)gpoly;
for(Coordinate co : gpoly.getExteriorRing().getCoordinates() {
poly.addPoint(co.x, co.y);
}
g2d.setColor(col);
g2d.fill(poly);
g2d.setColor(Color.BLACK);
g2d.draw(poly);
}
Sadly java.awt.Polygon does not support Polygons with holes.

Use the Polygon as the basis for an Area (e.g. called polygonShape).
Create an Ellipse2D for the 'hole', then establish an Area for it (ellipseShape).
Use Area.subtract(Area) something like:
Area polygonWithHole = polygonShape.subtract(ellipseShape);

There are some ways to draw shapes or areas that are more complex than a simple polygon (another answer already mentioned Area).
Besides those, you could try to tessellate your final polygon. There are lots of algorithms to do this. For more complex shapes, the algorithms get a bit more complex as well. Basically, you're dividing your final shape into little polygons (usually triangles, but it also can be something else) and then draw those polygons.
You can take a look at your possibilities by searching for "Tessellation Algorithm", there are also some already implemented libraries for Java.

You can use java.awt.geom.Path2D to render a "compound shape" with a hole in it:
If you have java.awt.Shape objects defining the outside & inside edges of the shape, use append(shape, false) to add each shape.
If you have a set of path points for the outside edge and a set of path points for the inside edge, use lineTo() to add the first set of points - creating a closed loop by either ending with the same point you started with, or calling closePath() to automatically close the loop. Then use moveTo() to create a break before adding the inner set of points via more lineTo() calls.
In either case, you must create the path passing Path.WIND_NON_ZERO to the constructor - otherwise the hole won't be left unfilled.
See How to create shape with a hole? for a longer code example.

You could fill the polygon first, and then draw the holes on top, giving the illusion that it filled everything but the holes.

Related

How to Fill color inside shape using setPixel method?

I need to fill the color inside custom shape. I know one of the pixel coordinate inside the shape and also know the color of the shape. I need to get all pixel inside the shape calculate from knowing pixel coordinate how can i write logic for this can some one please help.
For already rendered shapes
use Flood Fill or Boundary fill algorithms. For example see:
my C++ implementation of Flood&Boundary fill
beware most implementations are recursive so there is a high risk of stack/heap overflow for bigger areas. There are also iterative approaches using dynamic point lists which are safer.
For polygons in vector form
Use convex polygon filling. In case you got concave polygons you need to divide them into convex polygons first. Another options is to triangulate. Both triangle and convex polygon rasterization is the same see:
Algorithm to fill triangle
how to rasterize rotated rectangle (in 2d by setpixel)
If you need triangulation see:
Wiki: Polygon triangulation
In case of very complicated shapes and not possible triangulation for any reason you can try fill all the pixels in the bounding box of polygon that are inside polygon. For that you need:
hit-test

Rendering a triangular face in 3d space

Let's say I have a triangular face in 3d space, and I have the 3d coordinates of each vertex of this triangle, and would also have other information about the triangle(angles, lengths of sides, etc.). In Java, if I have the viewing screen and its information, how can I draw that plane, without using libraries like LWJGL, to that image, assuming I can properly project, accounting for perspective, any 3d point to that 2d image.
Would the best course of action just be to run a loop that draws each point on the plain to a point on the image(i.e. setting the corresponding pixel), which will most likely set the same pixel multiple times? If I'd do this, what would be the best way to identify each point in an oblique triangle, or a triangle that doesn't line up nicely with the axes?
tl;dr: I have a triangular face in 3d space, a "camera" looking at the face, and an image in which I can set each pixel. Using no GL libraries, what's the best way to project and draw that face onto the image?
Projection :
won't detail as you seems to know it
Drawing a line
you can look at Bresenham algorithm if you wanna start with the basics
(hardwared in recent graphics card)
Filling
you can fill between left and right borders of the triangle while you use Bresenham on both (you could use a floodfill algorithm starting ... i don't know, maybe at the projection of the center of the triangle)
Your best bet is to check out the g.fillPolygon() function for Java. It allows you to draw polygons with as many sides as possible and theres also g.drawPolygon() if you don't want it solid. Then you can just do some simple maths for the points. Such as each point is basically it's x and y except if the polygon is further away the points move closer to the center of the polygon and if the polygon is closer they move further away from the center of the polygon.
A second idea could be using some sort of array to store pixels and then researching line drawing algorithms and drawing lines then putting all the line data in another array and using some sort of flood-fill. Then whilst it's in that array you could try and do some weird stuff to the pixels if you wanted textures or something.

libgdx: sprite break like a glass

I have a sprite which is ball. Let's say, it represents a glass ball.
I am rendering the graphics with SpriteBatch.
Is it possible in libgdx to have a breaking glass effect for the ball? Meaning, I want to split the sprite to different pieces with abnormal borders (not rectangular) and then draw them flying to different directions.
Use a PolygonSprite to represent the non-rectangular chunks of your sprite.
To generate the chunks, I suggest picking a random spot near the center of your sprite, and then creating several triangles from that point to the corners and 2 or 3 points on each side of the square sprite. You should be able to define a PolygonRegion for each shard, and use that to build PolygonSprite instances.
I haven't actually used the PolygonRegion API before (and it looks a bit obtuse), so you might want to check the examples.

Detect lines and its curve hand drawn by Graphics2d in a java draw application

I'm making a music application that enables you to freedraw lines from specified colors and then a trackbar would pass on top of it and should detect the curves and color to output sound and modified pitch etc depending on the curves.
What I'm looking for is help on detecting the lines and curves. They are drawn in a Label as a BUfferedImage. The following is a screenshot:
The Black line I drew to represent the trackbar, but infact it would be a Rectangle drawn by drawRect or it could be a imagepanel, depends on the way you detect lines.
My question:
How could I detect the yellow, green, etc lines and its curve and handle that data? If I get that data I could easily modify gain and pitch for each assign sound for each color. Thanks!
You want to store the coordinates of the user's drawing motions at the very least. You could store these as points or convert them into representations of line segments and/or curves depending on your requirements. Of course, store the stroke, color and anything you want as part of this model.
To accomplish this, I think the path of least resistance would probably have you utilizing java.awt.Shape and everything in java.awt.geom. Specifically, I think you would want to represent each user-drawn element as one or more Path2D and/or Area objects in response to user drawing motions. Then, have your GUI render these models on your custom Component.
Path2D would store the movements as lines and curves accessible through a PathIterator. Given a trackbar represented by a Rectangle2D, you can use the various methods available for comparing and combining geometries--namely the Shape interface's intersects(Rectangle2D) here. If a geometry model intersects your trackbar, you could then iterate through the path components until you find the actual sub-segment that is intersecting. This gets you the local slope.

Mouse pointer detection over a Path2D

I have constructed a Path2D that represents an unclosed shape consisting of straight lines:
I want to be able to detect when the mouse is clicked and the mouse pointer is near to (within a few pixels of) the path. Using the contains method does not work because the algorithm treats the unclosed shape as implicitly closed (i.e. by drawing a straight line between the start and end points).
Does anyone know of another mechanism for achieving this?
Create a BasicStroke (the width controls your pixel-distance-tolerance)
Don't draw with it, only use its createStrokedShape method to create a second shape from your shape. This second shape describes the outline of the shape that would be filled if you would draw your first shape with the BasicStroke.
Use the contains method of this second shape
From Stroke.createStrokedShape API documentation:
Returns an outline Shape which encloses the area that should be
painted when the Shape is stroked according to the rules defined by
the object implementing the Stroke interface.

Categories