> For the complete documentation index, see [llms.txt](https://nissan-goldberg.gitbook.io/java101/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://nissan-goldberg.gitbook.io/java101/lesson-8-oop/exercise-creating-circles.md).

# Exercise: Creating circles

## Exercise: Circle - Part I

`Point`

* contains x and y
* copy `Point.java`

```java
class Point {
    private double x, y;

    //=== constructors ===

    //default constructor
    Point() {
        x =0;
        y = 0;
    }

    Point(double new_x, double y) {
        x = new_x;
        this.y = y;
    }

    //copy constructor
    Point(Point p) {
        x = p.x; // Since this is the same class I can access without getter/setter
        y = p.y;
    }

    //=== static methods ===
    public static double distance(Point a, Point b) {
        double dist = Math.pow(a.x-b.x, 2) + Math.pow(a.y-b.y, 2);
        return Math.sqrt(dist);
    }

    //=== getters and setters ===
    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public String toString() {
        return "Point {" + " x=" + x + ", y=" + y + " }";
    }
}
```

**Write the following class:**

* `Circle`&#x20;
  * contains a **point** and **radius**&#x20;

![](https://i.ibb.co/Gcnfwts/circles-oop.jpg)

the `Circle` class should include the following functions (methods):

* 3 constructors
  * default constructor
  * copy constructor
  * `Circle(double x, double y, double radius)`
* **getters** and **setters** (for point and radius)
* `public static boolean intersect(Circle a, Circle b)`
* `public double circumference ()`
* `public double area()`
* `toString()`

### Solution

{% tabs %}
{% tab title="Main.java" %}

```java
public class Main {
    public static void main(String[] args) {
        Circle circle1 = new Circle(0, 3, 5);
        Circle circle2 = new Circle(0, 12.9, 5);

        System.out.println(circle1);
        System.out.println(circle2.toString()); //same as System.out.println(circle2)

        boolean doesIntersect = Circle.intersect(circle1, circle2);
        System.out.println("Intersects? " + doesIntersect);

        System.out.println("Area of circle1: " + circle1.circumference() );
    }
}
```

{% endtab %}

{% tab title="Circle.java" %}

```java
class Circle {
    private Point point;
    private double radius;

    Circle() {
        point = new Point();
    }

    Circle(double x, double y, double radius) {
        this.radius = radius;
        point = new Point(x,y);
    }

    Circle(Circle other) {
        point.setX(other.point.getX());
        point.setY(other.point.getY());
        radius = other.radius; // Since this is the same class I can access without getter/setter
    }

    //=== static methods ===
    public static boolean intersect(Circle a, Circle b) {
        double distance =  Point.distance(a.point, b.point);
        return (distance <= a.radius + b.radius);
    }

    public double circumference () {
        return 2 * Math.PI * radius;
    }

    public double area() {
        return Math.PI * Math.pow(radius, 2);
    }

    // === getters and setter ===
    public Point getPoint() {
        return point;
    }

    public double getRadius() {
        return radius;
    }

    public String toString() {
        return "Circle{ " + point+ ", radius=" + radius + " }";
    }

}
```

{% endtab %}

{% tab title="Point.java" %}

```java
class Point {
    private double x, y;

    //=== constructors ===

    //default constructor
    Point() {
        x =0;
        y = 0;
    }

    Point(double new_x, double y) {
        x = new_x;
        this.y = y;
    }

    //copy constructor
    Point(Point p) {
        x = p.x; // Since this is the same class I can access without getter/setter
        y = p.y;
    }

    //=== static methods ===
    public static double distance(Point a, Point b) {
        double dist = Math.pow(a.x-b.x, 2) + Math.pow(a.y-b.y, 2);
        return Math.sqrt(dist);
    }

    //=== getters and setters ===
    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public String toString() {
        return "Point {" + " x=" + x + ", y=" + y + " }";
    }
}
```

{% endtab %}
{% endtabs %}

```
Circle { Point { x=0.0, y=3.0 }, radius=5.0 }
Circle { Point { x=0.0, y=12.9 }, radius=5.0 }
Intersects? true
Area of circle1: 31.41592653589793
```

## Exercise: Circle - Part II - adding intersections and random circles

add the following functions to `Circle`

* `intersect` - return if 2 circles intersect
* `intersections` - **print** all the circles that intersect
* `createRandomCircles` - generate x amount of random circles

```java
class Circle {
    //add before

    //=== static methods ===
    public static boolean intersect(Circle a, Circle b) {
        //your code
    }


    public static void intersections(Circle[] circles) {
       //your code
    }

    public static Circle[] createRandomCircles(int amount){
        //your code
    }
}



public class Main {
    public static void main(String[] args) {
        //Circle[] circles = new Circle[]{ new Circle(0, 3, 5), new Circle(0, 13, 5)};
        Circle[] circles = Circle.createRandomCircles(10);

        Circle.intersections(circles);
    }
}
```

#### Solution

```java
class Circle {
    //add before

    //=== static methods ===
    public static boolean intersect(Circle a, Circle b) {
        double distance =  Point.distance(a.point, b.point);
        return (distance <= a.radius + b.radius);
    }


    public static void intersections(Circle[] circles) {
        boolean[][] checked = new boolean[circles.length][circles.length]; //default is false

        for (int i = 0; i < circles.length; i++) 
            for (int j = 0; j < circles.length; j++) 
                if (i!=j && !(checked[i][j]) && intersect(circles[i], circles[j])){
                    System.out.println(circles[i] + " and " + circles[j] + " intersect");
                    checked[i][j] = true;
                    checked[j][i] = true;
                }
    }

    public static Circle[] createRandomCircles(int amount){
        Circle[] circles = new Circle[amount];
        int min_point = -30;
        int max_point =  30;
        int min_radius = 2;
        int max_radius = 5;

        for (int i = 0; i < circles.length; i++) {
            double x = (int) ((Math.random() * ((max_point+1) - min_point)) + min_point);
            double y = (int) ((Math.random() * ((max_point+1) - min_point)) + min_point);
            double radius = (int) ((Math.random() * ((max_radius+1) - min_radius)) + min_radius);
            circles[i] = new Circle(x, y, radius);
        }

        return circles;
    }
}
```

## Exercise: Circle - Part III - drawing circles with StdDraw

add the following functions to `Circle`

* `draw` - draw the circle (non static)
* `setWindowForCircles` - set the window size, find: *min of x, min of y, max of x and max of y*
  * find the 4 edges of the window
  * Then use `StdDraw.setXscale()` and `StdDraw.setYscale()`

```java
import java.awt.Color;
import java.awt.Font;

class Circle {
    //add before ...
    public static void setWindowForCircles(Circle[] circles){
        //your code

        //fill in the functions: 
        // StdDraw.setXscale();
        // StdDraw.setYscale();
    }

   public void draw() {
        //your code
    }
}
```

```java
public class Main {
    public static void main(String[] args) {
        Circle[] circles = Circle.createRandomCircles(10);

        Circle.setWindowForCircles(circles);
        Circle.intersections(circles);

        for (int i = 0; i < circles.length; i++){
            circles[i].draw();
//            System.out.println(circles[i]);
        }
    }
}
```

#### Solution

{% tabs %}
{% tab title="Main.java" %}

```java
public class Main {
    public static void main(String[] args) {
        Circle[] circles = Circle.createRandomCircles(10);

        Circle.setWindowForCircles(circles);
        Circle.intersections(circles);

        for (int i = 0; i < circles.length; i++){
            circles[i].draw();
//            System.out.println(circles[i]);
        }
    }
}
```

{% endtab %}

{% tab title="Java" %}

```java
class Circle {
    //add before

    //=== static methods ===
    public static void setWindowForCircles(Circle[] circles){
        Circle[] mins = new Circle[2];
        Circle min_x_circle = circles[0];
        Circle min_y_circle = circles[0];
        Circle[] max = new Circle[2];
        Circle max_x_circle = circles[0];
        Circle max_y_circle = circles[0];

        for (int i = 0; i < circles.length; i++) {
            if (max_x_circle.getPoint().getX() < circles[i].getPoint().getX())
                max_x_circle = circles[i];

            if (max_y_circle.getPoint().getY() < circles[i].getPoint().getY())
                max_y_circle = circles[i];

            if (min_x_circle.getPoint().getX() > circles[i].getPoint().getX())
                min_x_circle = circles[i];

            if (min_y_circle.getPoint().getY() > circles[i].getPoint().getY())
                min_y_circle = circles[i];
        }


        StdDraw.setXscale(min_x_circle.getPoint().getX()-min_x_circle.radius, max_x_circle.getPoint().getX()+max_x_circle.radius);
        StdDraw.setYscale(min_y_circle.getPoint().getY()-min_y_circle.radius, max_y_circle.getPoint().getY()+max_y_circle.radius);
    }


    public void draw() {
        int r =  (int) (Math.random() * 256);
        int g =  (int) (Math.random() * 256);
        int b =  (int) (Math.random() * 256);
        StdDraw.setPenColor(new Color(r, g, b));
        StdDraw.filledCircle(point.getX(), point.getY(), radius);
        StdDraw.setPenColor(Color.DARK_GRAY); // give grey edge to circle

        StdDraw.circle(point.getX(), point.getY(), radius);
    }
}
```

{% endtab %}
{% endtabs %}

![](https://i.ibb.co/Gcnfwts/circles-oop.jpg)

```
Circle { Point { x=29.0, y=17.0 }, radius=4.0 } and Circle { Point { x=27.0, y=16.0 }, radius=2.0 } intersect
```

### Code until now

![](https://i.ibb.co/0XyCbyM/Floating-Balls.gif)

> To make the circles move we add some **dx** and **dy** to their position, also we can increase and decrease their size. We also have to in account the boundary of the window.

{% tabs %}
{% tab title="Main.java" %}

```java
public class Main {
    public static void main(String[] args) {
        Circle[] circles = Circle.createRandomCircles(10);
        Circle.setWindowForCircles(circles);

        Circle.intersections(circles);

        for (int i = 0; i < circles.length; i++){
            circles[i].draw();
//            System.out.println(circles[i]);
        }
    }
}
```

{% endtab %}

{% tab title="Circle.java" %}

```java
import java.awt.Color;
import java.awt.Font;

class Circle {
    private Point point;
    private double radius;

    Circle() {
        point = new Point();
    }

    Circle(double x, double y, double radius) {
        this.radius = radius;
        point = new Point(x,y);
    }

    Circle(Circle other) {
        point.setX(other.point.getX());
        point.setY(other.point.getY());
        radius = other.radius; // Since this is the same class I can access without getter/setter
    }

    //=== static methods ===
    public static boolean intersect(Circle a, Circle b) {
        double distance =  Point.distance(a.point, b.point);
        return (distance <= a.radius + b.radius);
    }

    public double circumference () {
        return 2 * Math.PI * radius;
    }

    public double area() {
        return Math.PI * Math.pow(radius, 2);
    }


    // === getters and setter ===
    public Point getPoint() {
        return point;
    }

    public double getRadius() {
        return radius;
    }

    public void draw() {
        int r =  (int) (Math.random() * 256);
        int g =  (int) (Math.random() * 256);
        int b =  (int) (Math.random() * 256);
        StdDraw.setPenColor(new Color(r, g, b));
        StdDraw.filledCircle(point.getX(), point.getY(), radius);
        StdDraw.setPenColor(Color.DARK_GRAY);

        StdDraw.circle(point.getX(), point.getY(), radius);
    }

    public String toString() {
        return "Circle{ " + point+ ", radius=" + radius + " }";
    }

    //find min and max circles
    // and set  StdDraw.setXscale and StdDraw.setYscale
    public static void setWindowForCircles(Circle[] circles){
        Circle[] mins = new Circle[2];
        Circle min_x_circle = circles[0];
        Circle min_y_circle = circles[0];
        Circle[] max = new Circle[2];
        Circle max_x_circle = circles[0];
        Circle max_y_circle = circles[0];

        for (int i = 0; i < circles.length; i++) {
            if (max_x_circle.getPoint().getX() < circles[i].getPoint().getX())
                max_x_circle = circles[i];

            if (max_y_circle.getPoint().getY() < circles[i].getPoint().getY())
                max_y_circle = circles[i];

            if (min_x_circle.getPoint().getX() > circles[i].getPoint().getX())
                min_x_circle = circles[i];

            if (min_y_circle.getPoint().getY() > circles[i].getPoint().getY())
                min_y_circle = circles[i];
        }

        StdDraw.setXscale(min_x_circle.getPoint().getX()-min_x_circle.radius, max_x_circle.getPoint().getX()+max_x_circle.radius);
        StdDraw.setYscale(min_y_circle.getPoint().getY()-min_y_circle.radius, max_y_circle.getPoint().getY()+max_y_circle.radius);
    }

    public static Circle[] createRandomCircles(int amount){
        Circle[] circles = new Circle[amount];
        int min_point = -30;
        int max_point =  30;
        int min_radius = 2;
        int max_radius = 5;

        for (int i = 0; i < circles.length; i++) {
            double x = (int) ((Math.random() * ((max_point+1) - min_point)) + min_point);
            double y = (int) ((Math.random() * ((max_point+1) - min_point)) + min_point);
            double radius = (int) ((Math.random() * ((max_radius+1) - min_radius)) + min_radius);
            circles[i] = new Circle(x, y, radius);
        }

        return circles;
    }

    public static void intersections(Circle[] circles) {
        boolean[][] checked = new boolean[circles.length][circles.length]; //default is false

        for (int i = 0; i < circles.length; i++)
            for (int j = 0; j < circles.length; j++)
                if (i!=j && !(checked[i][j]) && intersect(circles[i], circles[j])){
                    System.out.println(circles[i] + " and " + circles[j] + " intersect");
                    checked[i][j] = true;
                    checked[j][i] = true;
                }
    }

}
```

{% endtab %}

{% tab title="Point.java" %}

```java
class Point {
    private double x, y;

    //=== constructors ===

    //default constructor
    Point() {
        x =0;
        y = 0;
    }

    Point(double new_x, double y) {
        x = new_x;
        this.y = y;
    }

    //copy constructor
    Point(Point p) {
        x = p.x; // Since this is the same class I can access without getter/setter
        y = p.y;
    }

    //=== static methods ===
    public static double distance(Point a, Point b) {
        double dist = Math.pow(a.x-b.x, 2) + Math.pow(a.y-b.y, 2);
        return Math.sqrt(dist);
    }

    //=== getters and setters ===
    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public String toString() {
        return "Point {" + " x=" + x + ", y=" + y + " }";
    }
}
```

{% endtab %}
{% endtabs %}
