How to create an array of Rectangles with a Rectangle class? - java

I'm working on an assignment that is supposed to return an array of 10 rectangles with a random height, random width, and random color selected from a string.
The program works fine to return the objects for ONE rectangle, but how would I implement this to create an array of 10 rectangles and THEN return each one in a loop?
Here's my class file with my objects:
import java.util.*;
public class Rectangle
{
private double width;
private double height;
public static String color = "White";
private Date date;
Rectangle() {
width = 1;
height = 1;
date = new Date();
}
Rectangle (double w, double h) {
width = w;
height = h;
date = new Date();
}
public double getHeight() {
return height;
}
public void setHeight(double h) {
height = h;
}
public double getWidth() {
return width;
}
public void setWidth(double w) {
width = w;
}
public static String getColor() {
return color;
}
public static void setColor(String c) {
color = c;
}
public Date getDate() {
return date;
}
public void setDate (Date d) {
date = d;
}
public double getArea() {
return width * height;
}
public double getPerimeter() {
return 2 * (width + height);
}
public String toString() {
String S;
S = "Rectangle with width of " + width;
S = S + " and height of " + height;
S = S + " was created on " + date.toString();
return S;
}
}
Here is my client program so far. I am setting a random height and a random width and selecting a random color from the colors String.
I would like to be able to do this for an array of 10 different rectangles:
import java.util.*;
public class ClientRectangle
{
public static void main(String[] args)
{
String[] colors = {"White","Blue","Yellow","Red","Green"};
Rectangle r = new Rectangle();
int k;
for(int i = 0; i < 10; i++)
{
r.setWidth((Math.random()*40)+10);
r.setHeight((Math.random()*40)+10);
System.out.println(r.toString() + " has area of " + r.getArea() + " and perimeter of " + r.getPerimeter());
k = (int)(Math.random()*4)+1;
System.out.println(colors[k]);
}
}
}
Thanks!

Create an array of rectangles and add a rectangle to each index.
Rectangle[] arr = new Rectangle[10];
for(int i = 0; i < 10; i++)
{
Rectangle r = new Rectangle();
r.setWidth((Math.random()*40)+10);
r.setHeight((Math.random()*40)+10);
arr[i] = r;
}

Move the Rectangle r = new Rectangle(); inside the for loop. Initialise a Array(List) outside the loop, and keep adding the Rectangles in the loop to the array.

