# Constructor to create a new class instance by assignment

**URL:** <https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803>\
**Category:** Beginners\
**Created:** [May 12, 2020, 10:19pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803 "2020-05-12T22:19:32Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![ddownn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ddownn/32/2731_2.png) [@ddownn](https://discourse.processing.org/u/ddownn)\
**Post date:** [May 12, 2020, 10:19pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/1 "2020-05-12T22:19:32Z")

</div>

I was hoping I could create a new class instance by assignment like this:  
`innerRect = new Rect(outside.insetBy(m2, m2));`

Is there any way to let a class have an constructor that can take an instance of the same type?

Or do I have to say something like this:

```auto
PVector newOrigin = outerRect.insetBy(m2, m2).origin;
PVector newSize = outerRect.insetBy(m2, m2).sz;
innerRect = new Rect(newOrigin, newSize);

```

```auto
Rect outerRect, innerRect; 
float m1 = 20;
float m2 = 5;

void setup() {
   size(414, 600);

   outerRect = new Rect(m1, m1, width - m1 * 2, height - m1 * 2);
   innerRect = new Rect(outerRect.insetBy(m2, m2));
}

void draw() {
   background(127);
}

class Rect {

   PVector origin;
   PVector sz;

   Rect() {
      origin = new PVector();
      sz = new PVector();
   }

   Rect(PVector origin, PVector sz) {
      this.origin = origin;
      this.sz = sz;
   }

   Rect(float x, float y, float w, float h) {
      origin = new PVector(x, y);
      sz = new PVector(w, h);
   }

   Rect(Rect r) {
      return new Rect(r.origin, r.sz);
   }

   Rect insetBy(float dx, float dy) {
      PVector newSize = new PVector(this.w() - dx, this.h() - dy);
      PVector newOrigin = PVector.add(this.origin, center()).sub(PVector.div(newSize, 2)); // this.origin + center() - (newSize / 2)
      return new Rect(newOrigin, newSize);
   }

   PVector center() {
      return new PVector(midX(), midY());
   }

   float w() {
      return sz.x;
   }

   float h() {
      return sz.y;
   }

   float midX() {
      return origin.x + sz.x / 2;
   }

   float midY() {
      return origin.y + sz.y / 2;
   }
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [May 12, 2020, 10:34pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/2 "2020-05-12T22:34:08Z")

</div>

here is a working Sketch

please don’t say initializer but constructor

see [https://www.processing.org/tutorials/objects/](https://www.processing.org/tutorials/objects/)

Chrisir

**Full Sketch I**

```auto
Rect outerRect, innerRect; 
int m1 = 20;
int m2 = 5;

void setup() {
  size(1414, 900);

  outerRect = new Rect( new PVector(m1, m2), new PVector(width - m1 * 2, height - m1 * 2));
  innerRect = outerRect.copy() ;

  innerRect.origin.x=57;
  innerRect.origin.y=53;
}

void draw() {
  background(0);

  fill(0, 0, 255);
  outerRect.display();
  fill(255, 0, 255);
  innerRect.display();
}

// ===============================================================

class Rect {

  PVector origin; // pos 
  PVector sz; // size 

  // constr I
  Rect() {
    origin = new PVector();
    sz = new PVector();
  }

  // constr II
  Rect(PVector origin, PVector sz) {
    this.origin = origin.copy();
    this.sz = sz.copy();
  }

  // NOT a constr !!!!!!!!!!!!!!!!!
  Rect getMySelf (Rect r) {
    return 
      new Rect(r.origin, r.sz);
  }

  // NOT a constr !!!!!!!!!!!!!!!!!
  Rect copy() {
    return 
      new Rect(origin, sz);
  }

  // NOT a constr !!!!!!!!!!!!!!!!!
  void display() {
    rect(origin.x, origin.y, 
      sz.x, sz.y);
  }
  //
}//class

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [May 12, 2020, 10:37pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/3 "2020-05-12T22:37:48Z")

</div>

> [@ddownn](#):
>
> Is there any way to let a class have an constructor that can take an instance of the same type?

Yes.

This would take a rect as a parameter to instantiate a new Rect object.

see constr III

Chrisir

**Full Sketch II**

```auto
Rect outerRect, innerRect; 
int m1 = 20;
int m2 = 5;

void setup() {
  size(1414, 900);

  outerRect = new Rect( new PVector(m1, m2), new PVector(width - m1 * 2, height - m1 * 2));
  innerRect = new Rect( outerRect );

  //innerRect.origin.x=57;
  //innerRect.origin.y=53;
}

void draw() {
  background(0);

  fill(0, 0, 255);
  // outerRect.display();
  fill(255, 0, 255);
  innerRect.display();
}

// ===============================================================

class Rect {

  PVector origin; // pos 
  PVector sz; // size 

  // constr I
  Rect() {
    origin = new PVector();
    sz = new PVector();
  }

  // constr II
  Rect(PVector origin, PVector sz) {
    this.origin = origin.copy();
    this.sz = sz.copy();
  }

  // constr III
  Rect( Rect oldOne) {
    this.origin = oldOne.origin.copy();
    this.sz = oldOne.sz.copy();
  }

  // ---------------------------------------------------------------------------

  // NOT a constr !!!!!!!!!!!!!!!!!
  Rect getMySelf (Rect r) {
    return 
      new Rect(r.origin, r.sz);
  }

  // NOT a constr !!!!!!!!!!!!!!!!!
  Rect copy() {
    return 
      new Rect(origin, sz);
  }

  // NOT a constr !!!!!!!!!!!!!!!!!
  void display() {
    rect(origin.x, origin.y, 
      sz.x, sz.y);
  }
  //
}//class

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [May 12, 2020, 10:41pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/4 "2020-05-12T22:41:40Z")

</div>

> [@ddownn](#):
>
> insetBy

Sorry, I understood now what you mean.

Since your method insetBy returns a new Rect (the new is inside the method), just call it like this:  
` innerRect = outerRect.insetBy(m2, m2);`

Chrisir

**Full Sketch III**

```auto
Rect outerRect, innerRect; 
float m1 = 20;
float m2 = 5;

void setup() {
  size(414, 600);

  outerRect = new Rect(m1, m1, width - m1 * 2, height - m1 * 2);
  innerRect = outerRect.insetBy(m2, m2);
}

void draw() {
  background(127);

  fill(0, 0, 255);
  outerRect.display();
  fill(255, 0, 255);
  innerRect.display();
}

// ==========================================================================================

class Rect {

  PVector origin;
  PVector sz;

  Rect() {
    origin = new PVector();
    sz = new PVector();
  }

  Rect(PVector origin, PVector sz) {
    this.origin = origin;
    this.sz = sz;
  }

  Rect(float x, float y, float w, float h) {
    origin = new PVector(x, y);
    sz = new PVector(w, h);
  }

  // Rect(Rect r) {
  // return new Rect(r.origin, r.sz);
  // }

  Rect insetBy(float dx, float dy) {
    PVector newSize = new PVector(this.w() - dx, this.h() - dy);
    PVector newOrigin = PVector.add(this.origin, center()).sub(PVector.div(newSize, 2)); // this.origin + center() - (newSize / 2)
    return new Rect(newOrigin, newSize);
  }

  PVector center() {
    return new PVector(midX(), midY());
  }

  float w() {
    return sz.x;
  }

  float h() {
    return sz.y;
  }

  float midX() {
    return origin.x + sz.x / 2;
  }

  float midY() {
    return origin.y + sz.y / 2;
  }

  // NOT a constr !!!!!!!!!!!!!!!!!
  void display() {
    rect(origin.x, origin.y, 
      sz.x, sz.y);
  }
}

```

---

<div class="post-metadata">

**Author:** ![ddownn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ddownn/32/2731_2.png) [@ddownn](https://discourse.processing.org/u/ddownn)\
**Post date:** [May 12, 2020, 11:44pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/5 "2020-05-12T23:44:54Z")

</div>

> [@Chrisir](#):
>
> Since your method insetBy returns a new Rect (the new is inside the method), just call it like this:  
> ` innerRect = outerRect.insetBy(m2, m2);`

That makes sense, thank you.

Another question, why isn’t the new rectangle actually inset on the right and bottom? It’s supposed to be uniformly smaller and still centered within the original rectangle.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [May 13, 2020, 7:00am UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/6 "2020-05-13T07:00:12Z")

</div>

rect works with upper left corner

Look at rectMode()

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [May 13, 2020, 7:24am UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/7 "2020-05-13T07:24:16Z")

</div>

You can have one ctor use another one like this

```auto
   Rect(Rect r) {
      this(r.origin, r.sz);
   }

```

which would call this method

> [@ddownn](#):
>
> ```auto
> Rect(PVector origin, PVector sz) {
> this.origin = origin; // Does not copy PVector, the rects will share the PVector
> this.sz = sz;
> }
> 
> ```

You need to change the first line  
`this.origin = origin; // Does not copy PVector, the rects will share the PVector`  
to  
`this.origin = origin.copy(); `

copy() is a method in PVector that creates a new PVector based on the original

---

<div class="post-metadata">

**Author:** ![ddownn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ddownn/32/2731_2.png) [@ddownn](https://discourse.processing.org/u/ddownn)\
**Post date:** [May 13, 2020, 11:36am UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/8 "2020-05-13T11:36:04Z")

</div>

> [@ddownn](#):
>
> …why isn’t the new rectangle actually inset on the right and bottom?

Sorry, I should not have been adding the origin here:

```auto
PVector newOrigin = PVector.add(this.origin, center()).sub(PVector.div(newSize, 2)); // this.origin + center() - (newSize / 2)

```

This works as expected:

```auto
PVector newOrigin = PVector.sub(center(), (PVector.div(newSize, 2))); // center() - (newSize / 2)

```

Thanks everyone

Here is the whole thing which now works the way I wanted.

```auto
Rect outerRect, innerRect; 
float m1 = 20;
float m2 = 100;

void setup() {
   size(414, 600);

   outerRect = new Rect(m1, m1, width - m1 * 2, height - m1 * 2);
   
   // either of these now work to construct a new Rect and assign it to innerRect
   //innerRect = new Rect(outerRect.insetBy(m2, m2));
   innerRect = outerRect.insetBy(m2, m2);
}

void draw() {
   background(127);
   
   fill(0, 0, 255);
   outerRect.display();

   fill(255, 0, 255);
   innerRect.display();
}

// ==========================================================================================

class Rect {

   PVector origin;
   PVector sz;

   Rect() {
      origin = new PVector();
      sz = new PVector();
   }

   Rect(Rect r) {
      this(r.origin, r.sz);
   }

   Rect(PVector origin, PVector sz) {
      // this.origin = origin; // this is wrong - Does not copy PVector, the rects will share the PVector
      this.origin = origin.copy();
      this.sz = sz.copy();
   }

   Rect(float x, float y, float w, float h) {
      origin = new PVector(x, y);
      sz = new PVector(w, h);
   }

   Rect insetBy(float dx, float dy) {
      PVector newSize = new PVector(this.w() - dx * 2, this.h() - dy * 2);

      PVector newOrigin = PVector.sub(center(), PVector.div(newSize, 2)); // center() - (newSize / 2)

      return new Rect(newOrigin, newSize);
   }

   PVector center() {
      return new PVector(midX(), midY());
   }

   float w() {
      return sz.x;
   }

   float h() {
      return sz.y;
   }

   float midX() {
      return origin.x + sz.x / 2;
   }

   float midY() {
      return origin.y + sz.y / 2;
   }

   float maxX() {
      return origin.x + sz.x;
   }

   float maxY() {
      return origin.y + sz.y;
   }

   // NOT a constr !!!!!!!!!!!!!!!!!
   void display() {
      rect(origin.x, origin.y, 
         sz.x, sz.y);
   }
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [May 13, 2020, 11:42am UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/9 "2020-05-13T11:42:43Z")

</div>

As I said you should use rectMode(CENTER); or not?

Also, since `insetBy()` returns a new rect this line

```auto
 innerRect = new Rect(outerRect.insetBy(m2, m2));

```

can be

```auto
 innerRect = outerRect.insetBy(m2, m2);

```

---

<div class="post-metadata">

**Author:** ![ddownn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ddownn/32/2731_2.png) [@ddownn](https://discourse.processing.org/u/ddownn)\
**Post date:** [May 13, 2020, 11:57am UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/10 "2020-05-13T11:57:02Z")

</div>

> [@Chrisir](#):
>
> As I said you should use rectMode(CENTER); or not?

The plan was to use the default `rectMode(CORNER);`

> [@Chrisir](#):
>
> Also, since `insetBy()` returns a new rect this line
> 
> ```auto
> innerRect = new Rect(outerRect.insetBy(m2, m2));
> 
> ```
> 
> can be
> 
> ```auto
> innerRect = outerRect.insetBy(m2, m2);
> 
> ```

I see it is better to do it this way in this case.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [May 13, 2020, 2:18pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/11 "2020-05-13T14:18:39Z")

</div>

> [@ddownn](#):
>
> ```auto
> Rect(Rect r) {
> this(r.origin, r.sz);
> }
> 
> ```

Not sure if this is needed

---

<div class="post-metadata">

**Author:** ![ddownn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ddownn/32/2731_2.png) [@ddownn](https://discourse.processing.org/u/ddownn)\
**Post date:** [May 13, 2020, 7:17pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/13 "2020-05-13T19:17:10Z")

</div>

I guess not. I can’t think of any reason to have this.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [May 14, 2020, 11:10am UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/14 "2020-05-14T11:10:45Z")

</div>

here is my version with only one constructor

Chrisir

```auto

Rect outerRect, innerRect; 

void setup() {
  size(414, 600);

  float m1 = 20;
  float m2 = 100;

  outerRect = new Rect(
    new PVector(m1, m1), 
    new PVector(width - m1 * 2, height - m1 * 2));

  // either of these now work to construct a new Rect and assign it to innerRect
  //innerRect = new Rect(outerRect.insetBy(m2, m2));
  innerRect = outerRect.insetBy(m2, m2);
}//func 

void draw() {
  background(127);

  fill(0, 0, 255);
  outerRect.display();

  fill(255, 0, 255);
  innerRect.display();
}//func 

// ==========================================================================================

class Rect {

  PVector origin = new PVector();
  PVector sz = new PVector();

  Rect(PVector origin_, PVector sz_) {
    // this.origin = origin_; // this is wrong - Does not copy PVector, the rects will share the PVector
    origin = origin_.copy();
    sz = sz_.copy();
  } // constr 

  // ------------------------------------------------
  // methods of the class 

  Rect insetBy(float dx, float dy) {
    PVector newSize = new PVector(w() - dx * 2, h() - dy * 2);
    PVector newOrigin = PVector.sub(center(), PVector.div(newSize, 2)); 
    return new Rect(newOrigin, newSize);
  } // method 

  PVector center() {
    return new PVector(midX(), midY());
  }

  float w() {
    return sz.x;
  }

  float h() {
    return sz.y;
  }

  float midX() {
    return origin.x + w() / 2;
  }

  float midY() {
    return origin.y + h() / 2;
  }

  float maxX() {
    return origin.x + w();
  }

  float maxY() {
    return origin.y + h();
  }

  void display() {
    rect(origin.x, origin.y, 
      sz.x, sz.y);
  }
}//class
//

```

---

<div class="post-metadata">

**Author:** ![ddownn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ddownn/32/2731_2.png) [@ddownn](https://discourse.processing.org/u/ddownn)\
**Post date:** [May 14, 2020, 12:25pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/15 "2020-05-14T12:25:51Z")

</div>

These lines no longer apply, you might want to take them out of your example.

> [@Chrisir](#):
>
> ```auto
> // either of these now work to construct a new Rect and assign it to innerRect
> //innerRect = new Rect(outerRect.insetBy(m2, m2));
> 
> ```

This is nice to have if you are pretending to make a CGRect 😀

> [@ddownn](#):
>
> ```auto
> Rect(float x, float y, float w, float h) {
> origin = new PVector(x, y);
> sz = new PVector(w, h);
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [May 14, 2020, 12:30pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/16 "2020-05-14T12:30:58Z")

</div>

> [@ddownn](#):
>
> ```auto
> Rect(float x, float y, float w, float h) {
>      
> 
> ```

Yes

But it’s the same like with two PVectors

---

<div class="post-metadata">

**Author:** ![ddownn](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ddownn/32/2731_2.png) [@ddownn](https://discourse.processing.org/u/ddownn)\
**Post date:** [May 14, 2020, 12:43pm UTC](https://discourse.processing.org/t/constructor-to-create-a-new-class-instance-by-assignment/20803/17 "2020-05-14T12:43:12Z")

</div>

It is, but if you’re trying to use Processing to work out ideas for programming iOS, this one gets a lot more use generally. There is no Daniel Shiffman in the world of iOS programming telling everyone how nice it is to use Vectors instead of x, y. So all the drawing code is doubled, no one uses Vectors. If you want to use vector math at all, you have to write your own extensions. It’s bleak.
