How to handle multiple constructors? - java

Hello I have problems with assignment where I need to create 3 constructors in one class. That initialize 2 coordinates for 2 corners in a rectangle. The error Eclipse is giving: "Duplicate method" and "Multiple markers on this line" errors with the Constructs.
public class Rectangle {
private double lowleftx;
private double lowlefty;
private double uprightx;
private double uprighty;
public Rectangle() {
this.lowleftx = 0;
this.lowlefty = 0;
this.uprightx = 1;
this.uprighty = 1;
}
public Rectangle(uprightx, uprighty) {
this.lowleftx = 0;
this.lowlefty = 0;
}
public Rectangle(uprightx, uprighty, lowleftx, lowlefty) {
this.lowleftx = lowleftx;
this.lowlefty = lowlefty;
this.uprightx = uprightx;
this.uprighty = uprighty;
}
public double getLowleftx() {
return lowleftx;
}
public void setLowleftx(double lowleftx) {
this.lowleftx = lowleftx;
}
public double getLowlefty() {
return lowlefty;
}
public void setLowlefty(double lowlefty) {
this.lowlefty = lowlefty;
}
public double getUprightx() {
return uprightx;
}
public void setUprightx(double uprightx) {
this.uprightx = uprightx;
}
public double getUprighty() {
return uprighty;
}
public void setUprighty(double uprighty) {
this.uprighty = uprighty;
}
}

As said in the comments, you forgot to add the type of the parameters :
public Rectangle(double uprightx, double uprighty...)
You can optimize your code by calling the constructor with all parameters from other constructors :
public class Rectangle {
private double lowLeftX;
private double lowLeftY;
private double upRightX;
private double upRightY;
public Rectangle(double lowLeftX, double lowLeftY, double upRightX, double upRightY) {
this.lowLeftX = lowLeftX;
this.lowLeftY = lowLeftY;
this.upRightX = upRightX;
this.upRightY = upRightY;
}
public Rectangle(double upRightX, double upRightY) {
this(0, 0, upRightX, upRightY); // = Rectangle(0, 0, upRightX, upRightY)
}
public Rectangle() {
this(0, 0, 1, 1); // = Rectangle(0, 0, 1, 1), or Rectangle(1, 1)
}
// ...
}
You can also create a class to represent a "point" (a coordinate with a X value and Y value) and use it in your Rectangle class :
// Point.java
public class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
// ...
}
// Rectangle.java
public class Rectangle {
private final Point lowLeft;
private final Point upRight;
public Rectangle(final Point lowLeft, final Point upRight) {
this.lowLeft = lowLeft;
this.upRight = upRight;
}
public Rectangle(final Point upRight) {
this(new Point(0, 0), upRight);
}
public Rectangle() {
this(new Point(1, 1));
}
}

You have missed to specify the double datatype in the constructor arguments, so add it as shown below:
public Rectangle() {
this.lowleftx = 0;
this.lowlefty = 0;
this.uprightx = 1;
this.uprighty = 1;
}
public Rectangle(double uprightx, double uprighty) {
this.lowleftx = 0;
this.lowlefty = 0;
}
public Rectangle(double uprightx, double uprighty,
double lowleftx, double lowlefty) {
this.lowleftx = lowleftx;
this.lowlefty = lowlefty;
this.uprightx = uprightx;
this.uprighty = uprighty;
}

