# How can i create Brushes for drawing?

**URL:** <https://discourse.processing.org/t/how-can-i-create-brushes-for-drawing/41990>\
**Category:** Coding Questions\
**Created:** [May 14, 2023, 10:22am UTC](https://discourse.processing.org/t/how-can-i-create-brushes-for-drawing/41990 "2023-05-14T10:22:36Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aryszin](https://avatars.discourse-cdn.com/v4/letter/a/ec9cab/32.png) [@Aryszin](https://discourse.processing.org/u/Aryszin)\
**Post date:** [May 14, 2023, 10:22am UTC](https://discourse.processing.org/t/how-can-i-create-brushes-for-drawing/41990/1 "2023-05-14T10:22:36Z")

</div>

I want to make brushes for my drawing software, i have code, but its kinda bad and not working correctly.  
The problem is if i put down a image of the brush every frame, it will not work when moving the mouse fast. I tried fixing that. Heres my (not fully working) code.

The image is just a gradient from middle.

It is working kinda fine, but between the mouse beeing moved too fast and slow enought (there are 2 functions that switch) there is some error.

thanks anyone who is helping!

```auto
int dist, distnow, max = 10, size = 35;

boolean mouseClick = false;
boolean pressed = false;
PVector mouseClickA = new PVector(0,0);
PVector mouseClickB = new PVector(0,0);

PImage airbrush;

void setup() {
  size(960,540);
  noStroke();
  frameRate(255);
  airbrush = loadImage("b1.png");
}

void draw() { 
  dist += (int)dist(mouseX,mouseY,pmouseX,pmouseY);
  distnow = (int)dist(mouseX,mouseY,pmouseX,pmouseY);
  
  if(mousePressed) {
    line(mouseX,mouseY,pmouseX,pmouseY);
    mouseClickA.x = mouseX;
    mouseClickA.y = mouseY;
    mouseClickB.x = pmouseX;
    mouseClickB.y = pmouseY;
    fill(0,25);
    noStroke();
    if(dist > max && distnow-5 < max) image(airbrush,mouseX,mouseY,size,size);//circle(mouseX,mouseY,size);
    if(distnow > max) {
      dottedLine(mouseClickA,mouseClickB, max+3);
      image(airbrush,mouseX,mouseY,size,size);//circle(mouseX,mouseY,size);
    }
  }
  
  if(dist > max) dist = 0;
  
  if(keyPressed) background(#CCCCCC);
  
  fill(255);
  rect(0,0,width-1,50);
  fill(0);
  text(dist+"\n"+distnow,10,20);
  text(frameRate,50,20);
}

void dottedLine(PVector posA, PVector posB, int distance) {
  posA = posA.copy();
  posB = posB.copy();
  PVector direction = posB.sub(posA);
  int len = (int) (direction.mag() / distance);
  direction.normalize();
  direction.mult(distance);
  fill(0,25);
  for (int i = 0; i < len; i++) {
    posA.add(direction);
    image(airbrush,posA.x,posA.y,size,size);//circle(posA.x,posA.y,size);
  }
}

```

---

<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:** [May 14, 2023, 11:14am UTC](https://discourse.processing.org/t/how-can-i-create-brushes-for-drawing/41990/2 "2023-05-14T11:14:41Z")

</div>

hm, not sure what you mean.

We don’t have your brush image, but I used a point() instead.

Is it a speed issue?

Hint: to use image() command with 5 parameters is costly.

- Instead use image always with 3 parameters.

- use resize in setup - only once

- make sure that the image is only drawn once per loop. I see it 3 times in your code?

Also, it might be faster to store mouseX and mouseY in a variable and use those instead.

Remark.  
` dist, distnow;` should be `float `

Chrisir

```auto

//

float dist, distnow;
int max = 10, size = 35;

boolean mouseClick = false;
boolean pressed = false;
PVector mouseClickA = new PVector(0, 0);
PVector mouseClickB = new PVector(0, 0);

PImage airbrush;

void setup() {
  size(960, 540);
  //noStroke();
  stroke(0);
  //frameRate(255);
  // airbrush = loadImage("b1.png");
}

void draw() {

  stroke(0);

  dist += (int)dist(mouseX, mouseY, pmouseX, pmouseY);
  distnow = (int)dist(mouseX, mouseY, pmouseX, pmouseY);

  if (mousePressed) {
    line(mouseX, mouseY, pmouseX, pmouseY);
    mouseClickA.x = mouseX;
    mouseClickA.y = mouseY;
    mouseClickB.x = pmouseX;
    mouseClickB.y = pmouseY;
    fill(0, 25);
    // noStroke();
    // if (dist > max && distnow-5 < max) image(airbrush, mouseX, mouseY, size, size);//circle(mouseX,mouseY,size);
    if (dist > max && distnow-5 < max)
      point(mouseX, mouseY);

    if (distnow > max) {
      dottedLine(mouseClickA, mouseClickB, max+3);
      //image(airbrush, mouseX, mouseY, size, size);//circle(mouseX,mouseY,size);
      point(mouseX, mouseY);
    }
  }

  if (dist > max)
    dist = 0;

  if (keyPressed)
    background(#CCCCCC);

  fill(255);
  noStroke();
  rect(0, 0, width-1, 50);
  fill(0);
  text(dist+"\n"+distnow, 10, 20);
  text(frameRate, 50, 20);
}

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

void dottedLine(PVector posA, PVector posB, int distance) {
  posA = posA.copy();
  posB = posB.copy();
  PVector direction = posB.sub(posA);
  int len = (int) (direction.mag() / distance);
  direction.normalize();
  direction.mult(distance);
  fill(0, 25);
  for (int i = 0; i < len; i++) {
    posA.add(direction);
    point( posA.x, posA.y );
    // image(airbrush, posA.x, posA.y, size, size);//circle(posA.x,posA.y,size);
  }
}

```

---

<div class="post-metadata">

**Author:** ![DevaPan](https://avatars.discourse-cdn.com/v4/letter/d/278dde/32.png) [@DevaPan](https://discourse.processing.org/u/DevaPan)\
**Post date:** [May 14, 2023, 3:20pm UTC](https://discourse.processing.org/t/how-can-i-create-brushes-for-drawing/41990/3 "2023-05-14T15:20:14Z")

</div>

Try making the image smaller if possible, it makes a big difference. You could also try using it as a mouse cursor icon. Just a thought…

---

<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:** [May 14, 2023, 9:46pm UTC](https://discourse.processing.org/t/how-can-i-create-brushes-for-drawing/41990/4 "2023-05-14T21:46:37Z")

</div>

> [@DevaPan](#):
>
> You could also try using it as a mouse cursor icon.

Yes and no.

- Yes: [cursor() / Reference / Processing.org](https://processing.org/reference/cursor_.html)

- No: I think actually, OP is using the brush as staying on the canvas as being the actual stroke. This won’t be possible with mouse cursor because it’s not permanent.

* * *

Here is another brush - maybe for Calligraphy ( **ONE MORE Sketch BELOW** )

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

```

* * *

**And another Paint program**

```auto

float startX=-1, startY=-1;

// constants
final int lineMode = 0;
final int circleMode = 1;
final int rectMode = 2;
final int brushMode = 3;
int mode = brushMode; // current

String[] description={
  "line mode",
  "ellipse mode",
  "rect mode",
  "points mode"
};

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

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

void draw() {

  showText();

  if (mode==lineMode) {
    if (startX>=0) {
      stroke(random(pmouseX), random(pmouseY), abs(pmouseX-pmouseY));
      line(startX, startY, pmouseX, pmouseY);
    }
  } else if (mode==circleMode) {
    if (startX>=0) {
      noFill();
      stroke(random(pmouseX), random(pmouseY), abs(pmouseX-pmouseY));
      ellipse (startX, startY, mouseX-startX, mouseY-startY);
    }
  } else if (mode==rectMode) {
    if (startX>=0) {
      noFill();
      stroke(random(pmouseX), random(pmouseY), abs(pmouseX-pmouseY));
      rect (startX, startY, mouseX-startX, mouseY-startY);
    }
  } else if (mode==brushMode) {
    if (startX>=0) {
      noFill();
      for (int i=0; i<11; i++) {
        float r=random(18);
        float angle = random(TWO_PI);
        float x1=(r*cos(angle)) + mouseX;
        float y1=(r*sin(angle)) + mouseY;
        stroke(255, 0, 0);
        point(x1, y1);
      }
    }
  } else {
    println("Error on mode : 176");
    exit();
  }
} // func draw()

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

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

  fill(255);
  text("Modes: e (ellipses), r (rectangles), l (lines), b (points). Current mode is "
    +description[mode]
    +". Mouse to draw. c to clear. q to quit.",
    14, 14);
}

void keyPressed() {
  if (keyPressed) {
    if (key == 'c') {
      background(255);
    } else if (key==ESC) {
      key=0;
      startX=-1;
    }
    // ---------------------- modes
    else if (key=='e') {
      mode = circleMode;
      println ("mode = circle Mode");
      startX=-1;
    } else if (key=='l') {
      mode = lineMode;
      println ("mode = line Mode");
      startX=-1;
    } else if (key=='r') {
      mode = rectMode;
      println ("mode = rect Mode");
      startX=-1;
    } else if (key=='b') {
      mode = brushMode;
      println ("mode = brush Mode");
      startX=-1;
    }

    // ---------------------------- quit
    else if (key=='q') {
      exit(); // quit
    }
  } //
} // func

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

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

```

---

<div class="post-metadata">

**Author:** ![DevaPan](https://avatars.discourse-cdn.com/v4/letter/d/278dde/32.png) [@DevaPan](https://discourse.processing.org/u/DevaPan)\
**Post date:** [May 14, 2023, 11:16pm UTC](https://discourse.processing.org/t/how-can-i-create-brushes-for-drawing/41990/5 "2023-05-14T23:16:37Z")

</div>

> [@Chrisir](#):
>
> ```auto
> startX=-1;
> 
> ```

Yes, you are right. I meant it more like an addition to the existing sketch, just to spice it up a little. Like e.g. in Photoshop when the tool for drawing/painting is visible all the time…

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [May 15, 2023, 11:26am UTC](https://discourse.processing.org/t/how-can-i-create-brushes-for-drawing/41990/6 "2023-05-15T11:26:10Z")

</div>

> [@Aryszin](#):
>
> It is working kinda fine, but between the mouse beeing moved too fast and slow enough

Consider lerping between the two points:

```auto
PVector v1, v2, v3;

void setup() 
  {
  size(500, 500);
  v1 = new PVector(0.0, 0.0);
  v2 = new PVector(width, height);
  v3 = new PVector(0, 0);
  noLoop();
  }

void draw() 
  {
  float dist = PVector.dist(v1, v2);
  println(dist);
  for(int i=0; i<100; i++)
    {
    v3 = PVector.lerp(v1, v2, i/100.0);
    println(i, v1, v2, v3);
    circle(v3.x, v3.y, 10);
    }
  }

```

`:)`

---

<div class="post-metadata">

**Author:** ![Aryszin](https://avatars.discourse-cdn.com/v4/letter/a/ec9cab/32.png) [@Aryszin](https://discourse.processing.org/u/Aryszin)\
**Post date:** [May 15, 2023, 7:48pm UTC](https://discourse.processing.org/t/how-can-i-create-brushes-for-drawing/41990/7 "2023-05-15T19:48:21Z")

</div>

is using vectors better than points?
