Java Rectangles and Casting - java

Obviously based on the class assignment this is homework..so help me as much as you can/want, don't flame me for posting HW okay?
I have been dying, reading through my book, reading through online for the past two hours and can't find for the love of god WHY this stupid rectangle says "Cannot find Method setX()". Also is there a way to make the doubles, be ints without casting them as int? It looks really messy, and we aren't supposed to add anything except in the method enclosing...I think I have to cast??
Thanks for any help you can give..
import java.awt.Rectangle;
import java.util.ArrayList;
public class Homework18A
{
public static void main(String[] args)
{
ArrayList<Rectangle> test = new ArrayList<Rectangle>();
test.add(new Rectangle(10, 20, 30, 40));
test.add(new Rectangle(20, 10, 30, 40));
test.add(new Rectangle(10, 20, 40, 50));
test.add(new Rectangle(20, 10, 50, 30));
Rectangle enc = enclosing(test);
System.out.println(enc);
System.out.println("Expected: java.awt.Rectangle[x=10,y=10,width=60,height=60]");
}
/**
Computes the smallest rectangle enclosing all rectangles in
an array list.
#param rects an array list of rectangles of size >= 1
#return the smallest rectangle enclosing all rectangles in rect
*/
public static Rectangle enclosing(ArrayList<Rectangle> rects)
{
Rectangle containRec = new Rectangle(0, 0, 0, 0);
for(int i = 0; i < rects.size(); i++) {
if(rects.get(i).getX() < containRec.getX())
containRec.setX((int)rects.get(i).getX());
if(rects.get(i).getY() < containRec.getY())
containRec.setY((int)rects.get(i).getY());
if(rects.get(i).getX() + rects.get(i).getWidth() > containRec.getWidth())
containRec.setWidth(((int)rects.get(i).getX() + rects.get(i).getWidth()));
if(rects.get(i).getY() + rects.get(i).getHeight() > containRec.getHeight())
containRec.setHeight(((int)rects.get(i).getY() + rects.get(i).getHeight()));
}
return containRec;
}
}

Because Rectangle does not have a method setX() or setY(). If you're trying to set the position you want to use setLocation(x,y).
Edit: there is no setWidth() or setHeight() methods either, you want to use setSize(width, height). Even though the Rectangle class has fields for x, y, width, and height it does not follow the normal Java conventions where the fields are made private and public getter and setter methods are used. In this case you could access the fields directly and just say containRec.x = whatever, but it's a bad habit to get in to.
You don't want to remove the (int) casts, but you can definitely clean up that section. Instead of calling rects.get(i) you could put a line at the beginning of the loop that says Rectangle currentRect = rects.get(i); or better yet use a for-each loop.

Sorry but I had to lauch :D
Poor Matt :-*
Here is the link for the api: http://download.oracle.com/javase/1,5,0/docs/api/java/awt/Rectangle.html
There is no setX() or setY()

