Hello everyone,
as far as you know is there a class or library to deal with Grid design systems?
I’m looking for something that could be helpful in composition of 2D images.
Thank you in advance.
Best
R_colors
Hello everyone,
as far as you know is there a class or library to deal with Grid design systems?
I’m looking for something that could be helpful in composition of 2D images.
Thank you in advance.
Best
R_colors
hi,
please help with more details,
a grid of x*y rectangles… is easy,
a grid like data table ( spreadsheet style ) difficult ( or needs a good library )
or
you talk a drawing aid grid like fine lines on the background every N pix?
but basically all grid are 2 nested for loops and one draw ?line? command.
example of a grid of rectangles
// smart grid of rectangles, fit to area / canvas
int x = 10, y = x, w = 0, h = w, offset = 5;
int grid = 4, many = grid*grid;
void setup() {
size(200, 300);
stroke(0, 0, 200);
fill(0, 200, 0);
auto_scale(true, width, height); //true / false / canvas or any aerea to fit in
}
void auto_scale(boolean scale, int wide, int high) { // autoscale w h
if ( scale ) {
w = (wide - 2*x)/grid - offset;
h = (high - 2*y)/grid - offset;
}
println("x "+x+" y "+y+" w "+w+" h "+h+" offset "+offset+" grid "+grid+" many "+many);
}
void draw() {
background(200, 200, 0);
for (int i = 0; i < many; i++) rect(x+(i%grid)*(w+offset), y+(floor(i/grid))*(h+offset), w, h); // or any other shape/text on that position
}
thanks for the fast reply,
I was loooking for something like a drawing aid, would be great something like this third part menu in photoshop.
https://guideguide.me/documentation/use-the-grid-form/
For now I was using some simple .svg files to superimpose the grid.
Trivial example:
PShape center,firds,fibo;
void setup() {
size(640, 360);
center = loadShape("data/Grid_Center.svg");
//thirds = loadShape("data/Grid_Thirds.svg");
//fibo = loadShape("data/Fibonacci_spiral.svg");
}
void draw() {
background(102);
shape(center, 0, 0, width, height);
}
But if there is a more algorithmic way of working, maybe using something already available I would really appreciate.
did you play with my example?
oh, you want that parameter window for this variables?
this comes in the next lesson.
I know that there is the ControlP5 library to make interfaces, and I use it.
But before those fancy stuff, I honestly have to take a step back.
I tried your sketck, I was using something similar time ago, and in some situations it’s perfect.
I think it’s implemented in this library: http://cloud.brendandawes.com/dawesometoolkit/
I took some hours to clarify myself, and to find the way to reply you properly.
It’s the first time that I use this kind of forum, and it’s a bit tricky.
I found some wonderful explanation that’ll help to visualize the main rules that I need.
But I can’t post it here because of the forum limitations to upload only one image for reply,
I’ll add in different ones.(if allowed)
A good starting point to keeping the problem simple, could be to have a look at the cropping menu in photoshop:
Nevertheless It’s possible to use those grids like drawing aids, that’s the point for me, NOT to crop anything.
I found some wonderful explanation that’ll help you visualize this rules.
My main needing now, is to have some simple grids like the most used:
The rule of thirds is a “rule of thumb” or guideline which applies to the process of composing visual images such as designs, films, paintings, and photographs. The guideline proposes that an image should be imagined as divided into nine equal parts by two equally spaced horizontal lines and two equally spaced vertical lines, and that important compositional elements should be
placed along these lines or their intersections.
DiagonalGrid[] d =new DiagonalGrid[4];
//int DISPLAY = 0; // choose manually
void setup() {
// you need to use a ratio 1.6 from the width-hight 400*1.6 = 640
size(640, 400);
background(255);
for (int i = 0; i<d.length; i++) {
d[i] = new DiagonalGrid(i+1);
}
showMeAll();
}
void drawInter(int i) {
fill(255, 0, 0, 126);
ellipse(d[i].getCross().x, d[i].getCross().y, 20, 20);
}
void showMeAll() {
for (int i=0; i<d.length; i++ ) {
d[i].drawDiagLines();
drawInter(i);
}
}
class
class DiagonalGrid{
// data USE FLOAT with int doesnt' work ...
float x1,x2,x3,x4,y1,y2,y3,y4 =0;
// implied constructor
DiagonalGrid(int w){
if(w >0 && w < 5)
switch(w){
case 1 :
// LEFT_TOP
x1 = 0;
y1 = 0;
x2 = height;
y2 = height;
//println("line 1: x1:"+x1+" y2: "+y1+" x2: "+x2+" y2: "+y2);
// RIGHT_TOP
x3 = width;
y3 = 0;
x4 = 0 ;
y4 = width;
//println("line 2: x3: "+x3+" y3: "+y3+" x4: "+x4+" y4: "+y4);
break;
case 2 :
// LEFT_B
x1 = 0;
y1 = height;
x2 = width;
y2 = height-width;
//println("line 1: x1:"+x1+" y2: "+y1+" x2: "+x2+" y2: "+y2);
// RIGHT_B
x3 = width;
y3 = height;
x4 = 0 ;
y4 = height-width;
//println("line 2: x3: "+x3+" y3: "+y3+" x4: "+x4+" y4: "+y4);
break;
case 3 :
// RIGHT_TOP
x1 = width;
y1 = 0;
x2 = 0 ;
y2 = width;
//println("line 1: x1:"+x1+" y2: "+y1+" x2: "+x2+" y2: "+y2);
// RIGHT_B
x3 = width;
y3 = height;
x4 = 0 ;
y4 = height-width;
break;
case 4 :
// LEFT_TOP
x1 = 0;
y1 = 0;
x2 = height;
y2 = height;
// LEFT_B
x3 = 0;
y3 = height;
x4 = width;
y4 = height-width;
break;
/*_________________*/
default:
println("ERROR in SWITCH/Case Constructor DiagonalGrid");
break;
}
}
// functions
void drawDiagLines(){
stroke(0,126);
strokeWeight(1);
line(x1,y1,x2,y2);
line(x3,y3,x4,y4);
}
// PVector of the intersection
PVector getCross() {
// calculate the distance to intersection point
float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
//println("(x4-x3)*(y1-y3) :"+ (x4-x3)*(y1-y3) +" - "+ "(y4-y3)*(x1-x3): "+(y4-y3)*(x1-x3)+ " = "+ ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) );
//println("(y4-y3)*(x2-x1) :"+ (y4-y3)*(x2-x1) +" - "+ "(x4-x3)*(y2-y1): "+(x4-x3)*(y2-y1)+ " = "+ ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1)) );
//println("IL PRIMO DIVISO PER IL SECONDO __ uA: "+uA);
float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
//println("UB _____________ IL PRIMO DIVISO PER IL SECONDO __ uB: "+uB);
//println("uA:"+uA+"uB:"+uB);
// intersection
PVector intersection = new PVector(x1 + (uA * (x2-x1)),y1 + (uA * (y2-y1))) ;
//println("intersection:"+intersection);
return intersection;
}
}
I opened one of Bresson’s images in Photoshop and used the Golden Ratio crop overlay. The two vertical lines fit almost perfectly above the facing ends of the two walls.
Notice how the girl is framed in the middle.
the first step in this direction is to find the point of intersection BD,CE
ORIGINAL CODE FROM http://www.jeffreythompson.org/collision-detection/line-line.php
LOWER RIGHT
float x1 = 0; // line controlled by mouse
float y1 = 0;
float x2 = 0; // fixed end
float y2 = 0;
float x3 = 0; // static line
float y3 = 0;
float x4 = 0;
float y4 = 0;
void setup() {
size(356,576);
strokeWeight(1); // make lines easier to see
}
void draw() {
background(255);
// set line's end to mouse coordinates
x1 = width;
y1 = height;
x3 = 0;
y3 = height;
x4 = width;
y4 = width;
// check for collision
// if hit, draw a circle
PVector hit = lineLine(x1,y1,x2,y2, x3,y3,x4,y4);
fill(255,0,0);
noStroke();
ellipse(hit.x,hit.y, 20,20);
stroke(255,150,0);
line(x3,y3, x4,y4);
stroke(0);
line(x1,y1, x2,y2);
}
// LINE/LINE
PVector lineLine(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
// calculate the distance to intersection point
float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
// intersection
PVector intersection = new PVector(x1 + (uA * (x2-x1)),y1 + (uA * (y2-y1))) ;
return intersection;
}
Said that would be very interesting to find a more algorithmic approach.
Would be great to find something similar to this other tool in photoshop to freely set all the parameters of a grid.
https://guideguide.me/documentation/use-the-grid-form/
//VECTOR System
And idially would be nice to have the coordinates maybe stored in an array of 2D vectors of the intersections of the lines to place the shapes(or texts, etc…)
in the “n” intersection:
like here first, second third firth, and the 4 verices.
with the possibility to navigate the different vectors, where intersections occurs, or to align to the left / rigt, top / bottom of the lines.
As well as the option to choose if the shape has to stay in the center or corner, for instances similar to rectMode(CENTER).
I know that I have too many ideas, but I’m trying to have a comprehensive view of the problem.
wow, yes, that is a nice project.
not sure that is of any help, but i have a
grid array of class version,
possibly makes the start easier?
// https://discourse.processing.org/t/scalable-grid-with-rectangles/7256
// https://discourse.processing.org/t/better-grid-performance/7314
// https://discourse.processing.org/t/gryd-system-graphic-design/10457
// use backup memory array for resize/reinit grid but remember selected rects
int x = 12, y = x, w = 50, h = w, grid = 10, many = grid*grid;
boolean auto = false;//false;//true;
boolean shownum = false; // key [n]
boolean showstroke = true;
boolean showFPS = true;
boolean togfill = true;
// color setup:
color bg = color(200, 200, 0);
color stk = color(0, 0, 200);
color fillsel = color(0, 200, 0);
color fillnsel= color(200, 0, 200);
Myrect[] myrects = new Myrect[many];
Mybackup[] myselects = new Mybackup[many]; // temporary memory
void setup() {
size(800, 520);
noSmooth();
set_grid(true); // init
println("use: mouse LEFT to select, mouse RIGHT to deselect");
println("key UP DOWN RIGHT LEFT for position");
println("key + - for grid size");
println("key n toggle shownumber");
println("key f toggle fill");
}
void draw() {
background(bg);
fill(0);
if (showFPS ) text(nf(frameRate, 1, 1), 10, 10);
for (int i = 0; i < many; i++) myrects[i].drawit(); // draw each rect ( and check on mouse over + click )
}
class Mybackup {
boolean selected=false;
}
class Myrect {
int x, y, id;//, w, h; from global
boolean selected=false;
Myrect (int x, int y, int id) {
this.x = x;
this.y = y;
this.id = id;
}
void drawit() {
if ( showstroke ) stroke(stk);
else noStroke();
if ( selected ) fill(fillsel);
else fill(fillnsel);
if ( togfill ) noFill();
rect(x, y, w, h);
fill(0); // black text
if (shownum) text(id, x+w/4, y+h/3);
sel();
}
boolean over() {
return( x < mouseX && mouseX < x+w && y < mouseY && mouseY < y+h );
}
void sel() {
if ( over() ) {
if ( selected && mousePressed && mouseButton == RIGHT) selected=false;
if ( !selected && mousePressed && mouseButton == LEFT) selected=true;
}
}
}
void set_wh() {
// use x,y,grid as master and auto adjust rectangles (w,h) to window:
println(" width= "+width+", height= "+height+", grid= "+grid);
w = ( width - 2 * x ) / grid;
println(" w= "+w+", x= "+x+", ( grid * w + 2 * x )= "+(grid*w+2*x));
h = ( height - 2 * y ) / grid;
println(" h= "+h+", y= "+y+", ( grid * h + 2 * y )= "+(grid*h+2*y));
}
void set_grid(boolean init) {
if ( auto ) set_wh();
if ( init ) for (int i = 0; i < many; i++) myselects[i]=new Mybackup(); // init backup memory
else for (int i = 0; i < many; i++) myselects[i].selected = myrects[i].selected; // backup
for (int i = 0; i < many; i++) myrects[i]=new Myrect(x+(i%grid)*w, y+(floor(i/grid))*h, i); // resize
if ( !init ) for (int i = 0; i < many; i++) myrects[i].selected = myselects[i].selected; // restore
}
void keyPressed() {
if ( keyCode == UP ) y--;
else if ( keyCode == DOWN ) y++;
else if ( keyCode == LEFT ) x--;
else if ( keyCode == RIGHT ) x++;
else if ( key == '+' ) w++;
else if ( key == '-' ) w--;
h=w; // quadrat only
auto = false; // confirm
set_grid(false); // resize
if ( key == 'n' ) shownum = !shownum;
if ( key == 'f' ) togfill = !togfill;
}
If I’m understanding right, the visual guides you are describing is part of the specific concept in Dawesome Toolkit. Specifically, drawThirdsGuide(color c)
and the other “draw” methods. But you want more of them, and you want some of them to be configurable.
Maybe these features should be proposed as an extension to that library, if you already like the way it works with thirds? Up until your spiral, a generic grid generator, and a “Vector System”, these others are really, really easy to implement – they are just a specific set of lines. You could submit them as patches to Brandon and just use a forked library in the meantime.
Thank you, kll and jeremydouglass for the help.
I’m exploring the Dawesome Toolkit library, and I’ll have a look at how github, and forked libraries work as well.
Just a warning, if you haven’t used git or github before and especially if you aren’t familiar with Java software development (e.g. in Eclipse) then running your own forked Dawsome Toolkit will probably have a substantial learning curve. IT might be a shorter path to what you want to build in @kll 's example – perhaps making it a separate tab with a class that could be cut-pasted into any sketch.
I’m not a programmer, and I never used java software development in proper ide and I’m not familiar with git or github, I’m trying to learn Processing and that’s enough work for now. )
thanks for the general guidance!
I added an Idea to use A4 size 300dpi, like a main working area and two offscreen buffers.
I worked on the simple rule of thirds for now.
This is my first class, it’s a bit messy. Anyway the idea was just to start to rich some modularity in the code.
if you have suggestions, I would really appreciate it.
I know that it’s already implemented in the Dawesome libary, with the function to snaptogrid as well.
/*
- A4 in pixels 300 dpi a4X×a4Y pixels
*/
Thirds gridThird = new Thirds() ;
// A4 in pixels swap them if you want to change the XY
int a4X = 2480, a4Y = 3508;
void setup() {
// trying to keep visual consistency with the A4 format
size(473, 669, P2D);
gridThird.setMeup();
}
void draw() {
gridThird.drawLines();
gridThird.drawInPlace();
//key UP/DOWN
gridThird.k();
}
Class Thirds
class Thirds{
// data
PGraphics ofs_0, ofs_1;
byte unitVectors = 17;
PVector[] thirds;
int pos =1;
// Constructor to initialize?
//Thirds(){}
void setMeup(){
ofs_0 = createGraphics(a4X, a4Y);
ofs_1 = createGraphics(a4X, a4Y);
// LINES
thirds = new PVector[unitVectors];
int count = 0;
for (int i = 0; i<=3; i++ ) {
for (int j = 0; j<=3; j++ ) {
count++;
thirds[count] = new PVector(((ofs_0.width/3)*i), ((ofs_0.height/3)*j), 0);
//println(count+"_: "+thirds[count]);
}
}
}
// functionality
void drawLines() {
ofs_1.beginDraw();
ofs_1.stroke(255, 0, 0);
ofs_1.strokeWeight(4); // Beastly
for (int i =1; i<thirds.length; i+=4) {
ofs_1.line(thirds[i].x, thirds[i].y, thirds[i+3].x, thirds[i+3].y);
}
for (int i =1; i<thirds.length/4; i++) {
ofs_1.line(thirds[i].x, thirds[i].y, thirds[i+12].x, thirds[i+12].y);
}
ofs_1.endDraw();
// Draw your PG to the screen and resize the representation of it to the screen bounds
image(ofs_0, 0, 0, width, height); // <-- this wont actually clip/resize the image
}
void drawInPlace() {
ofs_0.beginDraw();
ofs_0.background(100);
ofs_0.stroke(255);
ofs_0.fill(200);
ofs_0.ellipse(thirds[pos].x, thirds[pos].y, 400, 400);
//for (int pos =1; pos<=16; pos++) {
// ofs_0.ellipse(thirds[pos].x, thirds[pos].y, 400, 400);
//}
ofs_0.endDraw();
image(ofs_1, 0, 0, width, height);
}
void k() {
if (keyPressed == true) {
//println("key: "+key+" keyCode: "+keyCode);
if ( key == CODED){
if ( keyCode == UP ){ if(pos < unitVectors-1) pos = pos+1; println(pos+" NEXT");}
if ( keyCode == DOWN ){if(pos > 1) pos = pos-1;; println(pos+" PREVIOUS");}
}
}
}
}
4 Spots added:
Dislay all 4 simultaneously.
!Display 1 spot in one of the 4 positions
display 2 adjacent points in the 4 positions.
display 2 points with a gap of 2.
display 3 points in the 4 positions
GoldenSpiralVector[] spiral = new GoldenSpiralVector[4];
int switchOne,switchTwo,switchThree = 0;
int second,third =1;
boolean sec,sec1,sec2,sec3 = false; // security
/*
to be very Lazy
Just add one line of code and you can quickly save screenshots
*/
import dawesometoolkit.*;
DawesomeToolkit dawesome;
void setup() {
size(356,576);
for(int i =0; i<spiral.length; i++)
{
spiral[i] = new GoldenSpiralVector(i+1);
// spiral[i].drawTri(i);
}
// only to save quickly
dawesome = new DawesomeToolkit(this);
// Turn on the saveFrame capture feature
// Creates a unique time based filename and has a 500ms debounce built-in.
dawesome.enableLazySave('q',".png");
}
void draw() {
background(255);
//draw lines and point of Intersaction/s
if(sec==true)drawAll();
if(sec1==true)drawOne(switchOne);
if(sec2==true)drawTwo(switchTwo,second);
if(sec3==true)drawThree(switchThree,third);
}
void drawAll(){
for(int i =0; i<spiral.length; i++)
{
// displayLines if you like
spiral[i].displayLines();
// get the intersection Vector
noStroke();
fill(255,0,0,126);
ellipse(spiral[i].getCross().x,spiral[i].getCross().y,20,20);
}
}
// draw one and change position
void drawOne(int where){
if(where>=0 && where <=4 )
// displayLines if you like
spiral[where].displayLines();
// get the intersection Vector
noStroke();
fill(255,0,0,126);
ellipse(spiral[where].getCross().x,spiral[where].getCross().y,20,20);
}// draw a Random one
// draw two and change position
void drawTwo(int where,int step){
if(where>=0 && where <=4 )
spiral[where].displayLines();
spiral[(where+step)%4].displayLines();
noStroke();
fill(255,0,0,126);
ellipse(spiral[where].getCross().x,spiral[where].getCross().y,20,20);
fill(0,255,0,126);
ellipse(spiral[(where+step)%4].getCross().x,spiral[(where+step)%4].getCross().y,20,20);
}
// draw three and change position
void drawThree(int where,int step){
if(where>=0 && where <=4 )
spiral[where].displayLines();
spiral[(where+step)%4].displayLines();
spiral[(where+step+1)%4].displayLines();
noStroke();
fill(255,0,0,126);
ellipse(spiral[where].getCross().x,spiral[where].getCross().y,20,20);
fill(0,255,0,126);
ellipse(spiral[(where+step)%4].getCross().x,spiral[(where+step)%4].getCross().y,20,20);
fill(0,0,255,126);
ellipse(spiral[(where+step+1)%4].getCross().x,spiral[(where+step+1)%4].getCross().y,20,20);
}
// interaction
void keyPressed(){
// press any non key bounded for Non drawing...
if(key == 'a') sec = true; else sec = false;
if(key == 's')
{
sec1 = true; switchOne = (switchOne+1)%4;
//if(keyPressed == true) switchOne = (int)random(0,4);
} else{sec1 = false;}
// combination of possible states for two points
// distance 1 gap switchTwo= ((int)random(1,4))%4;
if(key == 'd')
{
sec2 = true;
switchTwo = (switchTwo+1)%4;
second = 1;
println("letterD switchTwo: " +switchTwo+" second: "+(switchTwo+second)%4);
}
else if(key == 'f')
{
sec2 = true;
switchTwo = (switchTwo+1)%4;
second = 2;
println("letterD switchTwo: " +switchTwo+" second: "+(switchTwo+second)%4);
}
else if(key == 'g')
{
sec2 = true;
switchTwo = (switchTwo+1)%4;
second = 3;
println("letterD switchTwo: " +switchTwo+" second: "+(switchTwo+second)%4);
}else{sec2 = false;}
// three
if(key == 'z')
{
sec3 = true; switchThree = (switchThree+1)%4;
//if(keyPressed == true) switchOne = (int)random(0,4);
} else{sec3 = false;}
}
class
class GoldenSpiralVector{
// data
float x1,y1,x2,y2,x3,y3,x4,y4 = 0;
// implied constructor
GoldenSpiralVector(int where)
{
if(where>0 && where<=4)
switch(where){
case 1:
x1 = 0;
y1 = 0;
x2 = width;
y2 = height;
x3 = 0;
y3 = height;
x4 = width;
y4 = width;
println("LOWER_RIGHT");
break;
case 2:
x1 = width;
y1 = 0;
x2 = 0;
y2 = height;
x3 = width;
y3 = height;
x4 = 0;
y4 = width;
println("LOWER_LEFT");
break;
case 3:
x1 = 0;
y1 = 0;
x2 = width;
y2 = height;
x3 = width;
y3 = 0;
x4 = 0;
y4 = height-width;
println("UPPER_LEFT");
break;
case 4:
x1 = width;
y1 = 0;
x2 = 0;
y2 = height;
x3 = 0;
y3 = 0;
x4 = width;
y4 = height-width;
println("UPPER_RIGHT");
break;
default:
println("ERROR in SWITCH/Case Constructor");
break;
}
}
// func
private void displayLines()
{
strokeWeight(1);
stroke(255,150,0);
line(x3,y3, x4,y4);
stroke(0);
line(x1,y1, x2,y2);
}
// PVector of the intersection
PVector getCross() {
// calculate the distance to intersection point
float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
// intersection
PVector intersection = new PVector(x1 + (uA * (x2-x1)),y1 + (uA * (y2-y1))) ;
return intersection;
}
}