Java: Find possible intersection - java

I have this code:
public void paint(Graphics g) {
g.setColor(Color.black);
g.fill3DRect(myX, myY, 20, 20,true);
g.setColor(Color.red);
g.fillOval(nX, nY, 20, 20);
}
Coordinates of the 2 shapes are given by the user, how can i know if there's a intersection between them?
(I don't need coordinates of the intersection, just need to know if there is or not)
Thanks in advance!

It heavily depends on the context and the actual intention. A very simple solution is to use the Area class: Just create one Area object for each of the shapes that you want to check, and intersect these areas:
Shape shape0 = new Rectangle2D.Double(mxY, myY, 20, 20);
Shape shape1 = new Ellipse2D.Double(nX, nY, 20, 20);
Area a0 = new Area(shape0);
Area a1 = new Area(shape1);
a0.intersect(a1);
if (!a0.isEmpty()) { /* They intersect! */ }
(BTW: You can cast your Graphics object to Graphics2D and then paint the Shape objects directly)
Important : Note that this solution may be very inefficient compared to an analytic solution. If you only have to check "simple" objects (circles, rectangles...) for intersection, you might want to implement an analytic solution, especially if you have to check "many" of these simple objects. The advantage of the Area solution is its simplicity and genericity: It works for arbitrary shapes, even complex shapes like font letters or manually created Path2D objects.

Related

Fill Color of Multiple Drawlines that Intersect Forming Closed Shape

I needed to draw a Car using Java and Graphics2D. I used multiple basicstrokes to come up with the shape of the car. How do I fill it with color? An example would be drawing 3 lines in the shape of a triangle and then wanting to fill it with color.
You can not simply fill a shape that was only created by drawing three lines. You have to define the shape, including all the lines that it consists of.
How exactly this is implemented depends on serveal factors. For example, whether you want to use the same stroke for all three lines, or whether they need different strokes.
It could be helpful if you had already provided some information of how exactly you are drawing the lines at the moment. I'll try to make a guess here...
So assuming that your current code roughly looks like this:
void paintCar(Graphics2D g)
{
g.setStroke(new BasicStroke(1.0f));
g.setColor(Color.BLUE);
// Draw the triangle
g.drawLine(100,100,200,100);
g.drawLine(100,200,150, 50);
g.drawLine(150, 50,100,100);
}
the easiest way to additionally fill this triangle would be to change it as follows:
void paintCar(Graphics2D g)
{
g.setStroke(new BasicStroke(1.0f));
g.setColor(Color.BLUE);
Path2D path = new Path2D();
// Build the triangle
path.append(new Line2D.Double(100,100,200,100), false);
path.append(new Line2D.Double(100,200,150, 50), true);
path.append(new Line2D.Double(150, 50,100,100), true);
// Draw the triangle
g.draw(path);
// Fill the triangle, with a different color
g.setColor(Color.CYAN);
g.fill(path);
}
But note...
... that there are more elegant and concise ways of achieving this. Usually, one would not append individual Line2D segments, but simply use the Path2D to build the shape:
void paintCar(Graphics2D g)
{
g.setStroke(new BasicStroke(1.0f));
g.setColor(Color.BLUE);
// Build the triangle
Path2D path = new Path2D();
path.moveTo(100,100);
path.lineTo(200,100);
path.lineTo(150, 50);
path.closePath();
// Draw the triangle
g.draw(path);
// Fill the triangle, with a different color
g.setColor(Color.CYAN);
g.fill(path);
}
So if you have the coordinates of your shape in an appropriate form (maybe stored as a list of Point2D objects), you may more easily build a shape that you can draw and fill then.

distance between two Shapes/Areas in Java?

If I have two java.awt.geom.Area's made out of the union of various simple Shapes (Polygons and Ellipses), is there a method out there to find the distance (i.e. closest distance) between the two Areas?
To clarify: suppose I have two arbitrary Areas, each of which is created from the union of shapes of any sort:
//Define the first area
Area a = new Area(new Ellipse2D.Double(50, 50, 100, 100));
a.add(new Area(new Rectangle2D.Double(100, 100, 100, 100)));
//Define the second area
Area b = new Area(new Ellipse2D.Double(200, 300, 100, 100));
b.add(new Area(new Ellipse2D.Double(250, 250, 100, 100)));
What I want is a method getDistance(Area a, Area b) that gives me a double representing the shortest distance between any point in Area a and any point in Area b. Here's an image of the above two Areas with a line in blue indicating the distance I'm interested in:
Is there a method out there to do this? If not, how might I implement one?
There doesn't seem to be a method that does that exactly; however, using PathIterators, you should be able to compare point to point along the outline of the shapes and find the distance manually.
http://docs.oracle.com/javase/6/docs/api/java/awt/geom/PathIterator.html
This Wikipedia article describes how you could efficiently implement this to avoid the quadratic obvious implementation.
Use Hausdorff Distance
Check this very clear explanation of how to use hausdorff Distance:
http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/98/normand/main.html

How to treat a shape painted with an algorithm like an object?

Ok dear folks, i've got this question and i don't really know a certain way to solve it.
I'm doing like a "Paint application" in java, i know everything is ready, but I need to paint the shapes with Computer Graphics Algorithms.
So, the thing is, once the shape is painted in the container how could I convert it like sort of an "Object" to be able to select the shape and move it around (I have to move it with another algorithm) I just want to know how could I know that some random point clicked in the screen belongs to an object, knowing that, I would be able to fill it(with algorithm).
I was thinking that having a Point class, and a shape class, if i click on the screen, get the coordinates and look within all the shapes and their points, but this may not be very efficient.
Any ideas guys ?
Thanks for the help.
Here is some of my code:
public class Windows extends JFrame{
private JPanel panel;
private JLabel etiqueta,etiqueta2;
public Windows() {
initcomp();
}
public void initcomp()
{
panel = new JPanel();
panel.setBounds(50, 50, 300, 300);
etiqueta = new JLabel("Circulo Trigonometrico");
etiqueta.setBounds(20, 40, 200, 30);
etiqueta2 = new JLabel("Circulo Bresenham");
etiqueta2.setBounds(150, 110, 200, 30);
panel.setLayout(null);
panel.add(etiqueta);
panel.add(etiqueta2);
panel.setBackground(Color.gray);
this.add(panel);
this.setLayout(null);
this.setVisible(true);
this.setSize(400,400);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.red);
g2d.setStroke(new BasicStroke(2));
dibujarCirculo_bresenham(g2d, 50, 260, 260);
dibujarCirculo_trigonometrico(g2d, 50, 130, 200);
}
/*This functions paints a Circle*/
public void dibujarCirculo_trigonometrico(Graphics g,int R,int xc,int yc)
{
int x,y;
for (int i = 0; i < 180; i++) {
double angulo = Math.toRadians(i);
x = (int) (Math.cos(angulo)*R);
y = (int) (Math.sin(angulo)*R);
g.drawLine(x+xc, y+yc, x+xc, y+yc);
g.drawLine((-x+xc), (-y+yc), (-x+xc), (-y+yc));
}
}
I assume that any image is a valid (isn't constrained to a particular set of shapes). To get an contiguous area with similar properties, try using a flood fill.
To colour in or move a particular shape around, you can use flood fill to determine the set of pixels and manipulate the set accordingly. You can set a tolerance for similar hue, etc so that it's not as rigid as in Paint, and becomes more like the magic selection tool in Photoshop.
There are a couple of approaches to take here depending on what precisely you want.
1) is to have objects, one for each drawn thing on screen, with classes like Circle and Rectangle and Polygon so on. They would define methods like paint (how to draw them on screen), isCLickInsideOf (is a click at this point on screen contained by this shape, given size/position/etc?) and so on. Then, to redraw the screen draw each object, and to test if an object is being clicked on ask each object what it thinks.
2) is, if objects have the property of being uniform in colour, you can grab all pixels that make up a shape when the user clicks on one of the pixels by using a floodfill algorithm. Then you can load these into some kind of data structure, move them around as the user moves the mouse around, etc. Also, if every object is guaranteed to have a unique colour, you can test which object is being clicked on by just looking at colour. (Libraries like OpenGL use a trick like this sometimes to determine what object you have clicked on - drawing each object as a flat colour on a hidden frame and testing what pixel colour under the mouse pointer is)