I assume you're using the java.awt.Rectangle class. It does not have a setX method (take a look at the Javadocs to confirm this), but it does declare it's x field to be public, so you can just set it directly:
containRec.x = whatever;
The same goes for y, of course. Directly setting public fields is generally A Bad Thing (as #Jordan Bently pointed out), but it'll work in this case.
Or you can use some combination of setLocation, setBounds, setSize, setRect or setFrame.
EDIT: You can get rid of all those nasty casts by using entirely integer arithmetic. Instead of using getX(), which returns a double, just look up the x field directly - it's an int.
The java.awt.Rectangle class is somewhat cumbersome to use.

Related

Checking Rectangle OverLap

Hello :) I'm currently working on something that hinges on checking the overlap of two rectangles in Java on BlueJ, and I've been checking the internet stuck for hours for anything to help but I've not managed to find anything which helps which is specific enough to what I'm dealing with.
Currently, I'm writing a method called "checkOverLap" and it looks a little like this:
private Boolean checkOverlap() {
if (word2.getXPosition() >= word1.getXPosition() && word2.getXPosition() <= word1.getXPosition() + word1.getTextWidth() && (word2.getYPosition() >= word1.getYPosition() && word2.getYPosition() <= word1.getYPosition() + word1.getTextHeight())){
return true;
}
else{
return false;
}
}
Erm, I'm relatively new to Java, so please forgive how horrendously this is formatted >.>
The general gist of what it needs to do, is to return true when the rectangles overlap :) Else, it will return false. The reason this is required, is because I want the rectangles to randomize their position on the screen until they overlap.
I have already included accessor methods which return the X and Y coordinates and the Width and Height of the rectangles, and these are what I am using in the if statement to compare and see if they over lap.
As to whats wrong with it, I'm currently unsure but I'm thinking it's to do with the logic of the statement, like I haven't compared the right variables etc or I've added the wrong operators :/
Any advice or such would be appreciated :)
You don't have to do it yourself. Use the intersects method of java.awt.Rectangle instead:
final Rectangle r1 = new Rectangle(50, 50, 10, 10);
final Rectangle r2 = new Rectangle(40, 40, 10, 10);
final Rectangle r3 = new Rectangle(40, 40, 15, 15);
System.out.println(r2.intersects(r1)); // false
System.out.println(r3.intersects(r1)); // true

Java: Find possible intersection

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.

Using self-referential arrays, polygons are invisible

I used an array that refers to previous elements in the same array to determine what the next value will be. This is so that I can get relative values for position when drawing polygons.
There are no reported syntax errors, but the triangles I use here in the example are either invisible or don't exist.
For this example, I would like to make small black triangles randomly scattered in the top half of the window without regard for the window's edges and the other triangles.
The following is the code which includes an example of what I'm trying to achieve, but without using a self-referential array (I wrote this in BlueJ and have never written anything outside of BlueJ. I don't know how to write continuous code so please bear with me. I wrote where each of the two classes begin after each // :
//first class
import javax.swing.*;
public class patterns {
public static void main(String[] args) {
JFrame f = new JFrame("Example");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
example p = new example();
f.add(p);
f.setSize(400,400);
f.setVisible(true);
}
}
//next class
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Color;
public class example extends JPanel{
public void paintComponent (Graphics g){
super.paintComponent(g);
this.setBackground(Color.WHITE);
//The following is the part of the code that doesn't work.
g.setColor(Color.BLACK);
int x=0;//this x is used for the following while loop
int[] xC = new int[3];//these are the x coordinates of the random triangles
int[] yC = new int[3];//these are the y coordinates of the random triangles
while(x<14){//this while loop is used to make many triangles
xC[0]= (int)Math.random()*400;
xC[1]= xC[0]+(int)Math.random()*20;
xC[2]= xC[1]+(int)Math.random()*4;
yC[0]= (int)Math.random()*200;
yC[1]= yC[0]-(int)Math.random()*10;
yC[2]= yC[0]-(int)Math.random()*3;
g.fillPolygon(xC,yC,3);//I changed this to fillPolygon
x++;//this is so the loop will eventually end
}
//the following is the manual part that does work.
int[] xCe = new int[3];//this is the array of x coordinates for the triangle
xCe[0]= 200;
xCe[1]= 210;
xCe[2]= 213;
int[] yCe = new int[3];//this is the array of y coordinates for the triangle
yCe[0]= 300;
yCe[1]= 295;
yCe[2]= 299;
g.fillPolygon(xCe,yCe,3);//this polygon appears properly
//everything after this is just to help explain after compiling
g.drawString("There should be a whole bunch of little triangles that look",20,320);
g.drawString("sort of like this one, but on the top half of this window.", 40,340);
g.drawLine(170,270,200,290);
g.drawLine(194,289,200,290);
g.drawLine(197,285,200,290);
g.drawString("this one",140,260);
}
}
What is causing them to be invisible? I would like for them to be visible. I don't know what I am doing wrong. Is it the self-referential arrays? Is that not allowed for fillPolygon()?
You initialize the values in your arrays like this:
xC[0]= (int)Math.random()*400;
But the cast happens before the multiplication, so the value returned by Math.random() (which will be less than 1) gets cast to an int, so it becomes 0*400, therefore 0 gets stored into all the indices of your array.
To fix this, just put parentheses around the multiplication so it looks like:
xC[0]= (int)(Math.random()*400);
I should also note that your loop is just drawing the same triangle 14 times, so you still won't see a bunch of different triangles. To fix that, just put the code you use to generate your triangles inside of your loop, like so:
for (int i = 0; i < 14; i++) {
int[] xC = new int[3];
xC[0] = (int) (Math.random() * 400);
xC[1] = xC[0] + (int) (Math.random() * 200);
xC[2] = xC[1] + (int) (Math.random() * 4);
int[] yC = new int[3];
yC[0] = (int) (Math.random() * 200);
yC[1] = yC[0] - (int) (Math.random() * 10);
yC[2] = yC[0] - (int) (Math.random() * 3);
g.setColor(Color.BLACK);
g.fillPolygon(xC,yC,3);
}
I'd also suggest giving your triangles a more uniform size (sides of < 3 and 4 are kind of small), perhaps generate a random value between a low and high number (e.g. 10 to 20). And maybe look into the java.util.Random class while you're at it.

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