So, as seen in other answers: you forgot to specify the types for your parameters.
And for completeness: this is how you should really write down this constructors:
public Rectangle() {
this(1, 1);
}
public Rectangle(double x1, double y1) {
this(0, 0, x1, y1);
}
public Rectangle(double x1, double y1, double x2, double y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
In other words: avoid repeating code. You can delegate the real "assignment" work into your last ctor. And then you want to use easy to read but still meaningful names. When thinking about coordinates, x1/y1 is for example much easier to grasp then your approach.

Related

Must implement inherited abstract method error

I'm getting an error for Sphere.java that says
The type sphere must implement the inherited abstract method GeometricObjects.hit(Ray)
Though I don't see how I am getting this error as I've defined the hit method as shown below.
Below is the Sphere.java code:
package Objects;
import Utility.*;
public class Sphere extends GeometricObjects {
Point3d center;
double radius;
public Sphere(Point3d center, double radius, Color color) {
this.center = new Point3d(center);
this.radius = radius;
this.color = new Color(color);
}
public double hit(Ray ray) {
double a = ray.direction.dot(ray.direction);
double b = 2*ray.origin.sub(center).dot(ray.direction);
double c = ray.origin.sub(center).dot(ray.origin.sub(center)) - radius*radius;
double discriminant = b*b - 4*a*c;
if (discriminant < 0.0){
return 0.0;
}
else {
double t = (-b - Math.sqrt(discriminant)) / (2*a);
if (t > 10E-9) {
return t;
}
else {
return 0.0;
}
}
}
}
This is the GeometricObjects.java code:
package Objects;
import Utility.*;
public abstract class GeometricObjects {
public Color color;
public abstract double hit(Ray ray);
}
And heres the Ray.java code:
package Utility;
public class Ray {
public Point3d origin;
public Vector direction;
public Ray(Point3d origin, Vector direction) {
this.origin = new Point3d(origin);
this.direction = new Vector(direction);
}
}

Cannot find symbols while using abstract classes

Practicing abstract classes with shapes. The goal is to get the total area of the 3 shapes using abstract classes. So far this is what I have.
I'm not sure whether I did this part right:
static double sumArea(Shape[] arr){
// Sum up the areas of all the shapes using getArea()
return arr.getArea();
}
I keep getting error saying that it doesn't find the symbol h (height), w (width), tw (top_width). Anybody know why it's not finding these symbols?
public class TestShape{
public static void main(String args[]){
Point p = new Point(1, 1);
Shape[] arr = {
new Rectangle(p, 3, 4),
new Parallelogram(p, 5, 6, Math.PI/6.0),
new Trapezoid(p, 5, 6, 2)
};
System.out.println("SUM_AREA = " + sumArea(arr));
}
static double sumArea(Shape[] arr){
// Sum up the areas of all the shapes using getArea()
return arr.getArea();
}
}
class Point{
double x, y;
Point(){
this(0, 0);
}
Point(double x, double y){
this.x = x;
this.y = y;
}
public String toString(){
return "[" + x + ", " + y + "]";
}
}
abstract class Shape{
Shape(){
}
Shape(Point p){
this.p = p;
}
public Point getPosition(){
return p;
}
public void setPosition(Point p){
this.p = p;
}
// Abstract method
public abstract double getArea();
}
abstract class Quadrangle extends Shape{
protected double width, height;
Quadrangle(Point p, double w, double h){
this.p = p;
this.width = w;
this.height = h;
}
public double getWidth(){
return w;
}
public double getHeight(){
return h;
}
public void setWidth(double w){
this.weight = w;
}
public void setHeight(double h){
this.height = h;
}
}
class Rectangle extends Quadrangle{
Rectangle(Point p, double w, double h){
this.p = p;
this.width = w;
this.height = h;
}
public boolean isSquare(){
if(w == h){
return "Error";
}
}
#Override /** Return Area */
public double getArea(){
return w * h;
}
}
class Parallelogram extends Quadrangle{
protected double angle;
Parallelogram(Point p, double w, double h, double angle){
this.p = p;
this.weight = w;
this.height = h;
this.angle = angle;
}
public double getAngle(){
return angle;
}
public void setAngle(double a){
this.angle = a;
}
#Override /** Return Area */
public double getArea(){
return w * h;
}
}
class Trapezoid extends Quadrangle{
protected double top_width;
Trapezoid(Point p, double w, double h, double top_width){
this.p = p;
this.width = w;
this.height = h;
this.top_width = top_width;
}
public double getTopWidth(){
return top_width;
}
public void setTopWidth(double tw){
this.top_width = tw;
}
#Override /** Return Area */
public double getArea(){
return ((w + tw) / 2) * h;
}
}
The names w, tw and so on only exist as parameters. When you want to access the values you save in the constructors, you have to use the left hand side name: this.[width or whatever].
Also, rewrite sumArea to something like this:
static double sumArea(Shape[] arr){
// Sum up the areas of all the shapes using getArea()
double totalArea = 0;
for (Shape shape : arr) {
totalArea += shape.getArea();
}
return totalArea;
}

How to slow down move planet in its orbit?

I have a model of planet (below) and paint the Sun in center of screen. Then I draw the planets using a new thread. Planets move is too fast and not means that it's a move on a circle. I tried to change the thread's sleep time and planet's velocity and does not matter - planets move too fast. Velocity > 3 - too fast speed.
I need result: Planets move slow and I can manage a planet's speed with her velocity (1, 3, 5, 10). Angle (position of planet) changes 1 time in second on small amount (1, 3, 5 degrees - velocity)
public class Planet
{
private String name;
private int id;
private double radius = 1.0;
private double radiusOrbit = 5.0;
private double velocity = 1;
private Color color;
private int angle = 0;
private String parent;
public Planet(String name, int id, double rad, double radOrbit, double velocity, Color color)
{
this.name = name;
this.id = id;
this.radius = rad;
this.radiusOrbit = radOrbit;
this.velocity = velocity;
this.color = color;
}
...getters and setters
}
Main Class
public class ShowCosmos2 {
public static void main(String[] args)
{
JFrame frame = new PlanetsFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class PlanetsFrame extends JFrame
{
private int width = Toolkit.getDefaultToolkit().getScreenSize().width;
private int height = Toolkit.getDefaultToolkit().getScreenSize().height;
public PlanetsFrame()
{
setSize(width, height);
setTitle("Planets");
setContentPane(new PlanetsCanvas(width, height));
Container contentPane = getContentPane();
contentPane.setBackground(Color.BLACK);
}
}
class PlanetsCanvas extends JPanel
{
private int width, height;
private int centerX = 0;
private int centerY = 0;
private Thread runner;
private boolean running = false;
Planet[] planets = {
new Planet("Venera", 1, 5.0, 50.0, 1, Color.GREEN),
new Planet("Mercury", 1, 3.0, 75.0, 1.5, Color.ORANGE),
new Planet("Earth", 1, 6.0, 100.0, 2, Color.BLUE),
new Planet("Jupiter", 1, 12.0, 150.0, 1, Color.RED)
};
public PlanetsCanvas(int w, int h)
{
width = w;
height = h;
centerX = (int)(w/2);
centerY = (int)(h/2);
}
protected void drawFrame(Graphics g)
{
//Sun
g.setColor(Color.YELLOW);
g.fillOval(width/2 - 25, height/2 - 25, 50, 50);
for (int i = 0; i < planets.length; i++)
{
Planet p = planets[i];
g.setColor(p.getColor());
int newX = (int)(centerX + Math.cos(p.getAngle())*p.getRadiusOrbit());
int newY = (int)(centerY - Math.sin(p.getAngle())*p.getRadiusOrbit());
g.fillOval((int)(newX-p.getRadius()),
(int)(newY-p.getRadius()),
(int)p.getRadius()*2, (int)p.getRadius()*2);
//int angle = (int)(p.getAngle() + p.getVelocity());
//if (angle >= 360) angle = 0;
//p.setAngle(angle);
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
drawFrame(g);
startAnimation();
}
public void startAnimation() {
runner = new Thread() {
public void run() {
try {
while (!Thread.interrupted()) {
repaint();
for(int i=0; i<planets.length; i++)
{
Planet p = planets[i];
int angle = (int)(p.getAngle() + p.getVelocity());
if (angle >= 360) angle = 0;
p.setAngle(angle);
}
Thread.sleep(500);
}
} catch (Exception e) {
}
}
};
runner.start();
running = true;
}
}
Most important -- don't start your animation from within paintComponent. The paintcomponent method will keep being called over and over again, meaning you're going to be creating more and more animation threads unnecessarily, when only one is what's called for. What's worse, you do not have complete control over when or even if paintComponent is called. So instead start your animation thread once and likely in your class's constructor.
Consider following points
Your startAnimation() method should be called once only and not in paintComponent() method which will instantiate a new thread on every repaint()
Apart from that keep the angle a double type as this will allow you to make arbitrarily small increments and decrements to it.
Thead.sleep() interval should be the single frame time.
Maintain a DAMPING_COFFICIENT to multiply to velocity when calculating new angle to slow down or speed up.
Here's modified slowed down code.
import java.awt.Color;
public class Planet {
private String name;
private int id;
private double radius = 1.0;
private double radiusOrbit = 5.0;
private double velocity = 1;
private Color color;
private double angle = 0;
private String parent;
public Planet(String name, int id, double rad, double radOrbit,
double velocity, Color color) {
this.name = name;
this.id = id;
this.radius = rad;
this.radiusOrbit = radOrbit;
this.velocity = velocity;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getRadiusOrbit() {
return radiusOrbit;
}
public void setRadiusOrbit(double radiusOrbit) {
this.radiusOrbit = radiusOrbit;
}
public double getVelocity() {
return velocity;
}
public void setVelocity(double velocity) {
this.velocity = velocity;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public String getParent() {
return parent;
}
public void setParent(String parent) {
this.parent = parent;
}
public double getAngle() {
return angle;
}
public void setAngle(double angle) {
this.angle = angle;
}
}
Rest of the classes
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ShowCosmos2 {
public static void main(String[] args) {
JFrame frame = new PlanetsFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class PlanetsFrame extends JFrame {
private int width = Toolkit.getDefaultToolkit().getScreenSize().width;
private int height = Toolkit.getDefaultToolkit().getScreenSize().height;
public PlanetsFrame() {
setSize(width, height);
setTitle("Planets");
setContentPane(new PlanetsCanvas(width, height));
Container contentPane = getContentPane();
contentPane.setBackground(Color.BLACK);
}
}
class PlanetsCanvas extends JPanel {
private static final double DAMPING_COFFICIENT = 0.01;
private static final int FRAMES_PER_SECOND = 60;
private static final long FRAME_DURATION = (1000 / FRAMES_PER_SECOND);
private int width, height;
private int centerX = 0;
private int centerY = 0;
private Thread runner;
private boolean running = false;
Planet[] planets = { new Planet("Venera", 1, 5.0, 50.0, 1, Color.GREEN),
new Planet("Mercury", 1, 3.0, 75.0, 1.5, Color.ORANGE),
new Planet("Earth", 1, 6.0, 100.0, 2, Color.BLUE),
new Planet("Jupiter", 1, 12.0, 150.0, 1, Color.RED) };
public PlanetsCanvas(int w, int h) {
width = w;
height = h;
centerX = (int) (w / 2);
centerY = (int) (h / 2);
startAnimation();
}
protected void drawFrame(Graphics g) {
// Sun
g.setColor(Color.YELLOW);
g.fillOval(width / 2 - 25, height / 2 - 25, 50, 50);
for (int i = 0; i < planets.length; i++) {
Planet p = planets[i];
g.setColor(p.getColor());
int newX = (int) (centerX + Math.cos(p.getAngle())
* p.getRadiusOrbit());
int newY = (int) (centerY - Math.sin(p.getAngle())
* p.getRadiusOrbit());
g.fillOval((int) (newX - p.getRadius()),
(int) (newY - p.getRadius()), (int) p.getRadius() * 2,
(int) p.getRadius() * 2);
// int angle = (int)(p.getAngle() + p.getVelocity());
// if (angle >= 360) angle = 0;
// p.setAngle(angle);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawFrame(g);
}
public void startAnimation() {
runner = new Thread() {
public void run() {
try {
while (!Thread.interrupted()) {
repaint();
for (Planet p : planets) {
double angle = (p.getAngle() + p.getVelocity() * DAMPING_COFFICIENT);
//System.out.println(p.getName() + " : " + angle);
if (angle >= 360)
angle = 0;
p.setAngle(angle);
}
Thread.sleep(FRAME_DURATION);
}
} catch (Exception e) {
}
}
};
runner.start();
running = true;
}
}
.

circle object constructor not defined

I am trying to make class circle extend the Shape class but keep getting a error from JUnit saying the constructor Circle(Point, int) is undefined how would i define the Circle constructor differently from public Circle(Point[] center, int aradius)?
import java.awt.Point;
public abstract class Shape {
private String name;
private Point[] points;
protected Shape(){};
protected Shape(String aName) {
name = aName;
}
public final String getName() {
// TODO Implement method
return name;
}
protected final void setPoints(Point[] thePoints) {
points = thePoints;
}
public final Point[] getPoints() {
// TODO Implement method
return points;
}
public abstract double getPerimeter();
public static double getDistance(Point one, Point two) {
double x = one.getX();
double y = one.getY();
double x2 = two.getX();
double y2 = two.getY();
double x3 = x - x2;
double y3 = y - y2;
double ypow = Math.pow(y3, 2);
double xpow = Math.pow(x3, 2);
double added = xpow + ypow;
double distance = Math.sqrt(added);
return distance;
}
}
Circle.java
import java.awt.Point;
public class Circle extends Shape{
private double radius;
public Circle(Point[] center, int aradius) {
if(radius < 0){
radius = 0;
}
else{
radius = aradius;
}
this.setPoints(center);
}
#Override
public double getPerimeter() {
double perim = 2 * Math.PI * radius;
return perim;
}
public double getRadius(){
return radius;
}
}
Just pass it a single Point, not an array.
public Circle(Point center, int aradius)

problem with extending classes

I'm making Braid. I have a class Wall that prevents that an object goes into a wall.
Everything with Wall is working. But now I'm trying to make the same with the ceilings.
My ceiling class extends Wall. I've simply made a constructor like this:
public Ceiling(boolean deadly, int[] xPositions, int[] yPositions)
{
super(deadly,
Direction.Down, //Enum: the direction you have to leave the wall (Left, Right)
//Here of course down
xPositions, yPositions);
}
Now I have in my level-class an ArrayList of all the Walls and an ArrayList of all the Ceilings.
I have to add the Walls on this way:
walls.add(new Wall(false, Direction.Right, ..., ...));
And the Ceilings on this way:
ceilings.add(new Ceiling(false, ..., ...));
The ... replaces the coordinates.
If I check if there is an object in a Ceiling: there has nothing happened: the object goes through the ceiling. And if I use this way to add a Ceiling, it works:
ceilings.add(new Wall(false, Direction.Down, ..., ...));
I hope I've explained well.
Does somebody know what the problem is??
Thanks
Edit:
This is my collition code:
public boolean intersects(Rectangle r)
{
if (!bounds.intersects(r))
{
return false;
}
for (int i = 1; i < yPositions.length; i++) {
Line l = new Line(xPositions[i - 1], yPositions[i - 1], xPositions[i], yPositions[i]);
if (r.intersectsLine(l)) {
return true;
}
}
return false;
}
My Code
'doodelijk' means deadly
Wall:
package levels;
import domein.Direction;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
public class Wall
{
public boolean doodelijk;
public int[] yPositions;
public int[] xPositions;
private Rectangle bounds;
public Direction directionToLeave;
public Wall(boolean doodelijk, Direction directionToLeave, int[] yPositions, int[] xPositions)
{
this.doodelijk = doodelijk;
this.yPositions = yPositions;
this.xPositions = xPositions;
this.directionToLeave = directionToLeave;
createRectangle();
}
public boolean intersects(Rectangle r)
{
if (!bounds.intersects(r))
{
return false;
}
for (int i = 1; i < yPositions.length; i++) {
Line l = new Line(xPositions[i - 1], yPositions[i - 1], xPositions[i], yPositions[i]);
if (r.intersectsLine(l)) {
return true;
}
}
return false;
}
private void createRectangle()
{
int x = Integer.MAX_VALUE;
int y = Integer.MAX_VALUE;
int x1 = 0;
int y1 = 0;
for (int i = 0; i < xPositions.length; i++)
{
int tx = xPositions[i];
int ty = yPositions[i];
if (x > tx)
{
x = tx;
}
if (y > ty)
{
y = ty;
}
if (x1 < tx)
{
x1 = tx;
}
if (y1 < ty)
{
y1 = ty;
}
}
bounds = new Rectangle(x, y, x1 - x + 1, y1 - y +1);
System.out.println("Rect: " + bounds);
}
class Line extends Line2D
{
Point2D p1;
Point2D p2;
public Line()
{
p1 = new Point();
p2 = new Point();
}
public Line(Point2D p1, Point2D p2)
{
this.p1 = p1;
this.p2 = p2;
}
public Line(double X1, double Y1, double X2, double Y2)
{
this();
setLine(X1, Y1, X2, Y2);
}
#Override
public double getX1()
{
return p1.getX();
}
#Override
public double getY1()
{
return p1.getY();
}
#Override
public Point2D getP1()
{
return p1;
}
#Override
public double getX2()
{
return p2.getX();
}
#Override
public double getY2()
{
return p2.getY();
}
#Override
public Point2D getP2()
{
return p2;
}
#Override
public void setLine(double X1, double Y1, double X2, double Y2)
{
p1.setLocation(X1, Y1);
p2.setLocation(X2, Y2);
}
public Rectangle2D getBounds2D()
{
return new Rectangle((int) getX1(), (int) getY1(), (int) (getX2() - getX1()), (int) (getX2() - getY1()));
}
}
public void setXpositions(int ... xPos)
{
this.xPositions = xPos;
}
public void setYpositions(int ... yPos)
{
this.yPositions = yPos;
}
public void setPositions(int[] yPos, int[] xPos)
{
setXpositions(xPos);
setYpositions(yPos);
}
}
Ceiling:
package levels;
import domein.Direction;
public class Ceiling extends Wall
{
public Ceiling(boolean doodelijk, int[] xPositions, int[] yPositions)
{
super(doodelijk, Direction.Down, yPositions, xPositions);
}
}
Are you sure about your settings of the xposition and yposition arguments? That is, is the ceiling really where you think it is? Is it the same in your two variants of the constructor?
I guess the problem is in the code that checks for the "collision". I cant see any problem in the one you've given.
I don't see any obvious problems with your classes. There might be a bug somewhere else and you would have to post the complete classes for us to identify it.

Categories

Resources