You already seem to know how to declare an array of objects because you did so with an array of Strings. The declartion for an array of Rectangles is very similar:
Rectangle[] rects;
Note that you must also initialize the array. Since arrays are themselves objects you use the new operator, somewhat like when you initialize a reference variable to a single Rectangle:
Rectangle[] rects = new Rectangle[SIZE];
The only difference, as you can see, is that you put the size of the array inside the []s. This only creates an array of references to Rectangle objects. The references are all automatically set to null. This means that you need to create the Rectangles themselves. You can do this in for loop:
for (int i = 0; i <= SIZE; ++i) {
rects[i] = new Rectangle();
}
You can also set the width and height of each Rectangle as you want. (I will leave the exact details about how to do this to the reader.)
Finally, you need to put this all in a method other than main() so that you can return the whole array (You don't return one Rectangle at a time) as the instructions state:
return rects;

Related

Trying to create a 5x5 grid of squares with std draw but squares are at duplicate coordinates

I am trying to create a 5x5 board of rectangles(squares) with a 2d array but my code draws the 25 squares in only 5 places so it looks like there's only 5 squares diagonally on the "board". I'm assuming something is wrong with the logic in the nested loop but after tinkering around for a while I can't figure out what it is. Thanks for any help!!
Object class:
public class Card
{
private double x, y, wd, ht;
private int cardNum;
private boolean faceUp;
private double space;
private Color bsC, fsC;
Random gen = new Random();
public Card(double x, double y, double width, double height, int cN, double sP)
{
this.x = x;
this.y = x;
wd = width;
ht = height;
faceUp = false;
this.cardNum = cN;
space = 0.1;
bsC = new Color(178, 178, 178);
fsC = new Color(211, 172, 250);
}
public void drawMe()
{
StdDraw.setPenColor(bsC);
StdDraw.filledRectangle(x, y, wd, ht);
}
}
Tester class:
public class ClientCardJordanHubbard
{
public static void ClientCardJordanHubbard()
{
Random gen = new Random();
Card[][] cards = new Card[5][5];
int count = 0;
StdDraw.setFont(new Font("Arial", Font.BOLD, 20));
StdDraw.setPenColor(StdDraw.BLACK);
StdDraw.text(0.5,0.5, "Press w a s d to move");
StdDraw.pause(2000);
StdDraw.clear();
for(int i = 0; i < cards.length; i++)
{
double x = 0.25+0.14*i;
for (int j = 0; j < cards[i].length; j++)
{
double y = 0.25+0.14*j;
double w = 0.07;
double h = 0.07;
int cN = gen.nextInt(5)+1;
cards[i][j] = new Card(x, y, w, h, cN, 0.1);
cards[i][j].drawMe();
System.out.println("The value of the card at index " +i+" " +j
+ " is: " +cards[i][j].getcN());
System.out.println("The coordinates of the card at index " +i+" " +j
+ " is: " +cards[i][j].getX() +" "+cards[i][j].getY());
}
}
}
Since your cards are displayed diagonally, the first thing you need to check whether your x will get an y value or vice-versa at some point. Knowing this, it is easy to find the error, which is the line of
this.y = x;
since your this.y gets an x value.

I need to be able to find the smallest volume in an ArrayList using a for-each loop

This is the code I have done so far. It creates the ArrayList and adds the circles. The volume is stored and is printed in the console. The last thing I have to do is print out the smallest volume using a for-each loop. This is where I'm having difficulties. I could really use some help/advice
public static void main(String[] args)
{
Random rand = new Random();
final int RADIUS_MAX = 100;
int NUM_SPHERES = 4;
List<Sphere> spheres = new ArrayList<Sphere>();
for(int add = 1; add <= NUM_SPHERES; add++) {
spheres.add(new Sphere(rand.nextInt(RADIUS_MAX)));
}
for (Sphere s : spheres) {
System.out.println(s);
}
//TODO: Convert to a for-each loop to find the volume of the smallest sphere
for (Sphere s : spheres) {
}
}
You do not need an additional loop. The sphere with the smallest radius will have the smallest volume. You could store the smallest volume so far (initialized to a very large volume) and update it in either of your existing loops. I believe the formula for volume is (4. / 3) * Math.PI * Math.pow(radius, 3).
The volume formula of the sphere depends from radius like V <=> R, so no need to calculate volume each time, because minimal voule will be with minimal radius.
public class Foo {
public static void main(String... args) {
Random rand = new Random();
final int maxRadius = 100;
final int totalSphere = 4;
List<Sphere> spheres = new ArrayList<>();
for (int i = 0; i < totalSphere; i++)
spheres.add(new Sphere(rand.nextInt(maxRadius)));
for (Sphere sphere : spheres)
System.out.println(sphere);
Sphere smallestSphere = spheres.get(0);
for (Sphere sphere : spheres)
if (smallestSphere == null || sphere.compareTo(smallestSphere) < 0)
smallestSphere = sphere;
System.out.println("smallest volume: " + smallestSphere.getVolume());
}
public static class Sphere implements Comparable<Sphere> {
private final int radius;
public Sphere(int radius) {
this.radius = radius;
}
public double getVolume() {
return (4. / 3) * Math.PI * Math.pow(radius, 3);
}
#Override
public String toString() {
return "radius: " + radius;
}
#Override
public int compareTo(Sphere sphere) {
return Integer.compare(radius, sphere.radius);
}
}
}

How to draw multiple objects on a canvas?

I'm trying to draw multiple objects in a canvas but keep getting a runtime error, below is my GraphicalObject Class:
/*import javafx.scene.canvas.Canvas;*/
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import java.util.Scanner;
public class GraphicalObject { //class
private Scanner scan;
private int x;
private int y;
private int width;
private int height;
//private double xPoints;
//private double yPoints;
//private int numPoints;
/*
* constructor
*/
public GraphicalObject(){
this.x = 0;
this.y = 0;
this.width = 0;
this.height = 0;
//this.xPoints = 0;
//this.yPoints = 0;
//this.numPoints = 0;
}
public GraphicalObject(int x, int y, int width, int height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
//think of get/set methods ie acessor/mutators
//get x
//get y
//get width
//get height
public void draw(GraphicsContext gc){
//int numPoints = 5;
//double[] xPoints = new double[numPoints];
//double[] yPoints = new double[numPoints];
//xPoints = [x + (width/2), x + width, x + .8333 width, x + .1667 width, x]
//yPoints = [y, y + (height/2), y + height, y + height, y + (height/2)]
` gc.setFill(Color.PINK);
gc.fillRect(this.x, this.y, this.width, this.height);
//gc.fillPolygon(xPoints, yPoints, numPoints);
}
}
I can't figure out where I'm going wrong, I think my for loops are okay... I'm able to draw one rectangle but if I say I want to draw two, it lets me input info for one object and then gives a runtime error. This is my canvas class:
/**
* A basic canvas object that can store and
* draw graphical object
*/
import javafx.scene.canvas.Canvas;
import javafx.scene.paint.Color;
import javafx.scene.canvas.GraphicsContext;
import java.util.Scanner;
public class GraphicalObjectCanvas extends Canvas {
// data fields
// constants
public static final int C_WIDTH = 500;
public static final int C_HEIGHT = 500;
// instance variables
/**
* a scanner object to make the Canvas interactive
*/
private Scanner scan;
// TO DO: DECLARE YOUR ARRAY OF GRAPHICAL OBJECTS HERE
// (AND ANY OTHER INSTANCE VARIABLES YOU NEED TO MAINTAIN YOUR ARRAY)
GraphicalObject[] graphobs;
private int index;
private int numObjects;
/**
* Creates a canvas for drawing graphical objects
* with a size of C_WIDTHxC_HEIGHT pixels
*/
public GraphicalObjectCanvas() {
super(C_WIDTH, C_HEIGHT);
// initialize the scanner object
this.scan = new Scanner(System.in);
// find out how many objects the user wants to add
System.out.println("How many graphical objects do you want?");
numObjects = scan.nextInt();
// TO DO: DEFINE YOUR ARRAY OF GRAPHICAL OBJECTS HERE
graphobs = new GraphicalObject[numObjects];
// for each object they wanted to add...
for (int i = 0; i < numObjects; i++) {
this.add();
}
}
public void draw() {
// clear the picture
this.clear();
// get the graphics context from the canvas
GraphicsContext gc = this.getGraphicsContext2D();
// TO DO: LOOP THROUGH YOUR ARRAY OF GRAPHICAL OBJECTS
// AND TELL EACH ONE TO DRAW PASSING THE GRAPHICS CONTEXT (gc) AS INPUT
for(int i = 0; i < numObjects; i++){
graphobs[i].draw(gc);
System.out.println("Object drawn: " + i); //or 1??);
}
}
private void clear() {
GraphicsContext gc = this.getGraphicsContext2D();
gc.setFill(Color.WHITE);
gc.fillRect(0, 0, C_WIDTH, C_HEIGHT);
}
private void add() {
System.out.println("What is the x location of the object?");
int x = scan.nextInt();
System.out.println("What is the y location of the object?");
int y = scan.nextInt();
System.out.println("What is the width of the object?");
int width = scan.nextInt();
System.out.println("What is the height of the object?");
int height = scan.nextInt();
// TO DO: USE THE INFORMATION ABOVE TO CREATE A NEW GRAPHICAL OBJECT
// AND ADD IT TO THE ARRAY OF OBJECTS.
GraphicalObject gob = new GraphicalObject( x, y, width, height);
graphobs[index] = gob;
index++;
// after adding new object, redraw the canvas
this.draw();
}
}
The problem is that you are invoking GraphicalObject.draw(GraphicsContext) on a null object.
This occurs because you call GraphicalObjectCanvas.draw() at the end of the GraphicalObjectCanvas.add() method and the for loop in GraphicalObjectCanvas.draw() uses numObjects to determine the range of indices. However, you have yet to create and allocate an object to all the indices of the array graphobs when this for loop executes.
To fix this, either do not invoke GraphicalObjectCanvas.draw() at the end of your GraphicalObjectCanvas.add() method, or change the for loop in GraphicalObjectCanvas.draw() to i < index rather than i < numObjects.
For example:
for(int i = 0; i < index; i++){
graphobs[i].draw(gc);
System.out.println("Object drawn: " + i); //or 1??);
}

Creating a method to increase height and width of an oblong by amounts entered by the user

Ok so for class I have been working on some oblong questions based off an oblong class. The question I am having an issue with is to create a method to increase the height and width of the oblong by a user defined amount.
This is my main:
import java.util.Scanner;
public class Oblong6
{
public static void main(String [] args)
{
Oblong ob1 = new Oblong();
Scanner keyboardIn = new Scanner(System.in);
Oblong ob = new Oblong();
double h, w, x;
System.out.print ("Enter the height of the oblong:");
h = keyboardIn.nextDouble();
System.out.print ("Enter the width of the oblong:");
w = keyboardIn.nextDouble();
System.out.print (" Enter the amount to increment by ");
x = keyboardIn.nextInt();
ob.setHeight(h);
ob.setWidth(w);
ob.setX(x);
System.out.println (ob.incHeight());
System.out.println (ob.incWidth());
System.out.println("Height " + h);
System.out.println("Width " + w);
}
}
And this is the method I have created in the oblong class to increase them:
public class Oblong
{
// instance variables
private double height;
private double width;
private double x;
// constructor
public Oblong()
{
height = 0.0;
width = 0.0;
x = 0.0;
}
// methods
public double getHeight()
{
return height;
}
public double getWidth()
{
return width;
}
public double setX(double x)
{
return x;
}
public void setWidth(double w)
{
width = w;
}
public void setHeight(double h)
{
height = h;
}
public double calculateArea()
{
return width * height;
}
public double calculatePerimeter()
{
return width + height * 2;
}
public boolean isSquare()
{
if(height == width)
{
return true;
}
else
{
return false;
}
}
public double incHeight()
{
{
return height + x ;
}
}
public double incWidth()
{
{
return width + x ;
}
}
}// end of class
but it only ever prints out the original height and width.
Your code:
public double incHeight()
{
{
return height + x ;
}
}
That just adds two numbers and returns the result.
It doesn't do anything else. The same is true for your other methods.
Whereas the purpose of the method seems to be to alter the state of the underlying object. But as said; the current implementation does not alter that state.
Hope that is good enough to help you to resolve your problem on your own.
Side note: read about Java syntax. Your extra pair of braces ... doesn't do anything either.
Whit this:
public double incWidth()
{
{
return width + x ;
}
}
You are returning width + 1 but you are not modifying the private attribute. Just do this:
public double incWidth(){
this.width = this.width + 1;
return this.width;
}
Also in setters you don't need to return anything. To change an attribute inside a class do something like:
private double value;
private void setValue( double value ) {
this.value = value;
}
With this.value you are refering to the private value inside the class. Without this you are refering to the parameter value of the method setValue.
Further reading:
How do getters and setters work?
Your instance variable x has not been set, hence the height + x will return height + 0.0.
change this:
public double setX(double x)
{
return x;
}
To this:
public double setX(double x)
{
this.x = x;
}
This will return value to be displayed, but it should be set for later use, so you need this :
public void incHeight()
{
setHeight(height + x) ;
}
and then :
System.out.println("Height " + height); // height not h

What's the best way of changing the 24 pixels around a particular pixel?

I'm currently working on a piece of code which changes the colour of certain pixels of an image. It does this via the following method:
inputImage.put(25, 25, colour);
This selects a pixel at the x-coordinate 25, the y-coordinate 25, and then changes it to the specified colour.
I now have to change this pixel and the 24 pixels around it to a new colour, meaning that there's a 5x5 space which gets recoloured.
I can think of a few ways of doing this. One is to iterate through all the pixels of an image and check whether they are between 23 and 27 for x and y-coordinates, then recolour them if they are. The other is to individually specify each of the pixels that need changing. But both of these ideas seem kinda flabby. Can anyone recommend a more elegant way of doing this?
don't loop.
instead, set the complete 5x5 roi (at x,y):
int x=15,y=7;
in.submat(y-3,y+2, x-3,x+2).setTo(colour);
Perhaps change your loop conditions to start at your specific x and y and end at your boundary (perhaps x+5 and y+5)
Example:
int start = 23;
int boundary = start+5;
for(int x = start; x < boundary; x++) {
for(int y = start; y < boundary; y++) {
inputImage.put(x,y,colour);
}
}
A proper oop solution would be to define a Point class and create an Iterator to walk the range you want.
class Point {
public static final Point UNIT = new Point(1, 1);
public static final Point X = new Point(1, 0);
public static final Point Y = new Point(0, 1);
public static final Point ZERO = new Point(0, 0);
final int x;
final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public Point(Point from) {
this(from.x, from.y);
}
public Point add(Point delta) {
return new Point(x + delta.x, y + delta.y);
}
public Point sub(Point delta) {
return add(delta.negate());
}
public Point negate() {
return new Point(-x, -y);
}
public String toString() {
return "[" + x + "," + y + "]";
}
}
class Around implements Iterator<Point> {
private final Point center;
private final Point range;
private Point last = null;
private Point next = null;
public Around(Point center, Point range) {
this.center = center;
this.range = range;
}
#Override
public boolean hasNext() {
if (next == null) {
if (last != null) {
// Are we still in vertical range.
if (last.y <= center.y + range.y) {
// Next is last step right one.
next = last.add(Point.X);
// Have we hit limit?
if (next.x > center.x + range.x) {
next = next.add(new Point((-2 * range.x) - 1, 1));
if (next.y >= center.y + range.y + 1) {
// Fallen out of y range.
next = null;
}
}
}
} else {
// First = center - range.
last = center.add(range.negate());
next = last;
}
}
return next != null;
}
#Override
public Point next() {
Point n = last = next;
next = null;
return n;
}
}
public void test() {
Iterator<Point> around = new Around(new Point(0, 0), new Point(2, 2));
while (around.hasNext()) {
System.out.println(around.next());
}
}

Categories

Resources