Plotting functions with using java GUI

I need to plot a polynomial given a start point and an end point. I've looked at using the paincomponent to do do it, but I'm getting confused because the origin is in the top left corner and I need my grid lines to be dynamic.
How do I make it so I can create a dynamic scale and what java class is best used for plotting a function?
For example if the user were to enter -2 2 x^2 the plotter would need to create a grid that goes from -2 has 0 in the middle and 2 on the right for the x coordinates. However if the user enters x^3 we have negative coordinates in the y plane and I'll need to slide the line containing the x coordinates up to accomidate.
Thanks!
The way I think you could do this(and I may be wrong) is to draw the y-line and x-line of your graph, and label the values for x and y using drawString at the correct position.
To illustrate this I did this example for you:
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Point2D.Double from = new Point2D.Double(300, 100);
Point2D.Double to = new Point2D.Double(300, 300);
Line2D.Double line = new Line2D.Double(from, to);
g2.draw(line);
Point2D.Double from2 = new Point2D.Double(150, 200);
Point2D.Double to2 = new Point2D.Double(450, 200);
Line2D.Double line2 = new Line2D.Double(from2, to2);
g2.draw(line2);
g2.drawString("-1", 290, 215);
}
The drawString method would draw "-1" below 0. So you could use the same thing to draw -2 below -1, etc.
I know this sounds inefficient, but it's the only way I can think of.
Hope someone else will have a better solution for you.
It shouldn't be too difficult to transform the y-coordinate if you know the size of area you want to paint to. But to be honest, why don't you use one of the plotting libs like JFreeChart, ...?