circle packing - java

I have a task to draw a circle and then fill in with the most amount of circles without touching the sides. I can draw the circle, and I can make loops to pack the circle in a hexagonal/honeycomb format, but can't control whether they are inside or outside the circle.
I have used this: g.drawOval(50, 50, 300, 300); to specify my circle. Given I'm actually specifying a square as my boundaries I can't actually determine where the circle boundaries are. So I'm basically packing the square full of circles rather than the circle full of circles.
Can some please point me in the right direction? I'm new to java so not sure if I have done this the complete wrong way. My code is below. I have another class for the frame and another with the main in it.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class DrawCircle extends JPanel
{
private int width, height, diameter;
public DrawFrame d;
public DrawCircle()
{
width = 400;
height = 400;
diameter = 300;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.blue);
g.drawOval(50, 50, 300, 300);
for(int i=50; i<200; i=i+20)
{
for(int j=50; j<350; j=j+10)
{
g.drawOval(j, i, 10, 10);
}
}
for(int i=60; i<200; i=i+20)
{
for(int j=55; j<350; j=j+10)
{
g.drawOval(j, i, 10, 10);
}
}
for(int i=330; i>190; i=i-20)
{
for(int j=340; j>40; j=j-10)
{
g.drawOval(j, i, 10, 10);
}
}
for(int i=340; i>190; i=i-20)
{
for(int j=345; j>40; j=j-10)
{
g.drawOval(j, i, 10, 10);
}
}
}
}
All those magic numbers make me cringe a bit. You're new to Java, and it's homework, so I understand why you're doing it, but I would not recommend it if you do much programming in the future.
You need an algorithm or recipe for deciding when a small circle on the inside falls outside the big one you're trying to pack. Think about the ways you might do this:
If the distance between the center of the big circle and the small circle is is greater than the difference in their radii, the small circle will overlap the big circle or fall completely outside it.
You can add this check to your code: Just before you draw the circle, perform this check. Only draw if that circle passes.
Don't worry about Java for a second; draw yourself a picture on a piece of paper, draw that enclosing and packed circle, and see if that statement is correct. Then think about any corner situations that it might not cover, just as a check.
I'll make two more recommendations. First, do this by hand without a computer once so you'll see what the "right" answer might look like. Second, see if you can separate the calculation of the circles from the drawing part. It might make your job easier, because you can concentrate on one thing at a time. It's called "decomposition". You solve complex problems by breaking them up into smaller, more manageable pieces. In this case, it's also called "model-view separation". You might need to know that someday.
Maybe another way to think about this problem would be to imagine a 2D arrangement of circles, packed in their closest arrangement, extending to infinity in both the x- and y-directions. Now take your enclosing circle, put it on top of the 2D arrangement, and eliminate all the circles that overlap the big circle. I don't know if it'll be optimal, but it's easy to visualize.

Categories

Resources