# I want it to look like a real brush

**URL:** https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684
**Category:** Project Guidance
**Created:** [January 17, 2022, 1:03am UTC](https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684 "2022-01-17T01:03:08Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![yalaniv](https://avatars.discourse-cdn.com/v4/letter/y/7993a0/32.png) [@yalaniv](https://discourse.processing.org/u/yalaniv)
#### Post date: [January 17, 2022, 1:03am UTC](https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684/1 "2022-01-17T01:03:08Z")

</div>

I am willing to create a random spline,  
that it would look like it was made by brush

any idea where to begin?

---

<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: [January 17, 2022, 8:46pm UTC](https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684/2 "2022-01-17T20:46:10Z")

</div>

here is a brush that puts points around mouse (drag and hold mouse)

**(1)**

```auto
float startX=-1, startY=-1;

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

void setup() {
  size(900, 500);
  background(255);
} // func setup()

void draw() {
  showText();

  if (startX>=0) {
    // 11 is how many points we draw per frame
    for (int i=0; i<11; i++) {
      float radius=random(18);
      float angle = random(TWO_PI); 
      float x1=(radius*cos(angle)) + mouseX;
      float y1=(radius*sin(angle)) + mouseY;
      stroke(255, 0, 0); // RED 
      point(x1, y1);
    }
  }
} // func draw() 

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

void showText() {
  noStroke(); 
  fill(111);
  rect(0, 0, width, 20);

  fill(255);
  text("Mouse to draw. The slower you move the mouse, the more points you get. c to clear. q to quit.", 
    14, 14);
}

void keyPressed() {
  if (key == 'c') {
    background(255);
  } else if (key==ESC) {
    key=0;
    startX=-1;
  } else if (key=='q') {
    exit(); // quit
  }
} // func 

void mousePressed() {
  startX=mouseX;
  startY=mouseY;
}

void mouseReleased() {
  startX=-1;
  startY=-1;
}
//

```

* * *

**Similar approach (2)**

```auto

float startX=-1, startY=-1;

ArrayList<PVector> list = new ArrayList(); 

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

void setup() {
  size(900, 500);
  background(255);
  stroke(255, 0, 0); // RED 

  for (int i=0; i<11; i++) {
    // float radius=random(18);
    float radius=random(4, 18);
    if (random(1)<0.5) 
      radius*=-1; 

    float angle = random(TWO_PI); 
    float x1=(radius*cos(angle)) + 0;
    float y1=(radius*sin(angle)) + 0;
    list.add(new PVector(x1, y1));
  } // for
} // func setup()

void draw() {
  showText();

  if (startX>=0) {
    // 11 is how many points we draw per frame
    for (int i=0; i<11; i++) {
      PVector pv=list.get(i);
      pushMatrix();
      translate(mouseX, mouseY);
      stroke(255, 0, 0); // RED
      point(pv.x, pv.y);
      popMatrix();
    }
  }
} // func draw() 

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

void showText() {
  noStroke(); 
  fill(111);
  rect(0, 0, width, 20);

  fill(255);
  text("Mouse to draw. The slower you move the mouse, the more points you get. c to clear. q to quit.", 
    14, 14);
}

void keyPressed() {
  if (key == 'c') {
    background(255);
  } else if (key==ESC) {
    key=0;
    startX=-1;
  } else if (key=='q') {
    exit(); // quit
  }
} // func 

void mousePressed() {
  startX=mouseX;
  startY=mouseY;
}

void mouseReleased() {
  startX=-1;
  startY=-1;
}
//

```

* * *

**(3)**

```auto

float startX=-1, startY=-1;

ArrayList<PVector> list = new ArrayList(); 

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

void setup() {
  size(900, 500);
  background(255);
  stroke(255, 0, 0); // RED 

  for (int i=0; i<11; i++) {
    // float radius=random(18);
    float radius=random(4, 18);
    if (random(1)<0.5) 
      radius*=-1;

    float angle = random(TWO_PI); 
    float x1=radius*cos(angle) + 0;
    float y1=radius*sin(angle) + 0;
    list.add(new PVector(x1, y1));
  } // for
} // func setup()

void draw() {
  showText();

  if (startX>=0) {
    // 11 is how many points we draw per frame
    for (int i=0; i<11; i++) {
      PVector pv=list.get(i);
      pushMatrix();
      translate(mouseX, mouseY);
      stroke(255, 0, 0); // RED
      line(pv.x, pv.y, 
        mouseX-pmouseX, mouseY-pmouseY);
      popMatrix();
    }
  }
} // func draw() 

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

void showText() {
  noStroke(); 
  fill(111);
  rect(0, 0, width, 20);

  fill(255);
  text("Mouse to draw. The slower you move the mouse, the more points you get. c to clear. q to quit.", 
    14, 14);
}

void keyPressed() {
  if (key == 'c') {
    background(255);
  } else if (key==ESC) {
    key=0;
    startX=-1;
  } else if (key=='q') {
    exit(); // quit
  }
} // func 

void mousePressed() {
  startX=mouseX;
  startY=mouseY;
}

void mouseReleased() {
  startX=-1;
  startY=-1;
}
//

```

* * *

**(4)**

```auto

float startX=-1, startY=-1;

ArrayList<PVector> list = new ArrayList(); 

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

void setup() {
  size(900, 500);
  background(255);
  stroke(255, 0, 0); // RED
} // func setup()

void draw() {
  showText();

  if (startX>=0) {
    for (int i=0; i<list.size(); i++) {
      PVector pv=list.get(i);

      stroke(255, 0, 0); // RED
      line(pv.x, pv.y, 
        pv.x+(mouseX-pmouseX), pv.y + (mouseY-pmouseY));

      list.get(i).x += mouseX-pmouseX;  
      list.get(i).y += mouseY-pmouseY;
    }
  }
} // func draw() 

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

void showText() {
  noStroke(); 
  fill(111);
  rect(0, 0, width, 20);

  fill(255);
  text("Mouse to draw. The slower you move the mouse, the more points you get. c to clear. q to quit.", 
    14, 14);
}

void keyPressed() {
  if (key == 'c') {
    background(255);
  } else if (key==ESC) {
    key=0;
    startX=-1;
  } else if (key=='q') {
    exit(); // quit
  }
} // func 

void mousePressed() {
  startX=mouseX;
  startY=mouseY;

  list.clear();

  // how many points we draw per frame
  for (int i=0; i<33; i++) {
    // float radius=random(18);
    float radius=random(3, 18);
    if (random(1)<0.5) 
      radius*=-1;

    float angle = random(TWO_PI); 
    float x1=radius*cos(angle) + mouseX;
    float y1=radius*sin(angle) + mouseY;
    list.add(new PVector(x1, y1));
  } // for
}

void mouseReleased() {
  startX=-1;
  startY=-1;
}
//

```

---

<div class="post-metadata">

### Author: ![yalaniv](https://avatars.discourse-cdn.com/v4/letter/y/7993a0/32.png) [@yalaniv](https://discourse.processing.org/u/yalaniv)
#### Post date: [January 17, 2022, 9:29pm UTC](https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684/3 "2022-01-17T21:29:44Z")

</div>

Thanks for your helping code.

I an willing to the let computer paint those splines by itself, so I have some editing,  
and those codes are more like airbrush and less like a paintbrush, but it really a great good way to start from, and therefore I am thankful for your reply, as I already got the code and start playing with it

---

<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: [January 17, 2022, 9:33pm UTC](https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684/4 "2022-01-17T21:33:10Z")

</div>

Thank you.

In this new version I try not a round brush but a brush more like this: |

You can see the difference when you move the mouse right OR down

**(5)**

```auto

float startX=-1, startY=-1;

ArrayList<PVector> list = new ArrayList(); 

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

void setup() {
  size(900, 500);
  background(255);
  stroke(255, 0, 0); // RED
} // func setup()

void draw() {
  showText();

  if (startX>=0) {
    for (int i=0; i<list.size(); i++) {
      PVector pv=list.get(i);

      stroke(255, 0, 0); // RED
      line(pv.x, pv.y, 
        pv.x+(mouseX-pmouseX), pv.y + (mouseY-pmouseY));

      list.get(i).x += mouseX-pmouseX;  
      list.get(i).y += mouseY-pmouseY;
    }
  }
} // func draw() 

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

void showText() {
  noStroke(); 
  fill(111);
  rect(0, 0, width, 20);

  fill(255);
  text("Mouse to draw. The slower you move the mouse, the more points you get. c to clear. q to quit.", 
    14, 14);
}

void keyPressed() {
  if (key == 'c') {
    background(255);
  } else if (key==ESC) {
    key=0;
    startX=-1;
  } else if (key=='q') {
    exit(); // quit
  }
} // func 

void mousePressed() {
  startX=mouseX;
  startY=mouseY;

  list.clear();

  // how many points we draw per frame
  for (int i=0; i<166; i++) {
    // float radius=random(18);
    float radius=random(0, 28);
    if (random(1)<0.5) 
      radius*=-1;

    float angle = random(TWO_PI); 
    float x1=radius*cos(angle) + mouseX;
    float y1=radius*sin(angle) + mouseY;
    if (dist(x1, 0, mouseX, 0) < 3) { 
      list.add(new PVector(x1, y1));
    }
  } // for
}

void mouseReleased() {
  startX=-1;
  startY=-1;
}
//

```

---

<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: [January 17, 2022, 9:34pm UTC](https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684/5 "2022-01-17T21:34:00Z")

</div>

> [@yalaniv](#):
>
> more like airbrush and less like a paintbrush

I know what you mean.

Please note I made five versions, maybe 4 and 5 are better?

---

<div class="post-metadata">

### Author: ![yalaniv](https://avatars.discourse-cdn.com/v4/letter/y/7993a0/32.png) [@yalaniv](https://discourse.processing.org/u/yalaniv)
#### Post date: [January 17, 2022, 10:26pm UTC](https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684/6 "2022-01-17T22:26:21Z")

</div>

Thank you for your efforts 🙂  
I found number 3 very interesting. it is far beyond what I was looking for, but was very cool and make think about other uses for that.

However, I really like number 4. Thanks

---

<div class="post-metadata">

### Author: ![Flolo](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/flolo/32/13874_2.png) [@Flolo](https://discourse.processing.org/u/Flolo)
#### Post date: [January 18, 2022, 5:29pm UTC](https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684/7 "2022-01-18T17:29:10Z")

</div>

**Edit:** if you press n you get a random new color

Hey, I found your code very interesting and tried to add some bloom. Well, it didn’t turn out as well as I hoped, but I hope I was able to help a little anyway.  
(the longer you hover your mouse over a spot, the more bloom will be added)

```auto
float startX=-1, startY=-1;
float radius=0;

ArrayList<PVector> list = new ArrayList(); 

color drawColor = color(255, 0, 0);

void setup() {
  size(900, 500);
  background(255);
  stroke(255, 0, 0);
} 

void draw() {
  if (startX>=0) {
    for (int i=0; i<list.size(); i++) {
      PVector pv=list.get(i);

      stroke(drawColor);
      line(pv.x, pv.y, 
        pv.x+(mouseX-pmouseX), pv.y + (mouseY-pmouseY));

      list.get(i).x += mouseX-pmouseX;  
      list.get(i).y += mouseY-pmouseY;
    }
  }
  if (radius<0) {
    makeItSick(int(mouseX-radius*-2), int(mouseY-radius*-2), int(radius*-4), int(radius*-4));
  } else {
    makeItSick(int(mouseX-radius*2), int(mouseY-radius*2), int(radius*4), int(radius*4));
  }
}// func draw() 

// -----------------------------------------------------------------
void makeItSick(int startx, int starty, int w, int h) {
  //startx and starty must be the upper left corner
  int endx = startx + w;
  int endy = starty + h;
  loadPixels();

  int[] buffer = new int[pixels.length];
  for (int i = 0; i < pixels.length; i++) {
    buffer[i] = pixels[i];
  }
  for (int x = startx; x < endx; x++) {
    for (int y = starty; y < endy; y++) {
      //i for index
      int i = x + y * width;
      //c for color
      color c = pixels[constrain(i, 0, pixels.length-1)];

      int upi = (x) + (y-1) * width;
      color upc = pixels[constrain(upi, 0, pixels.length-1)];

      int downi = (x) + (y+1) * width;
      color downc = pixels[constrain(downi, 0, pixels.length-1)];

      int lefti = (x-1) + (y) * width;
      color leftc = pixels[constrain(lefti, 0, pixels.length-1)];

      int righti = (x+1) + (y) * width;
      color rightc = pixels[constrain(righti, 0, pixels.length-1)];

      float cr = red(c);
      float cg = green(c);
      float cb = blue(c);

      float upr = red(upc);
      float upg = green(upc);
      float upb = blue(upc);

      float downr = red(downc);
      float downg = green(downc);
      float downb = blue(downc);

      float leftr = red(leftc);
      float leftg = green(leftc);
      float leftb = blue(leftc);

      float rightr = red(rightc);
      float rightg = green(rightc);
      float rightb = blue(rightc);

      float newr = (cr + upr + downr + leftr + rightr)/5;
      float newg = (cg + upg + downg + leftg + rightg)/5;
      float newb = (cb + upb + downb + leftb + rightb)/5;

      color newColor = color(newr, newg, newb);
      buffer[constrain(i, 0, pixels.length-1)] = newColor;
    }
  }

  for (int i = 0; i < pixels.length; i++) {
    pixels[i] = buffer[i];
  }

  updatePixels();
}

void showText() {
  noStroke(); 
  fill(111);
  rect(0, 0, width, 20);

  fill(255);
  text("Mouse to draw. The slower you move the mouse, the more points you get. c to clear. q to quit.", 
    14, 14);
}
void keyPressed() {
  if (key == 'n') {//new color
    drawColor = color(random(255), random(255), random(255));
  } else if (key == 'c') {
    background(255);
  } else if (key==ESC) {
    key=0;
    startX=-1;
  } else if (key=='q') {
    exit(); // quit
  }
} // func 
void mousePressed() {
  startX=mouseX;
  startY=mouseY;

  list.clear();
  radius = 0;
  // how many points we draw per frame
  for (int i=0; i<33; i++) {
    // float radius=random(18);
    float r=random(3, 18);
    if (r > radius)
      radius = r;
    if (random(1)<0.5) 
      r*=-1;

    float angle = random(TWO_PI); 
    float x1=r*cos(angle) + mouseX;
    float y1=r*sin(angle) + mouseY;
    list.add(new PVector(x1, y1));
  } // for
}
void mouseReleased() {
  startX=-1;
  startY=-1;
}
//

```

---

<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: [January 18, 2022, 6:28pm UTC](https://discourse.processing.org/t/i-want-it-to-look-like-a-real-brush/34684/8 "2022-01-18T18:28:10Z")

</div>

Impressive!

There are also cool examples:

section Drawing

or Storing Input in section Input

![Storing Input](https://processing.org/static/fad809e182f2a842d277d922c68f3c5a/aeb79/StoringInput.png)

#### Storing Input

> **[Storing Input / Examples](https://processing.org/examples/storinginput.html)**
>
> Move the mouse across the screen to change the position of the circles. The positions of the mouse are recorded into an array and played back every frame. Between each frame, the newest value are adde…

> **[Examples](https://processing.org/examples/)**
>
> Short, prototypical programs exploring the basics of programming with Processing.