Index of geometric functions

I am making a sort of command based application to draw geometric figures. So if a user enters something like RECT 100, 50, 200, 120 I draw a rectangle at specified location on the drawing panel.
So for this i need to map RECT to g.drawRect(100, 50, 200, 120); and all such similar functions to draw geometric figures.
I will use a hash map for mapping, but i don't know how to build a array of functions in java. In C++ i have done this though.
The key can be 'RECT' and the value the offset of the index.
Please show me how can i index these functions. Or is there a still better way to address the primary concern?
There are no function pointers in Java, you need to do it through inheritance and/or interfaces. Here is an example:
interface Shape {
void draw(int[] data);
}
class Polygon implements Shape {
public void draw(int[] data) {
// Draw polygon using points data[i], data[i+1] for points
}
}
class Circle implements Shape {
public void draw(int[] data) {
// Draw circle using data[0], data[1] for the center, and data[2] for radius
}
}
In your main program's constructor or static initializer:
Map<String,Shape> shapes = new HashMap<String,Shape>();
shapes.put("POLY", new Polygon());
shapes.put("CIRC", new Circle());
In your drawing code:
shapes.get("CIRC").draw(new int[] {100, 100, 50});
I have to admit, I didn't really got your design, I'm not sure why do you need an array of functions as you said, but this is how this thing can be done in java.
Since Function (method in java terms) is not a "first-class-sitizen" in Java, you can't build an array of methods (at least in java 7) . What you can do instead is to use a more object oriented approach - define an interface, each method will be an implementation of the interface ( a class) so that you'll be able to store an array of interface implementation.
I would use a design pattern Command instead of array of methods or something... Hope this helps

Categories

Resources