Hi there!
If you draw a closed shape in processing, is there a way to get all points/pixels that the shape encloses in a separate array?
Best wishes,
Wouter
Hi there!
If you draw a closed shape in processing, is there a way to get all points/pixels that the shape encloses in a separate array?
Best wishes,
Wouter
Hi @Wouter,
Welcome to the forum!
There’s probably multiple ways to do this but one that came to my mind:
Use a separate PGraphics
instance to display your shape and then loop over all the pixels of the canvas and filter those who are exactly the color that you drew.
This might be expensive to compute depending on the size of the off-screen canvas but then you can draw complex flat shapes (by combining a circle and a square for example, mixing fill and stroke…) and it will work.
Don’t hesitate to ask if you have more questions!
What is your goal with the array?
Thanks for all comments! For example if you want to rotate only a subselection of an image. I would draw a shape, get all these pixels and do a coordinate transformation. But there might be other options?
Are you working on a drawing program?
Your way is certainly possible.
It might be easier though when you store the shapes in an ArrayList (and not put all pixels to the canvas directly)
you could also work with different layers of PGraphics.
Example with ArrayList
Here you have access to each item and could change size and rotation also (when you program this). Hence you don’t need to know the pixels in the first place.
ArrayList<Shape> list = new ArrayList();
int currentShapeToGenerate = 0;
boolean hold = false;
int i_hold=0;
String[] texts = {
"circle",
"square",
"triangle"
};
// -----------------------------------------------------------------------------------------------
void setup() {
size(1000, 700);
}
void draw() {
background(0);
// display all
int i=0;
for (Shape d : list) {
// set col
fill(255);
if (hold&&i==i_hold) {
fill(255, 0, 0);
}
// display
d.display();
// d.move();
i++;
}//for
// drag
if (hold) {
list.get(i_hold).setX( mouseX);
list.get(i_hold).setY( mouseY);
}
// text
fill(255);
text ("Use 0,1,2, click mouse, use Backspace and 'c'.\nUse right mouse to drag previous items. \n"+ texts[ currentShapeToGenerate ], 17, 17);
}
// -----------------------------------------------------------------------------------------------
void mousePressed() {
if (mouseButton == LEFT ) { // ----------------------------------
Shape newShape = null ;
switch( currentShapeToGenerate ) {
case 0:
newShape = new shapeCircle (mouseX, mouseY);
break;
case 1:
newShape = new shapeSquare (mouseX, mouseY);
break;
case 2:
newShape = new shapeTriangle (mouseX, mouseY);
break;
}//switch
// add
if (newShape!=null)
list.add(newShape);
} else {
// right mouse ------------------------------
int i=0;
for (Shape d : list) {
if (dist(mouseX, mouseY, d.getX(), d.getY())<11) {
//
hold=true;
(i_hold)=i;
}
i++;
}
}
}//func
void mouseReleased() {
hold = false;
}
void keyPressed () {
if (key=='0'||key=='1'||key=='2') {
currentShapeToGenerate=int(key+"");
} else if (key==ESC) {
key=0;//kill Esc
} else if (key==BACKSPACE) {
//
if (list.size()>0)
list.remove(list.size()-1);
} else if (key=='c') {
list.clear();
}
//else if
//
}// func
// =============================================================================================
// not called directly
interface Shape {
void move();
void display();
float getX();
float getY();
void setX(float x_);
void setY(float y_);
} //interface
// =============================================================================================
class shapeCircle implements Shape {
float x = 50;
float y = 50;
shapeCircle(float x_, float y_) {
x=x_;
y=y_;
}
void move() {
x = x + random(-1, 1);
}
void display() {
ellipse(x, y, 16, 16);
}
Shape copy() {
return new shapeCircle(x, y);
}
float getX() {
return x;
}
float getY() {
return y;
}
void setX(float x_) {
x=x_;
}
void setY(float y_) {
y=y_;
}
} //class
// =============================================================================================
class shapeSquare implements Shape {
float x = 50;
float y = 50;
shapeSquare(float x_, float y_) {
x=x_;
y=y_;
}
void move() {
y = y + random(-1, 1);
}
void display() {
rect(x, y, 16, 16);
}
float getX() {
return x;
}
float getY() {
return y;
}
void setX(float x_) {
x=x_;
}
void setY(float y_) {
y=y_;
}
} //class
// =============================================================================================
class shapeTriangle implements Shape {
float x = 50;
float y = 50;
shapeTriangle(float x_, float y_) {
x=x_;
y=y_;
}
void move() {
y = y + random(-1, 1);
}
void display() {
triangle(x, y,
x+36, y,
x+3, y+39);
}
float getX() {
return x;
}
float getY() {
return y;
}
void setX(float x_) {
x=x_;
}
void setY(float y_) {
y=y_;
}
} //class
//
Another example
// Demo for Drawing Program with ArrayList
// for mouse is on item / drag
final float hotSpotSize = 22; // radius
// Help text
final String helpText =
"Use 0,1,2, click mouse, use Backspace and 'c'.\n"
+ "Use right mouse to drag previous items. \nWhen you hold an item (right mouse button) use cursor to change size and rotation, use DEL to remove.";
// shapes / items
ArrayList<Shape> listShapes = new ArrayList();
// the type we add
int currentShapeToGenerate = 0;
// current shape we are adding (from currentShapeToGenerate)
String[] texts = {
"circle",
"square",
"triangle"
};
// mouse drag
boolean hold = false;
int i_hold=0;
// -----------------------------------------------------------------------------------------------
// Core funcs
void setup() {
size(1000, 700);
}
void draw() {
background(0);
// display all
displayShapes();
// drag
dragItem();
// show when mouse is on Hot Spot
showSmallRedCircleOnHotSpot();
// text
showText();
}
// -----------------------------------------------------------------------------------------------
// Input funcs
void mousePressed() {
if (mouseButton == LEFT) { // ----------------------------------
Shape newShape = null ;
switch( currentShapeToGenerate ) {
case 0:
newShape = new shapeCircle (mouseX, mouseY);
break;
case 1:
newShape = new shapeSquare (mouseX, mouseY);
break;
case 2:
newShape = new shapeTriangle (mouseX, mouseY);
break;
}//switch
// add
if (newShape!=null) {
listShapes.add(newShape);
} //if
//
} else {
// right mouse button --------------------------------
// search the item to drag
int i=0;
for (Shape currentShape : listShapes) {
if ( currentShape.underMouse() ) {
// store the item to drag
hold=true;
i_hold=i;
return;
}
i++;
}
}
}//func
void mouseReleased() {
hold = false;
}
void keyPressed() {
// get keys:
// these first keys apply always ---
if (key=='0'||key=='1'||key=='2') {
currentShapeToGenerate=int(key+"");
} else if (key==ESC) {
key=0;//kill Esc
} else if (key==BACKSPACE) {
// delete last item
if (listShapes.size()>0)
listShapes.remove(listShapes.size()-1);
} else if (key=='c') {
listShapes.clear();
} else if ( hold && keyCode == DELETE ) { // these following keys only apply when we hold a shape ---
listShapes.remove(i_hold);
hold=false;
} else if ( hold && keyCode == LEFT ) {
listShapes.get(i_hold).incAngle();
} else if ( hold && keyCode == RIGHT ) {
listShapes.get(i_hold).decAngle();
} else if ( hold && keyCode == UP ) {
listShapes.get(i_hold).incSize();
} else if ( hold && keyCode == DOWN ) {
listShapes.get(i_hold).decSize();
}
//
}// func
// --------------------------------------------------------------------------------------------
// Other funcs
void displayShapes() {
stroke(0);
int i=0;
for (Shape currentShape : listShapes) {
// set color (hold / not hold)
fill(255); // White = not hold
if (hold && i==i_hold) {
fill(255, 0, 0); // Red = hold
}
// display
currentShape.display();
// currentShape.move();
i++;
}//for
}
void dragItem() {
if (hold) {
listShapes.get(i_hold).setX(mouseX);
listShapes.get(i_hold).setY(mouseY);
}//if
}
void showSmallRedCircleOnHotSpot() {
for (Shape currentShape : listShapes) {
if (currentShape.underMouse()) {
// display the empty red circle
currentShape.showSmallRectCircle();
return;
}//if
}//for
}
void showText() {
fill(255);
text (helpText
+ "\n"
+ "curent > "
+ texts[ currentShapeToGenerate ], 17, 17);
}
// =============================================================================================
// not called directly
interface Shape {
void display();
void move();
float getX();
float getY();
void setX(float x_);
void setY(float y_);
void incAngle();
void decAngle();
void incSize();
void decSize();
boolean underMouse();
void showSmallRectCircle();
} //interface
// =============================================================================================
class shapeCircle implements Shape {
float x = 50;
float y = 50;
float angle;
float size1=25;
shapeCircle(float x_, float y_) {
x=x_;
y=y_;
}
void move() {
x = x + random(-1, 1);
}
void display() {
fill(255);
ellipse(x, y, size1, size1);
}
Shape copy() {
return new shapeCircle(x, y);
}
// ------------------------------------------------
float getX() {
return x;
}
float getY() {
return y;
}
void setX(float x_) {
x=x_;
}
void setY(float y_) {
y=y_;
}
void incAngle() {
angle+=0.01;
}
void decAngle() {
angle-=0.01;
}
void incSize() {
size1+=1;
}
void decSize() {
size1-=1;
}
boolean underMouse() {
return
dist(mouseX, mouseY, x, y)<hotSpotSize;
}
void showSmallRectCircle() {
// display the empty red circle
noFill();
stroke(255, 0, 0);
circle(x, y, hotSpotSize);
}
} //class
// =============================================================================================
class shapeSquare implements Shape {
float x = 50;
float y = 50;
float angle=0;
float size1 = 25;
shapeSquare(float x_, float y_) {
x=x_;
y=y_;
}
void move() {
y = y + random(-1, 1);
}
void display() {
rectMode(CENTER);
push();
translate(x, y);
rotate(angle);
rect(0, 0, size1, size1);
pop();
//reset
rectMode(CORNER); // default mode
}
// ------------------------------------------------
float getX() {
return x;
}
float getY() {
return y;
}
void setX(float x_) {
x=x_;
}
void setY(float y_) {
y=y_;
}
void incAngle() {
angle+=0.01;
}
void decAngle() {
angle-=0.01;
}
void incSize() {
size1+=1;
}
void decSize() {
size1-=1;
}
boolean underMouse() {
return
dist(mouseX, mouseY, x, y)<hotSpotSize;
}
void showSmallRectCircle() {
// display the empty red circle
noFill();
stroke(255, 0, 0);
circle(x, y, hotSpotSize);
}
} //class
// =============================================================================================
class shapeTriangle implements Shape {
float x = 50;
float y = 50;
float angle;
float size1=25;
shapeTriangle(float x_, float y_) {
x=x_;
y=y_;
}
void move() {
y = y + random(-1, 1);
}
void display() {
push();
translate(x, y);
rotate(angle);
triangle(0, 0,
0-size1, 0,
0, 0+size1);
pop();
}
// ------------------------------------------------
float getX() {
return x;
}
float getY() {
return y;
}
void setX(float x_) {
x=x_;
}
void setY(float y_) {
y=y_;
}
void incAngle() {
angle+=0.01;
}
void decAngle() {
angle-=0.01;
}
void incSize() {
size1+=1;
}
void decSize() {
size1-=1;
}
boolean underMouse() {
return
dist(mouseX, mouseY, x, y)<hotSpotSize;
}
void showSmallRectCircle() {
// display the empty red circle
noFill();
stroke(255, 0, 0);
circle(x, y, hotSpotSize);
}
} //class
//
If it’s a simple shape like a rectangle selection, you can use the get()
function to grab the section of an image. You can then display it and rotate it freely.
Thanks a lot, I ll explore these options!!