Gryd System Graphic Design

#1

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

1 Like
#2

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
}
1 Like
#3

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.


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.

2 Likes
#4

did you play with my example?

  • disable the fill
  • disable auto scale
  • play x,y,w,h,offset, grid

oh, you want that parameter window for this variables?
this comes in the next lesson.

#5

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.

  1. 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/

  2. 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.

  3. 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:
photoshop-overlay-crop-options
Nevertheless It’s possible to use those grids like drawing aids, that’s the point for me, NOT to crop anything.

1 Like
#6

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:

  1. Rule of thirds https://en.wikipedia.org/wiki/Rule_of_thirds

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.

1 Like
#7
  1. Diagonal
    Here we see a diamond shape in the middle. I used it to help me recompose this image by placing the horse in the middle of the photograph. The Diagonal overlay helped me rotate and re-crop this image so that the man’s hand is on the same diagonal line as the horse’s shoe. I believe this created balance in the final composition.
1 Like
#8
  1. left / right
  2. top / bottom
  3. simple grid n_rows*n_colums
    The Grid overlay is straight to the point. Combined with the Crop tool, it helps you straighten your images more accurately. This standard Grid is great for cropping architectural images. Notice how uneven my picture is. Here the Grid overlay allows me to match the horizontal and vertical lines to those found in the building.
    .
1 Like
#9
  1. triangle
    The Golden Triangle, also known as the sublime triangle, is very similar to the Golden Spiral which we’ll discuss shortly.
    Here is how it works. Imagine a central line cutting an image in half from one corner to another. Then imagine drawing a 90 degree line from each corner towards the central line that cuts your image in half. In the end you’ll have four triangles. The goal is to fill one of those triangles to create an interesting composition.
    Below is an image by the legendary photographer Henri Cartier-Bresson. For the sake of demonstration I reversed his image. Sorry B. Notice how the shadow cuts the image in half. That was his central line. Bresson then placed his subject in the upper triangle. The Triangle overlay in Photoshop helps us achieve similar composition.

1 Like
#10
  1. golden ratio
    Cartier-Bresson was the master of implementing the golden ratio into his photography.
    Bresson worked hard to implement the golden ratio, 1.618, into his photographs, also known as the Divine Proportion in the art world. According to the proponents of this technique, the Golden Ratio leads to harmonious proportions that can be found anywhere in nature, even on our faces.

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.

2 Likes
#11
  1. golden Spiral
    You’ll find golden spirals in nature, such as in Nautilus seashells and spiral galaxies. And yes, you’ll find them in another example from Bresson’s photography.
    In photography, the spiral shape engages and leads the eye to a specific point.
    Recognizing it on the spot and photographing it produces playful results in the final photograph.

the first step in this direction is to find the point of intersection BD,CE
image

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;

}
2 Likes
#12

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.


#13

//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.
9_9RuleOfthirdsIntersections
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.

1 Like
#14

wow, yes, that is a nice project.

not sure that is of any help, but i have a
grid array of class version,

  • and can move, resize
  • and ( you might need later ) each rectangle can be selected/un-selected
    ( that is what the class was for )
  • but you see only if fill is ON key [f]
  • can show numbers key [n]

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;
}

2 Likes
Click on shape in array
#15

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.

#16

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.

#17

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.

1 Like
#18

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. :slight_smile:)
thanks for the general guidance!

#19

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");}
      }
    }
  }

}
1 Like
#20

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;

}


}
1 Like