ddownn
May 12, 2020, 10:19pm
1
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:
PVector newOrigin = outerRect.insetBy(m2, m2).origin;
PVector newSize = outerRect.insetBy(m2, m2).sz;
innerRect = new Rect(newOrigin, newSize);
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;
}
}
1 Like
here is a working Sketch
please don’t say initializer but constructor
see https://www.processing.org/tutorials/objects/
Chrisir
Full Sketch I
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
1 Like
Yes.
This would take a rect as a parameter to instantiate a new Rect object.
see constr III
Chrisir
Full Sketch II
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
2 Likes
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
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);
}
}
2 Likes
ddownn
May 12, 2020, 11:44pm
5
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.
rect works with upper left corner
Look at rectMode()
1 Like
quark
May 13, 2020, 7:24am
7
You can have one ctor use another one like this
Rect(Rect r) {
this(r.origin, r.sz);
}
which would call this method
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
3 Likes
ddownn
May 13, 2020, 11:36am
8
Sorry, I should not have been adding the origin here:
PVector newOrigin = PVector.add(this.origin, center()).sub(PVector.div(newSize, 2)); // this.origin + center() - (newSize / 2)
This works as expected:
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.
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);
}
}
1 Like
As I said you should use rectMode(CENTER); or not?
Also, since insetBy()
returns a new rect this line
innerRect = new Rect(outerRect.insetBy(m2, m2));
can be
innerRect = outerRect.insetBy(m2, m2);
ddownn
May 13, 2020, 11:57am
10
The plan was to use the default rectMode(CORNER);
Chrisir:
Also, since insetBy()
returns a new rect this line
innerRect = new Rect(outerRect.insetBy(m2, m2));
can be
innerRect = outerRect.insetBy(m2, m2);
I see it is better to do it this way in this case.
1 Like
Not sure if this is needed
ddownn
May 13, 2020, 7:17pm
13
I guess not. I can’t think of any reason to have this.
here is my version with only one constructor
Chrisir
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
//
1 Like
ddownn
May 14, 2020, 12:25pm
15
These lines no longer apply, you might want to take them out of your example.
This is nice to have if you are pretending to make a CGRect
ddownn:
Rect(float x, float y, float w, float h) {
origin = new PVector(x, y);
sz = new PVector(w, h);
}
1 Like
Yes
But it’s the same like with two PVectors
ddownn
May 14, 2020, 12:43pm
17
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.
1 Like