0

Basically this was a homework that I had to do about rectangles. The problem came when I needed to do simple math to calculate the x and y values of the vertices e.g. (x-width/2), and because i needed to use those values in more than one method, i created new variables in the class for that simple math (x1 = (x-width/2), x2, y1, y2 etc), for readability. For some reason, in my methods, using the variables produced wrong results. when I went back and replaced them with the math again, it worked.

My question is why are the variables i made (under //WEIRD VARIABLES) not working inside the contains method?

here is my code:

package com.example;

public class MyRectangle2D {
    double x,y;
    double width, height;
    //a couple of getters and setters
    //constructor
    MyRectangle2D(){
        x=0.0;
        y=0.0;
        width=1.0;
        height=1.0;
    }
    MyRectangle2D(double X, double Y, double Width, double Height){
        x=X;
        y=Y;
        width=Width;
        height=Height;
    }

    // WEIRD VARIABLES
    private double x1 = x-(width/2);
    private double x2 = (x+(width/2));
    private double y1 = (y-(height/2));
    private double y2 = (y+(height/2));

    //methods
    boolean contains(double X, double Y){
        /* initially wrote: 
           return (!( X<x1 || X>x2 || Y <y1 || Y>y2 )); 
           didnt work, bc for some reason x1,x2,y1,y2 were all 0.0
           the below works well: */
        return (!(X<(x-(width/2)) || X>(x+(width/2)) || Y <(y-(height/2)) || Y>(y+(height/2))));
    }


    public static void main(String[] args) {
        MyRectangle2D b = new MyRectangle2D(1, 2, 3, 4);
        System.out.println(b.x1); // 0.0 (should be -0.5)
        System.out.println(b.x); // 1.0 (correct)
        System.out.println(b. width); // 3.0 (correct)
        System.out.println("(1.0,2.0) in b? (true?) " + b.contains(1.0,2.0)); //true (correct)
    }
}

I'm perfectly fine just writing the math out again and again, but in my homework they wanted me to create a method to check if this rectangle contains another rectangle, like

    boolean contains(MyRectangle2D r){}

which means i need to write r.(x-(width/2)) <= (x-(width/2)) etc. to write my conditions, which seems tedious and messy. It seemed logical to me to create those x1,x2,y1,y2 variables as a form of shortcut, since the math were the same formula and it would be cleaner and I could directly use r.x1 instead of r.(x-(width/2))

tl;dr: when i println x1, it gives me 0.0, but when i println x-(width/2), it gives me -0.5, which is correct.

i've been trying to figure out why the math goes wrong but i'm still lost. any help would be much appreciated!

hamburgieees
  • 111
  • 2

2 Answers2

0

The assignment of fields during their declaration (like x1, x2, y1 and y2) are done after the call to super() and before any other statement in the constructor. In your case, that happens before the assignment of x, y, width and height so x1, x2, y1 and y2 will be 0, regardless if you place the field declarations before or after the constructor.

The solution is to move the assignment in the constructor, at the end.

rhobincu
  • 906
  • 1
  • 7
  • 22
0

This assignment bellow is being done before any constructor. Doesn't matter that the constructores come first. All the fields declaration are processed first.

 // WEIRD VARIABLES
    private double x1 = x-(width/2);
    private double x2 = (x+(width/2));
    private double y1 = (y-(height/2));
    private double y2 = (y+(height/2));

Maybe a solution for your problem is to make the assignment inside the contructor, like:

//declare the filds outside any method
private double x1;
private double x2;
private double y1;
private double y2;

MyRectangle2D(){
   //... Your normal code here
   buildWeird();
}
MyRectangle2D(double X, double Y, double Width, double Height){
    //... Your normal code here
    buildWeird();
}
private void buildWeird(){
    this.x1 = x-(width/2);
    this.x2 = (x+(width/2));
    this.y1 = (y-(height/2));
    this.y2 = (y+(height/2));
}