Mouse pointer detection over a Path2D - java

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.

Related

Determine component overlapped by Line2D

There are no. of components around and on Line2D.I want to find only the overlapped ones.I tried line.getbounds().intersects(component) but it gives the rectangular area components which I don't need.Also,distance sometimes gives me a component which is very near to Line but not on line.Any solution?
Short answer: check if at least one of these two conditions is true
any endpoint of the line is inside the component, use the method contains
the line intersects any side of the component bounds, use the intersect method.
Detailed description:
These are the possible cases:
one endpoint of the line is inside the component (this include the case where the line is entirely inside the component);
the line cross the component but all the end points of the line are outside of the objects;In this case it will intersect two sides, but one is enough to validate.
in all other case, the line and the component do not overlap each other and we do not care.
Only the middle bullet is a bit tricky, however since you are testing only jcomponent, the life is simple, because they are rectangles aligned with the axis. You can easily compute the endpoint of the sides of the bounds of the component. The bounds are given by a point (x,y) the width w and the height h. This gives you the four sides as:
(x,y) - (x+w,y)
(x,y) - (x, y+h)
(x,y+h) - (x, y+h)
(x+w,y) - (x+w,y+h)
If the components you are talking about are java Components then they are rectangular and you can use line.intersects(component.getBounds())
if they are any other kind of shape you have to define that shape and work with the line mathematically if they are not rectangular

Java how to draw and fill a Polygon which has holes

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.

Bolding Shape Lines in Java

After creating the shape (for example GOval), how can I bold the shape lines?
AFAIK, there is no such thing as setting a shape line "bold" in the ACM API. What would "bold" be anyway? You would need to specify a "line thickness" value yourself, but I don't think the API caters for this, and there is no default constant for SHAPE_LINE_BOLD or similar.
Instead, think about how you can achieve the effect otherwise. GOval implements GFillable, i.e., you can fill your oval with a specific colour. Perhaps look into overlaying more than one filled shape.
Hint: If you filled your shape with the same colour as the background, would it be visible?

Java AWT bounds

I have an assignment to draw a certain number of circles using java.awt.Graphics.
Drawing the circles is fairly simple, but I am only supposed to draw the circle if it appears within the visible area. I know I can call method getClipBounds() to determine the drawing area, but I'm having trouble finding a java implementation of a way to determine if a circle intersects a Rectangle.
Is that the right way to go about determining if the circle I want to draw will be completely visible or is there a simpler way?
Don't use the Graphics.fillOval(...) method to do the painting.
Instead you can use the Graphics2D.fill(Shape) method. You can create oval Shape objects using the Ellipse2D class.
but I'm having trouble finding a java implementation of a way to determine if a circle intersects a Rectangle.
The Shape object has a method that will allow you to get the rectangular bounds of the Shape. Then you can use the Rectangle.contains(...) method of the your Graphics area to determine if the Shape is fully contained within your panel.
Check out Playing With Shapes for more information and ideas.
use Ellipse2D.Float to instanciate an object for example:
Shape circle = new Ellipse2D.Float(100.0f, 100.0f, 100.0f, 100.0f);
basically the parameters,from left to right, are: Height, Width, X of the Top left and Y of the top left, and by keeping the X and Y both greater or equal to zero, your circle will always be visible.
the parameters of the Float(...) are documented for the Ellipse2D.Float in Java SE 7 in
http://docs.oracle.com/javase/7/docs/api/java/awt/geom/Ellipse2D.Float.html

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.

Categories